↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 16 / 15 / 14
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5

71.3. 可扩展性 #

BRIN 接口具有较高层次的抽象,访问方法实现者只需实现被访问数据类型的语义。BRIN 层本身负责并发、日志记录以及搜索索引结构。

要让一种 BRIN 访问方法工作起来,只需实现少数几个用户定义的方法,它们定义索引中存储的摘要值的行为,以及这些摘要值与扫描键之间的交互。简言之,BRIN 把可扩展性与通用性、代码重用以及清晰的接口结合在一起。

BRIN 操作符类必须提供以下四个方法:

BrinOpcInfo *opcInfo(Oid type_oid)

返回被索引列的摘要数据的内部信息。返回值必须指向一个用 palloc 分配的 BrinOpcInfo,其定义如下:

typedef struct BrinOpcInfo
{
    /* 此操作符类在一个索引列中存储的列数 */
    uint16      oi_nstored;

    /* 供操作符类私有使用的不透明指针 */
    void       *oi_opaque;

    /* 所存储列的类型缓存条目 */
    TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
} BrinOpcInfo;

BrinOpcInfo.oi_opaque 可供操作符类例程在索引扫描期间于各个支持函数之间传递信息。

bool consistent(BrinDesc *bdesc, BrinValues *column, ScanKey *keys, int nkeys)

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

bool consistent(BrinDesc *bdesc, BrinValues *column, ScanKey key)

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

bool addValue(BrinDesc *bdesc, BrinValues *column, Datum newval, bool isnull)

给定一个索引元组和一个被索引值,修改该元组中指定的属性,使其能够额外表示这个新值。如果对该元组做了任何修改,就返回 true。

bool unionTuples(BrinDesc *bdesc, BrinValues *a, BrinValues *b)

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

BRIN 操作符类还可以选择指定下列方法:

void options(local_relopts *relopts)

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

options 函数会接收一个指向 local_relopts 结构体的指针,需要用一组操作符类专用选项填充它。这些选项可以通过 PG_HAS_OPCLASS_OPTIONS() 和 PG_GET_OPCLASS_OPTIONS() 宏从其他支持函数中访问。

由于被索引值的键提取以及 BRIN 中键的表示都具有灵活性,它们可能依赖于用户指定的参数。

核心发行版包含四种操作符类支持:minmax、minmax-multi、inclusion 和 bloom。针对核心数据类型,发行版会酌情附带使用它们的操作符类定义。用户也可以为其他数据类型定义等价的操作符类,而无需编写任何源代码;只要声明适当的系统目录项即可。注意,对操作符策略语义的某些假设嵌入在支持函数的源码中。

只要为上文所述的四个主要支持函数编写实现,也可以实现语义完全不同的操作符类。注意,不保证跨主版本的向后兼容性:例如,在后续版本中可能需要附加的支持函数。

要为实现全序集的数据类型编写操作符类,可以按表 71.2 所示,将 minmax 支持函数与相应操作符一起使用。所有操作符类成员(函数和操作符)都是必需的。

表 71.2. Minmax 操作符类的函数和支持编号

操作符类成员对象
支持函数 1内部函数 brin_minmax_opcinfo()
支持函数 2内部函数 brin_minmax_add_value()
支持函数 3内部函数 brin_minmax_consistent()
支持函数 4内部函数 brin_minmax_union()
操作符策略 1小于操作符
操作符策略 2小于等于操作符
操作符策略 3等于操作符
操作符策略 4大于等于操作符
操作符策略 5大于操作符

要为一种值能够被包含在另一种类型中的复杂数据类型编写操作符类,可以按表 71.3 所示,将 inclusion 支持函数与相应操作符一起使用。它只需要额外一个函数,而且该函数可以用任何语言编写。还可以定义更多函数以提供附加功能。所有操作符都是可选的。某些操作符依赖其他操作符,表中已列出这些依赖关系。

表 71.3. Inclusion 操作符类的函数和支持编号

操作符类成员对象依赖关系
支持函数 1内部函数 brin_inclusion_opcinfo() 
支持函数 2内部函数 brin_inclusion_add_value() 
支持函数 3内部函数 brin_inclusion_consistent() 
支持函数 4内部函数 brin_inclusion_union() 
支持函数 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大于操作符操作符策略 1
操作符策略 23大于等于操作符操作符策略 1

支持函数编号 1 到 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。支持函数 11 是构建索引所需的主要函数。它应接受两个与操作符类数据类型相同的参数,并返回它们的并集。如果 inclusion 操作符类在定义时使用了 STORAGE 参数,则它可以存储具有不同数据类型的并集值。并集函数的返回值应与 STORAGE 数据类型匹配。

支持函数 12 和 14 用于处理内置数据类型中的不规则情况。函数 12 用于支持来自不同地址族、无法合并的网络地址。函数 14 用于支持空范围。函数 13 是可选但推荐的;它允许在把新值传给并集函数之前先进行检查。由于 BRIN 框架在并集未发生变化时可以跳过某些操作,使用这个函数可以提升索引性能。

要为仅实现等值操作符且支持 hash 的数据类型编写操作符类,可以按表 71.4 所示,将 bloom 支持函数与相应操作符一起使用。所有操作符类成员(函数和操作符)都是必需的。

表 71.4. bloom 操作符类的函数和支持编号

操作符类成员对象
支持函数 1内部函数 brin_bloom_opcinfo()
支持函数 2内部函数 brin_bloom_add_value()
支持函数 3内部函数 brin_bloom_consistent()
支持函数 4内部函数 brin_bloom_union()
支持函数 5内部函数 brin_bloom_options()
支持函数 11计算元素 hash 值的函数
操作符策略 1等于操作符

支持函数编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。支持函数 11 是构建索引所需的主要函数。它应接受一个与操作符类数据类型相同的参数,并返回该值的 hash 值。

minmax-multi 操作符类也面向实现全序集的数据类型,可以看作 minmax 操作符类的简单扩展。minmax 操作符类把每个块范围中的值摘要为单个连续区间,而 minmax-multi 则允许将其摘要为多个较小区间,以改进对离群值的处理。可以按表 71.5 所示,将 minmax-multi 支持函数与相应操作符一起使用。所有操作符类成员(函数和操作符)都是必需的。

表 71.5. minmax-multi 操作符类的函数和支持编号

操作符类成员对象
支持函数 1内部函数 brin_minmax_multi_opcinfo()
支持函数 2内部函数 brin_minmax_multi_add_value()
支持函数 3内部函数 brin_minmax_multi_consistent()
支持函数 4内部函数 brin_minmax_multi_union()
支持函数 5内部函数 brin_minmax_multi_options()
支持函数 11计算两个值之间距离(范围长度)的函数
操作符策略 1小于操作符
操作符策略 2小于等于操作符
操作符策略 3等于操作符
操作符策略 4大于等于操作符
操作符策略 5大于操作符

minmax 和 inclusion 操作符类都支持跨数据类型操作符,但这样依赖关系会更加复杂。minmax 操作符类要求定义一整套两侧参数都具有相同数据类型的操作符。它还允许通过定义额外的操作符集合来支持附加数据类型。如表 71.3 所示,inclusion 操作符类的操作符策略依赖于另一种操作符策略,或者依赖于它们自身对应的同名操作符策略。这要求把依赖操作符定义为:左侧参数是 STORAGE 数据类型,右侧参数是其他受支持的数据类型。minmax 的示例见 float4_minmax_ops,inclusion 的示例见 box_inclusion_ops。

报告文档问题

阅读 上游文档. 通过 PostgreSQL 文档反馈表单.