# 68.3.可扩展性

BRIN接口具有较高的抽象级别,只需要访问方法实现者实现所访问的数据类型的语义。BRIN层本身负责并发、记录和搜索索引结构。

要使BRIN访问方法发挥作用,只需实现几个用户定义的方法,这些方法定义存储在索引中的摘要值的行为以及它们与扫描键的交互方式。简而言之,BRIN将可扩展性与通用性、代码重用和干净的接口结合起来。

BRIN的运算符类必须提供四种方法:

BrinOpcInfo*opcInfo(Oid类型_Oid)

返回有关索引列的摘要数据的内部信息。返回值必须指向palloc'd布林诺普辛福,其定义如下:

typedef struct BrinOpcInfo
{
    /* Number of columns stored in an index column of this opclass */
    uint16      oi_nstored;

    /* Opaque pointer for the opclass' private use */
    void       *oi_opaque;

    /* Type cache entries of the stored columns */
    TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
} BrinOpcInfo;

布林诺普辛福.oi_不透明可由操作员类例程在索引扫描期间在支持函数之间传递信息。

布尔一致性(BrinDesc*bdesc、BrinValues*列、ScanKey*键、int NKEY)

返回所有扫描键项是否与某个范围的给定索引值一致。要使用的属性号作为扫描键的一部分传递。同一属性的多个扫描键可以一次传递;条目的数量由肯基参数。

布尔一致(BrinDesc*bdesc,BrinValues*列,扫描键)

返回扫描键是否与某个范围的给定索引值一致。要使用的属性号作为扫描键的一部分传递。这是一致函数的一个较旧的向后兼容变体。

bool addValue(BrinDesc*bdesc,BrinValues*列,基准新值,bool为空)

给定一个索引元组和一个索引值,修改元组的指示属性,使其另外表示新值。如果对元组做了任何修改,被退回。

布尔联合元组(BrinDesc*bdesc、BrinValues*a、BrinValues*b)

合并两个索引元组。给定两个索引元组,修改第一个索引元组的指示属性,使其表示两个元组。第二个元组不会被修改。

BRIN的运算符类可以选择指定以下方法:

无效选项(本地重新选择*重新选择)

定义一组控制运算符类行为的用户可见参数。

这个选项函数被传递一个指向本地重新选择struct,它需要填充一组特定于运算符类的选项。可以使用从其他支持功能访问这些选项PG_有_OPCLASS_选项()PG_GET_OPCLASS_OPTIONS()宏。

由于索引值的键提取和BRIN中键的表示都是灵活的,它们可能取决于用户指定的参数。

核心发行版支持四种类型的操作符类:minmax、minmax multi、inclusion和bloom。使用它们的运算符类定义将根据需要提供给核心数据类型。用户可以使用等效定义为其他数据类型定义其他运算符类,而无需编写任何源代码;声明适当的目录条目就足够了。请注意,关于运算符策略语义的假设嵌入在支持函数的源代码中。

如果编写了上述四个主要支持函数的实现,那么实现完全不同语义的运算符类也是可能的。请注意,不能保证主要版本之间的向后兼容性:例如,在以后的版本中可能需要额外的支持功能。

要为实现完全有序集的数据类型编写运算符类,可以在使用相应运算符的同时使用minmax支持函数,如中所示表68.2.所有运算符类成员(函数和运算符)均为必填项。

表68.2.Minmax运算符类的函数和支持编号

操作员类成员 对象
支持功能1 内部功能brin_minmax_opcinfo()
支持职能2 内部功能brin_minmax_add_value()
支持职能3 内部功能brin_minmax_consistent()
支持功能4 内部功能brin_minmax_union()
运营商策略1 操作员少于
运营商策略2 运算符小于或等于
运营商策略3 运算符等于
运营商策略4 运算符大于或等于
运营商策略5 运算符大于

要为包含其他类型中的值的复杂数据类型编写运算符类,可以在使用相应运算符的同时使用包含支持函数,如中所示表68.3.它只需要一个附加函数,可以用任何语言编写。可以为附加功能定义更多功能。所有操作员都是可选的。某些运算符需要其他运算符,如表上的依赖项所示。

表68.3.包含运算符类的函数和支持号

