9.1第53章

From PostgreSQL wiki
Jump to navigationJump to search

52.1 介绍

GIN 表示通用倒排索引(Generalized Inverted Index)。它是一个索引结构,用来保存一个键值对(键字,张贴列表)的集合,在这里,一个“张贴列表”是一个存在有键值的行集合。每个索引的数值可以包含多个键字,因此某些行 ID 可以在很多张贴列表中出现。

通用的意思是,GIN 索引并不需要知道它为之加速的操作是什么。取而代之的是,它使用为特定数据类型定义的客户端策略。

GIN的一个有点是它允许客户数据类型的开发带着合适的访问方法,而且是由这个数据类型领域的专家实现,而不是一个数据库专家来实现。这个优点和 GiST 非常类似。

PostgreSQL 里面的 GIN 实现是 Teodor Sigaev 和 Oleg Bartunov 维护的。在它们的网站上有更多GIN相关的信息。


52.2 扩展性

GIN 接口有一个高层次的抽象,只需要访问方法实现者实现被访问的数据类型的语意。GIN 层本身负责处理并发性,日志和搜索树结构。

要让一个 GIN 访问方法可以运行,我们只需要实现四个用户定义的方法,这四个方法定义树里面的键字的行为和键字,索引值和可索引的查询之间的关系。简单说 GIN 把通用性,代码重用性和干净的界面组合在了一起。

GIN 的索引操作符表必须提供的四个方法是:

int compare(Datum a, Datum b)

   比较键字(不是索引后的数值!),返回一个小于零,等于零或者大于零的整数,表示第一个键字是否小于,等于或者大于第二个键字。 

Datum* extractValue(Datum inputValue, int32 *nkeys)

   给出一个要索引的值,返回一个键字的数组。返回的键字的个数必须存储在 *nkeys 里头。 

Datum* extractQuery(Datum query, int32 *nkeys, StrategyNumber n)

   给出一个带查询的数值,返回一个键字的数组;也就是说,查询是在一个可以索引的操作符右手边的关系,而这个操作符左手边是索引的字段。 n 是操作符在操作符表里面的策略号(见第34.14.2小节)。通常,extractQuery 需要用 n 来判断查询的数据类型和需要抽取的键值。返回的键字的个数必须存储在 *nkeys 里头。如果键字的个数等于零,那么 extractQuery 应该在 *nkeys 里头存储 0或者 -1。0 意味着任何匹配查询的行都会产生一个顺序扫描。 -1 意味着没有什么东西可以满足查询。数值的选择应该基于带有给出策略号的操作的语意进行。 

bool consistent(bool check[], StrategyNumber n, Datum query)

   如果索引的数值满足(或者如果操作符在操作符表里面标记为 RECHECK,那么就是“会满足”)策略号为 n 的查询操作符,则返回真。 check 数组长度和前面用于这个查询的 extractQuery 返回的键字的个数相同。如果索引过的数值暴汉对应的查询键字,那么 check 对应的元素就是 TRUE,也就是说,如果 (check[i] == TRUE),那么 extractQuery 结果数组的第 i 个键字就出现在索引过的数值中。最初的查询数据(不是抽取出来的键字数组!)会传递进来,以便 consistent 方法需要使用之。