Skip to content

11.10. 操作符类和操作符族#

索引定义可以为索引的每一列指定一个操作符类

CREATE INDEX name ON table (column opclass [ ( opclass_options ) ] [sort options] [, ...]);

操作符类标识索引将用于该列的操作符。例如,类型int4上的 B 树索引将使用int4_ops类;此操作符类包括类型int4的值的比较函数。在实践中,列的数据类型的默认操作符类通常就足够了。拥有操作符类的主要原因是,对于某些数据类型,可能有多种有意义的索引行为。例如,我们可能希望按绝对值或按实部对复数数据类型进行排序。我们可以通过为数据类型定义两个操作符类,然后在创建索引时选择适当的类来实现此目的。操作符类确定基本排序顺序(然后可以通过添加排序选项COLLATEASC/DESC和/或NULLS FIRST/NULLS LAST来修改此顺序)。

除了默认操作符类之外,还有一些内置操作符类

  • 运算符类 text_pattern_opsvarchar_pattern_opsbpchar_pattern_ops 分别支持类型 textvarcharchar 上的 B 树索引。与默认运算符类的区别在于,值是严格逐个字符进行比较,而不是根据特定于区域设置的排序规则进行比较。这使得这些运算符类适合在数据库不使用标准 C 区域设置时涉及模式匹配表达式(LIKE 或 POSIX 正则表达式)的查询使用。例如,您可以像这样为 varchar 列编制索引

    CREATE INDEX test_index ON test_table (col varchar_pattern_ops);
    

    请注意,如果您希望涉及普通 <<=>>= 比较的查询使用索引,则还应使用默认运算符类创建索引。此类查询无法使用 xxx_pattern_ops 运算符类。(但是,普通的相等比较可以使用这些运算符类。)可以在同一列上使用不同的运算符类创建多个索引。如果您确实使用 C 区域设置,则不需要 xxx_pattern_ops 运算符类,因为在 C 区域设置中,具有默认运算符类的索引可用于模式匹配查询。

以下查询显示所有已定义的运算符类

SELECT am.amname AS index_method,
       opc.opcname AS opclass_name,
       opc.opcintype::regtype AS indexed_type,
       opc.opcdefault AS is_default
    FROM pg_am am, pg_opclass opc
    WHERE opc.opcmethod = am.oid
    ORDER BY index_method, opclass_name;

运算符类实际上只是称为运算符族的更大结构的一个子集。在几种数据类型具有类似行为的情况下,经常有用定义跨数据类型的运算符并允许这些运算符与索引一起使用。为此,必须将每种类型的运算符类分组到同一个运算符族中。跨类型运算符是该族的成员,但与该族中的任何单个类都不关联。

此先前查询的扩展版本显示了每个运算符类所属的运算符族

SELECT am.amname AS index_method,
       opc.opcname AS opclass_name,
       opf.opfname AS opfamily_name,
       opc.opcintype::regtype AS indexed_type,
       opc.opcdefault AS is_default
    FROM pg_am am, pg_opclass opc, pg_opfamily opf
    WHERE opc.opcmethod = am.oid AND
          opc.opcfamily = opf.oid
    ORDER BY index_method, opclass_name;

此查询显示所有已定义的运算符族以及每个族中包含的所有运算符

SELECT am.amname AS index_method,
       opf.opfname AS opfamily_name,
       amop.amopopr::regoperator AS opfamily_operator
    FROM pg_am am, pg_opfamily opf, pg_amop amop
    WHERE opf.opfmethod = am.oid AND
          amop.amopfamily = opf.oid
    ORDER BY index_method, opfamily_name, opfamily_operator;

提示

psql具有命令\dAc\dAf\dAo,这些命令提供了这些查询的稍微复杂一些的版本。