操作员类成员 对象 附属国
支持功能1 内部功能brin_夹杂物_opcinfo()
支持职能2 内部功能brin_包含_添加_值()
支持职能3 内部功能brin_夹杂物_一致()
支持功能4 内部功能布林联盟
支持功能11 函数合并两个元素
支持职能12 可选功能,用于检查两个元素是否可合并
支持职能13 可选函数,用于检查一个元素是否包含在另一个元素中
支持职能14 用于检查元素是否为空的可选函数
运营商策略1 左边的接线员 运营商策略4
运营商策略2 操作员未延伸到操作员的右侧 运营商策略5
运营商策略3 运算符重叠
运营商策略4 运算符不延伸到左侧 运营商策略1
运营商策略5 经营者权利 运营商策略2
运营商策略6、18 运算符等于或等于 运营商策略7
运营商策略7,16,24,25 运算符包含或等于
运营商策略8、26、27 运算符包含或等于 运营商策略3
运营商策略9 运算符不延伸到上面 运营商策略11
运营商策略10 运算符在下方 运营商策略 12
运营商策略 11 运算符高于 运营商攻略9
运营商策略 12 运算符不在下面扩展 运营商攻略10
运营商策略 20 运算符小于 运营商策略5
运营商策略 21 运算符小于或等于 运营商策略5
运营商策略 22 运算符大于 运营商策略一
运营商策略 23 运算符大于或等于 运营商策略一

支持函数号 1 到 10 是为 BRIN 内部函数保留的,因此 SQL 级别的函数以数字 11 开头。支持函数号 11 是构建索引所需的主要函数。它应该接受与操作符类具有相同数据类型的两个参数,并返回它们的并集。包含运算符类可以存储具有不同数据类型的联合值,如果它是用贮存范围。联合函数的返回值应与贮存数据类型。提供支持功能编号 12 和 14 以支持内置数据类型的不规则性。

功能编号 12 用于支持来自不同系列的不可合并的网络地址。功能编号 14 用于支持空范围。函数号 13 是一个可选但推荐的函数,它允许在将新值传递给联合函数之前对其进行检查。由于 BRIN 框架可以在 union 不变的情况下对一些操作进行快捷化,使用该功能可以提高索引性能。要为仅实现相等运算符并支持散列的数据类型编写运算符类,可以将bloom支持过程与相应的运算符一起使用,如下所示

表 68.4.所有操作员类成员(过程和操作员)都是强制性的。表 68.4.

Bloom 运算符类的过程和支持编号

操作员类成员 目的
支持程序 1 内部功能brin_bloom_opcinfo()
支持程序 2 内部功能brin_bloom_add_value()
支持程序 3 内部功能brin_bloom_consistent()
支持程序 4 内部功能brin_bloom_union()
支持程序 11 计算元素哈希的函数
运营商策略一 运算符等于

1-10号的支持过程是为BRIN内部函数保留的,所以SQL级别的函数从11号开始。11号支持函数是构建索引所需的主要函数。它应该接受一个与操作符类具有相同数据类型的参数,并返回该值的哈希值。minmax-multi 运算符类也适用于实现完全有序集的数据类型,可以看作是 minmax 运算符类的简单扩展。

虽然 minmax 运算符类将每个块范围的值汇总到单个连续间隔中,但 minmax-multi 允许汇总到多个较小的间隔中以改进对异常值的处理。可以将 minmax-multi 支持过程与相应的运算符一起使用,如表 68.5.所有操作员类成员(过程和操作员)都是强制性的。表 68.5.

minmax-multi 运算符类的过程和支持编号

操作员类成员 目的
支持程序 1 内部功能brin_minmax_multi_opcinfo()
支持程序 2 内部功能brin_minmax_multi_add_value()
支持程序 3 内部功能brin_minmax_multi_consistent()
支持程序 4 内部功能brin_minmax_multi_union()
支持程序 11 计算两个值之间距离的函数(范围的长度)
运营商策略一 运算符小于
运营商策略二 运算符小于或等于
运营商策略3 运算符等于
运营商策略4 运算符大于或等于
运营商策略5 运算符大于

minmax 和包含运算符类都支持跨数据类型的运算符,尽管有了这些,依赖关系变得更加复杂。minmax 运算符类需要使用具有相同数据类型的两个参数来定义完整的运算符集。它允许通过定义额外的运算符集来支持其他数据类型。包含运算符类运算符策略依赖于另一个运算符策略,如表 68.3,或与自己相同的运营商策略。它们要求依赖运算符定义为贮存数据类型作为左侧参数,另一个支持的数据类型作为支持的运算符的右侧参数。看float4_minmax_ops作为 minmax 的一个例子,和box_inclusion_ops作为包容的例子。