63.2. B 树操作符类的行为

Table 38.2所示,btree 运算符类必须提供五个比较运算符<<==>=>。也许有人希望<>也应该是运算符类的一部分,但事实并非如此,因为在索引搜索中使用<> WHERE 子句几乎永远不会有用。 (出于某些目的,计划者将<>视为与 btree 运算符类相关联;但它是通过=运算符的否定符链接而不是从pg_amop找到该运算符的.)

当几种数据类型共享几乎相同的排序语义时,可以将它们的运算符类分组为一个运算符族。这样做是有利的,因为它允许计划者对交叉类型比较进行推论。系列中的每个运算符类都应包含其 Importing 数据类型的单类型运算符(和关联的支持功能),而交叉类型比较运算符和支持功能在该系列中是“松散的”。建议在该系列中包括一整套交叉类型的运算符,从而确保规划器可以代表由传递性推断出的任何比较条件。

btree 运算符族必须满足一些基本假设:

  • =运算符必须是等价关系;也就是说,对于数据类型的所有非空值* A B C *:

    • A * = * A *是真实的(反身法则)
    • 如果* A * = * B ,则 B * = * A *(对称律)

    • 如果* A * = * B B * = * C ,则 A * = * C *(传递律)

  • <运算符必须具有牢固的排序关系;也就是说,对于所有非空值* A B C *:

    • A * < * A *为假(不自反定律)
    • 如果* A * < * B B * < * C ,则 A * < * C *(传递律)
  • 此外,Order 是总计;也就是说,对于所有非空值* A B *:

    • A * < * B A * = * B B * < * A *中的一个正好是(三分法)

(当然,三分法证明了比较支持功能的定义是正确的.)

其他三个运算符以明显的方式根据=<定义,并且必须与它们一致地操作。

对于支持多种数据类型的运算符系列,当从系列中的任何数据类型中获取* A B C *时,必须遵守上述法律。传递律是最难以确保的,因为在交叉类型的情况下,传递律表示两个或三个不同运算符的行为是一致的声明。例如,将float8numeric放在同一个运算符族中是行不通的,至少在目前的语义上,不是将numeric值转换为float8以便与float8进行比较。由于float8的有限精度,这意味着将有不同的numeric值将比较等于相同的float8值,因此传递定律将失败。

对多数据类型族的另一个要求是,在运算符族中包括的数据类型之间定义的任何隐式或二进制强制转换都不得更改关联的排序 Sequences。

应该很清楚为什么 btree 索引要求这些定律保存在单个数据类型中:没有它们,就没有排序键的 Sequences。同样,使用不同数据类型的比较键进行索引搜索要求比较在两种数据类型之间保持理智的表现。 btree 索引机制本身并不严格要求对一个家族中的三个或更多数据类型进行扩展,但是计划者依靠它们来进行优化。