W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
GIN接口有一個(gè)高層次的抽象,要求訪問方法實(shí)現(xiàn)者只需要實(shí)現(xiàn)數(shù)據(jù)類型被訪問的語義。GIN層本身會(huì)操心并發(fā)、日志和搜索樹結(jié)構(gòu)的事情。
要讓一個(gè)GIN訪問方法工作起來所要做的全部事情就是實(shí)現(xiàn)一些用戶定義的方法,它們定義了樹中鍵的行為以及鍵、被索引項(xiàng)以及可索引查詢之間的關(guān)系。簡而言之,GIN的可擴(kuò)展性結(jié)合了通用性、代碼重用和一個(gè)干凈的接口。
一個(gè)用于GIN的操作符類必須提供的兩種方法是:
Datum *extractValue(Datum itemValue, int32 *nkeys,
bool **nullFlags)
給定一個(gè)要被索引的項(xiàng),返回一個(gè) palloc 過的鍵的數(shù)組。被返回的鍵的數(shù)量必須被存儲(chǔ)在*nkeys
中。如果鍵中的任意一個(gè)可能為空,還要 palloc 一個(gè)*nkeys
個(gè)bool
域的數(shù)組,將它的地址存儲(chǔ)在*nullFlags
中,并且根據(jù)需要設(shè)置這些空值標(biāo)志。如果所有的鍵都非空,
*nullFlags
可以被留成NULL
(其初始值)。如果該項(xiàng)不包含鍵,返回值可以為NULL
。
Datum *extractQuery(Datum query, int32 *nkeys,
StrategyNumber n, bool **pmatch, Pointer **extra_data,
bool **nullFlags, int32 *searchMode)
給定一個(gè)要被查詢的值,返回一個(gè) palloc 過的鍵的數(shù)組。即query
是一個(gè)可索引操作符(左手邊是被索引列)的右手邊的值。n
是操作符類中操作符的策略號(hào)(見第 37.16.2 節(jié))。通常,
extractQuery
將需要參考n
來判斷query
的數(shù)據(jù)類型以及它應(yīng)該用什么方法來抽取鍵值。被返回的鍵的數(shù)量必須被存儲(chǔ)在*nkeys
中。如果鍵中的任意一個(gè)可能為空,還要 palloc 一個(gè)*nkeys
個(gè)bool
域的數(shù)組,將它的地址存儲(chǔ)在
*nullFlags
中,并且根據(jù)需要設(shè)置這些空值標(biāo)志。如果所有的鍵都非空,*nullFlags
可以被留成NULL
(其初始值)。如果該項(xiàng)不包含鍵,返回值可以為NULL
。
searchMode
是一個(gè)輸出參數(shù),它允許extractQuery
指定有關(guān)搜索如何被完成的細(xì)節(jié)。如果*searchMode
被設(shè)置為GIN_SEARCH_MODE_DEFAULT
(這是在被調(diào)用之前它被初始化的值),只有那些匹配至少一個(gè)被返回鍵的項(xiàng)才會(huì)被考慮作為候選匹配。如果
*searchMode
被設(shè)置為GIN_SEARCH_MODE_INCLUDE_EMPTY
,那么除了至少包含一個(gè)匹配鍵的項(xiàng)之外,根本不包含鍵的項(xiàng)也被考慮作為候選匹配(例如,這種模式對(duì)于實(shí)現(xiàn)“是...的子集”操作符有用)。如果*searchMode
被設(shè)置為GIN_SEARCH_MODE_ALL
,那么索引中所有非空項(xiàng)都被考慮作為候選匹配,不管它們是否匹配被返回的鍵(這種模式比其他兩種選擇要慢很多,但是它對(duì)于正確實(shí)現(xiàn)極端情況可能是必要的。需要這種模式的操作符在大部分情況下可能并不是一個(gè)
GIN 操作符類的好選擇)。用于設(shè)置這個(gè)模式的符號(hào)被定義在access/gin.h
中。
pmatch
是一個(gè)輸出參數(shù),它用于在部分匹配匹配被支持時(shí)使用。要用它,extractQuery
必須分配一個(gè)*nkeys
個(gè)布爾值的數(shù)組,并且把它的地址存儲(chǔ)在*pmatch
中。如果一個(gè)鍵要求部分匹配,該數(shù)組的對(duì)應(yīng)元素應(yīng)該被設(shè)置為 TRUE,否則設(shè)置為 FALSE。如果
*pmatch
被設(shè)置為NULL
,則 GIN 假定不需要部分匹配。在調(diào)用前,該變量被初始化為NULL
,這樣這個(gè)參數(shù)可以簡單地被不支持部分匹配的操作符類忽略。
extra_data
是一個(gè)輸出參數(shù),它允許extractQuery
傳遞額外數(shù)據(jù)給consistent
和comparePartial
方法。要用它,extractQuery
必須分配一個(gè)*nkeys
個(gè)指針的數(shù)組,并且把它的地址存儲(chǔ)在
*extra_data
中,然后把任何它想存儲(chǔ)的東西存到單個(gè)指針中。在調(diào)用前該變量被初始化為NULL
,這樣這個(gè)參數(shù)可以簡單地被不需要額外數(shù)據(jù)的操作符類忽略。如果*extra_data
被設(shè)置,整個(gè)數(shù)組被傳遞給consistent
方法,并且適當(dāng)?shù)脑貢?huì)被傳遞給comparePartial
方法。
一個(gè)操作符類必須提供一個(gè)函數(shù)檢查一個(gè)被索引的項(xiàng)是否匹配查詢。有兩種形式, 一個(gè)布爾函數(shù)consistent
,以及一個(gè)三元函數(shù)triConsistent
。 triConsistent
覆蓋了兩者的功能,因此提供triConsistent
一個(gè)足矣。但是, 如果布爾變體的計(jì)算代價(jià)要更低,兩者都提供就會(huì)有好處。如果只提供布爾變體,
一些基于在取得所有鍵之前拒絕索引項(xiàng)的優(yōu)化將會(huì)被禁用。
bool consistent(bool check[], StrategyNumber n, Datum query,
int32 nkeys, Pointer extra_data[], bool *recheck,
Datum queryKeys[], bool nullFlags[])
如果一個(gè)被索引項(xiàng)滿足(如果重新檢查指示被返回,則表示可能滿足)有策略號(hào)n
的查詢操作符,則返回 TRUE。這個(gè)函數(shù)并沒有直接訪問被索引項(xiàng)的值,因?yàn)?acronym class="acronym">GIN沒有顯式存儲(chǔ)項(xiàng)??捎玫氖顷P(guān)于哪些從查詢抽取出的鍵值出現(xiàn)在一個(gè)給定被索引項(xiàng)中的知識(shí)。check
數(shù)組的長度是nkeys
,它和前面由
extractQuery
為這個(gè)查詢
數(shù)據(jù)返回的鍵的數(shù)目相同。 如果被索引項(xiàng)包含一個(gè)查詢鍵,那么check
數(shù)組的對(duì)應(yīng)元素為 TRUE,即如果 (check[i] == TRUE) ,則extractQuery
結(jié)果數(shù)組的第 i 個(gè)鍵存在于被索引項(xiàng)中。在consistent
方法需要參考原始
query
數(shù)據(jù)的情況中,它會(huì)被傳遞進(jìn)來,前面由extractQuery
返回的queryKeys[]
和nullFlags[]
數(shù)組也一樣。extra_data
是由extractQuery
返回的額外數(shù)據(jù)數(shù)組,如果沒有額外數(shù)據(jù)則為
NULL
。
當(dāng)extractQuery
在queryKeys[]
中返回一個(gè)空值鍵時(shí),如果被索引項(xiàng)包含一個(gè)空值鍵則對(duì)應(yīng)的check[]
元素為 TRUE。即,check[]
的語義類似IS NOT DISTINCT FROM
。如果
consistent
函數(shù)需要說出一個(gè)常規(guī)值匹配和一個(gè)空值匹配之間的區(qū)別,它可以檢查對(duì)應(yīng)的nullFlags[]
元素。
在成功時(shí),如果堆元組需要根據(jù)查詢操作符被重新檢查,則*recheck
應(yīng)該被設(shè)置為 TRUE,或者如果索引測試是準(zhǔn)確的則設(shè)置為 FALSE。即,一個(gè) FALSE 返回值保證堆元組不匹配查詢;一個(gè) TRUE 返回值以及設(shè)置為 FALSE 的*recheck
保證堆元組匹配查詢;并且一個(gè) TRUE 返回值和設(shè)置為 TRUE 的*recheck
表示堆元組可能匹配查詢,因此它需要被取出并且通過在原始的被索引項(xiàng)上計(jì)算查詢操作符來重新檢查。
GinTernaryValue triConsistent(GinTernaryValue check[], StrategyNumber n, Datum query,
int32 nkeys, Pointer extra_data[],
Datum queryKeys[], bool nullFlags[])
triConsistent
類似于consistent
, 但和check[]
中的布爾值不同,對(duì)每個(gè)鍵有三種可能值: GIN_TRUE
、GIN_FALSE
和GIN_MAYBE
。
GIN_FALSE
和GIN_TRUE
具有和常規(guī)布爾值相同的含義, 而GIN_MAYBE
意味著鍵的存在未知。當(dāng)GIN_MAYBE
值出現(xiàn)時(shí), 如果項(xiàng)必定匹配(不管該索引項(xiàng)是否包含對(duì)應(yīng)的查詢鍵),該函數(shù)應(yīng)該只返回GIN_TRUE
。 同樣地,如果項(xiàng)必定不匹配(不管它是否包含
GIN_MAYBE
), 該函數(shù)必須只返回GIN_FALSE
。 如果結(jié)果依賴于GIN_MAYBE
項(xiàng),即無法根據(jù)已知查詢鍵確認(rèn)或拒絕匹配, 該函數(shù)必須返回GIN_MAYBE
。
當(dāng)在check
向量中沒有GIN_MAYBE
值時(shí), GIN_MAYBE
返回值等效于在布爾函數(shù)consistent
中設(shè)置 recheck
標(biāo)志等效。
此外,GIN必須有方法能排序存儲(chǔ)在索引中的鍵值。操作符類可以通過指定一種比較方法來定義排序順序:
int compare(Datum a, Datum b)
比較兩個(gè)鍵(不是被索引項(xiàng)!)并且返回一個(gè)整數(shù),該整數(shù)為小于零、等于零或者大于零分別表示第一個(gè)鍵小于、等于或者大于第二個(gè)鍵??罩垫I絕不會(huì)被傳遞給這個(gè)函數(shù)。
或者,如果操作符類不提供compare
方法,GIN將查看索引鍵數(shù)據(jù)類型的默認(rèn)btree操作符類,并且使用它的比較函數(shù)。推薦為只用于一種數(shù)據(jù)類型的GIN操作符類指定這個(gè)比較函數(shù),因?yàn)椴檎襜tree操作符類需要消耗一些周期。不過,多態(tài)的GIN操作符類(例如array_ops
)通常無法指定單一的比較函數(shù)。
一個(gè)用于GIN的操作符類可以選擇性的提供下列方法:
int comparePartial(Datum partial_key, Datum key, StrategyNumber n,
Pointer extra_data)
比較一個(gè)部分匹配鍵和一個(gè)索引鍵。返回一個(gè)整數(shù),其符號(hào)指示結(jié)果:小于零表示索引鍵不匹配查詢,但是索引掃描應(yīng)該繼續(xù);零表示索引鍵匹配查詢;大于零表示索引掃描應(yīng)該停止,因?yàn)闆]有更多可能的匹配。產(chǎn)生該部分匹配查詢的操作符的策略號(hào)n
將被提供,可以通過其語義決定什么時(shí)候結(jié)束掃描。還有,extra_data
是由extractQuery
產(chǎn)生的額外數(shù)據(jù)數(shù)組中的對(duì)應(yīng)元素,如果沒有則為
NULL
。空值不會(huì)被傳遞給這個(gè)函數(shù)。
void options(local_relopts *relopts)
定義一組用戶可見的參數(shù)以控制操作符類的行為。
options
函數(shù)傳遞一個(gè)指針到一個(gè)local_relopts
結(jié)構(gòu),該結(jié)構(gòu)需要用一組特定的操作符類的選項(xiàng)來填充。 該選項(xiàng)可以使用PG_HAS_OPCLASS_OPTIONS()
和PG_GET_OPCLASS_OPTIONS()
宏,從其他支持的函數(shù)進(jìn)行訪問。
由于索引值的鍵提取和鍵在GIN中的表示都是靈活的,它們可能取決于用戶指定的參數(shù)。
要支持“部分匹配”查詢,一個(gè)操作符類必須提供comparePartial
方法,并且它的extractQuery
方法必須在遇到一個(gè)部分匹配查詢時(shí)設(shè)置pmatch
參數(shù)。詳見第 66.4.2 節(jié)。
上面提到的多個(gè)Datum
值的實(shí)際數(shù)據(jù)類型隨著操作符類而變化。 被傳遞給extractValue
的項(xiàng)值總是操作符類的輸入類型, 并且所有的鍵值必須是類的STORAGE
類型。被傳遞給extractQuery
、 consistent
和
triConsistent
的query
參數(shù)是由該策略號(hào)標(biāo)識(shí)的類成員操作符的右手邊輸入類型。 這不需要和被索引類型相同,只要正確類型的鍵值能從其中被抽取出來。不過, 推薦這三個(gè)支持函數(shù)的 SQL 聲明對(duì)query
參數(shù)使用操作符類的被 索引數(shù)據(jù)類型,即便實(shí)際類型可能是某種其他依賴于操作符的東西時(shí)也應(yīng)如此。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: