PostgreSQL7.0手册-程序员手册 -43. 扩展索引接口
第四十三章. 扩展索引接口
到目前为止我们描述的过程可以让你定义一个新类型,新函数和新操作符.但是,我们还不能在一个新类型或它的操作符上面定义一个从属索引(象一个 B-tree,R-tree 或哈希(hash)访问方式).
回过头来看看 主要的 Postgres 系统表。右半部分显示了那些我们如果要告诉 Postgres 如何在索引上(例如,pg_am,pg_amop,pg_amproc 和 pg_opclass)去使用用户定义类型和/或用户定义操作符时必须要修改的表.不幸的是,没有简单的命令可以做这些事情.我们将通过实例来演示如何通过修改这些表来实现上面需求,此例子是:一个新的用于 B-tree 访问模式的操作符表,它把复数以绝对值升序的顺序排列.
pg_am 表为每个用户定义的访问模式都保留一条记录.对堆的访问模式的支持内建于 Postgres,但其他所有访问模式在这里都有描述.表结构是
表 43-1. 索引表结构
字段/属性 描述
amname 访问模式名称
amowner 所有这在 pg_user 中的对象标识(object id )
amstrategies 此访问模式的(访问)策略数(见下面)
amsupport 此访问模式支持的过程数(见下面)
amorderstrategy 如果该索引没有提供排序顺序,为零,否则是描述了排序顺序的策略操作符的策略数
amgettuple
aminsert
... 该访问模式的接口过程的过程标识.例如,regproc 表示打开,关闭,和从这里出现的访问模式中获取记录.
pg_am 里的记录的 对象标识(object ID) 用于其他很多表的外部键值.你不需要向这个表里面增加一条新记录;你要关心的是你想要扩展的访问模式记录的 对象标识(object ID):
SELECT oid FROM pg_am WHERE amname = 'btree';
oid
-----
403
(1 row)
我们将在稍后在一个 WHERE 子句中使用这个 SELECT。
amstrategies 字段的存在用于使数据类型之间的比较标准化.例如,B-tree 对键字,小于号到大于号施加了很严格的顺序.因为 Postgres 允许用户定义操作符,所以 Postgres不能只是看到操作符的名称(如,">" 或 "<")就认为是什么样的比较.实际上,一些访问模式并不强加任何顺序要求.例如,R-tree的表达式是长方形包含关系,而一个散列(hash)数据结构表达式只是与散列(hash)函数的结果有一些位(bitwise)相似.Postgres 需要某种连贯的方法从你的查询里取来一个资格(条件),查看一下操作符然后马上决定是否有一个可用的索引存在.这意味着Postgres 需要知道,比如说,象 "<=" 和">" 操作符分割一个 B-tree.Postgres 使用策略来表达这些操作符之间的关系以及它们可以用于扫描索引的方法.
定义一套新的策略超出了这个讨论的范畴,但是我们将 B-tree 策略如何工作,因为你将需要知道了解这些来增加一个新的操作符表.在 pg_am 表里,amstrategies 字段是为这个访问模式定义的策略数量.对于 B-tree,这个数量是 5.这些策略对应于
表 43-2. B-tree 策略
操作 索引
less than(小于) 1
less than or equal(小于或等于) 2
equal(等于) 3
greater than or equal(大于或等于) 4
greater than(大于) 5
方法是你需要增加与上面对应的比较过程到 pg_amop 关系里去(见下面).访问模式代码可以使用这些策略数(不管数据类型是什么),来确定如何分割 B-tree,计算选择性等.先不必关心增加过程的细节问题;只要明白我们必须有一套这样的过程用于 int2,int4,oid,和所有其他 B-tree 可以操作的数据类型.
有时候,策略的信息还不足以让系统决定如何使用某个索引. 一些访问模式就需要其他的一些过程来保证能够工作.例如,B-tree 访问模式必须能够比较两个键字以决定其中一个是大于,等于,还是小于另外一个.类似的,R-tree 访问模式必须能够计算长方形的相交,联合,和大小等.这些操作不能在 SQL 查询里与用户的资格(条件)对应;它们是被访问模式的管理性质的过程内部调用的过程.
为了管理所有 Postgres 的访问模式支持的各种各样的过程,pg_am 包含一个字段叫 amsupport.这个字段记录被某个访问模式支持的过程的个数.对于 B-tree,这个数字是一-一个接受两个键字并且根据第一个键字是否小于,等于或大于第二个键字而返回 -1,0,或 +1的过程.
注意:严格的说,这个过程可以返回一个负数(< 0),0,或一个非零正数(> 0).
pg_am 里的 amstrategies 条目只是正在讨论的访问模式定义的策略数.用于小于,小于等于等的过程不在 pg_am 里出现.类似的,amsupport 只是访问模式需要的支持过程个数.实际的过程在其他地方列出.
顺便说一句,amorderstrategy 字段报告此访问模式是否支持排序的扫描。零意味着它不支持;如果该访问模式支持排序的扫描,amorderstrategy 就是对应排序操作符的策略过程的数目。例如,btree 的 amorderstrategy = 1,就是它的"小于"策略数目。
下一个让人感兴趣的表是 pg_opclass.这个表的存在只是用于把一个名称和一个缺省类型与一个对象标识(oid)联结起来.在 pg_amop,每个 B-tree 操作符表有一套过程,象上面那样从一到五.一些现有的 opclasses 是 int2_ops,int4_ops,和 oid_ops。你需要用你的 opclass 名称(例如,complex_abs_ops)增加一条记录到 pg_opclass 里面.这条记录的 oid 是其他表的外部键字,尤其是 pg_amop.
INSERT INTO pg_opclass (opcname, opcdeftype)
SELECT 'complex_abs_ops', oid FROM pg_type WHERE typname = 'complex';
SELECT oid, opcname, opcdeftype
FROM pg_opclass
WHERE opcname = 'complex_abs_ops';
oid | opcname | opcdeftype
--------+-----------------+------------
277975 | complex_abs_ops | 277946
(1 row)
注意你的 pg_opclass 记录的对象标识(oid)将会不一样!先不考虑这些。我们将在稍后从系统获取这些数字,就象我们在这里获取该类型的 oid 一样。
上面的例子假设你想把这个新的 opclass 做为 complex 数据类型的缺
到目前为止我们描述的过程可以让你定义一个新类型,新函数和新操作符.但是,我们还不能在一个新类型或它的操作符上面定义一个从属索引(象一个 B-tree,R-tree 或哈希(hash)访问方式).
回过头来看看 主要的 Postgres 系统表。右半部分显示了那些我们如果要告诉 Postgres 如何在索引上(例如,pg_am,pg_amop,pg_amproc 和 pg_opclass)去使用用户定义类型和/或用户定义操作符时必须要修改的表.不幸的是,没有简单的命令可以做这些事情.我们将通过实例来演示如何通过修改这些表来实现上面需求,此例子是:一个新的用于 B-tree 访问模式的操作符表,它把复数以绝对值升序的顺序排列.
pg_am 表为每个用户定义的访问模式都保留一条记录.对堆的访问模式的支持内建于 Postgres,但其他所有访问模式在这里都有描述.表结构是
表 43-1. 索引表结构
字段/属性 描述
amname 访问模式名称
amowner 所有这在 pg_user 中的对象标识(object id )
amstrategies 此访问模式的(访问)策略数(见下面)
amsupport 此访问模式支持的过程数(见下面)
amorderstrategy 如果该索引没有提供排序顺序,为零,否则是描述了排序顺序的策略操作符的策略数
amgettuple
aminsert
... 该访问模式的接口过程的过程标识.例如,regproc 表示打开,关闭,和从这里出现的访问模式中获取记录.
pg_am 里的记录的 对象标识(object ID) 用于其他很多表的外部键值.你不需要向这个表里面增加一条新记录;你要关心的是你想要扩展的访问模式记录的 对象标识(object ID):
SELECT oid FROM pg_am WHERE amname = 'btree';
oid
-----
403
(1 row)
我们将在稍后在一个 WHERE 子句中使用这个 SELECT。
amstrategies 字段的存在用于使数据类型之间的比较标准化.例如,B-tree 对键字,小于号到大于号施加了很严格的顺序.因为 Postgres 允许用户定义操作符,所以 Postgres不能只是看到操作符的名称(如,">" 或 "<")就认为是什么样的比较.实际上,一些访问模式并不强加任何顺序要求.例如,R-tree的表达式是长方形包含关系,而一个散列(hash)数据结构表达式只是与散列(hash)函数的结果有一些位(bitwise)相似.Postgres 需要某种连贯的方法从你的查询里取来一个资格(条件),查看一下操作符然后马上决定是否有一个可用的索引存在.这意味着Postgres 需要知道,比如说,象 "<=" 和">" 操作符分割一个 B-tree.Postgres 使用策略来表达这些操作符之间的关系以及它们可以用于扫描索引的方法.
定义一套新的策略超出了这个讨论的范畴,但是我们将 B-tree 策略如何工作,因为你将需要知道了解这些来增加一个新的操作符表.在 pg_am 表里,amstrategies 字段是为这个访问模式定义的策略数量.对于 B-tree,这个数量是 5.这些策略对应于
表 43-2. B-tree 策略
操作 索引
less than(小于) 1
less than or equal(小于或等于) 2
equal(等于) 3
greater than or equal(大于或等于) 4
greater than(大于) 5
方法是你需要增加与上面对应的比较过程到 pg_amop 关系里去(见下面).访问模式代码可以使用这些策略数(不管数据类型是什么),来确定如何分割 B-tree,计算选择性等.先不必关心增加过程的细节问题;只要明白我们必须有一套这样的过程用于 int2,int4,oid,和所有其他 B-tree 可以操作的数据类型.
有时候,策略的信息还不足以让系统决定如何使用某个索引. 一些访问模式就需要其他的一些过程来保证能够工作.例如,B-tree 访问模式必须能够比较两个键字以决定其中一个是大于,等于,还是小于另外一个.类似的,R-tree 访问模式必须能够计算长方形的相交,联合,和大小等.这些操作不能在 SQL 查询里与用户的资格(条件)对应;它们是被访问模式的管理性质的过程内部调用的过程.
为了管理所有 Postgres 的访问模式支持的各种各样的过程,pg_am 包含一个字段叫 amsupport.这个字段记录被某个访问模式支持的过程的个数.对于 B-tree,这个数字是一-一个接受两个键字并且根据第一个键字是否小于,等于或大于第二个键字而返回 -1,0,或 +1的过程.
注意:严格的说,这个过程可以返回一个负数(< 0),0,或一个非零正数(> 0).
pg_am 里的 amstrategies 条目只是正在讨论的访问模式定义的策略数.用于小于,小于等于等的过程不在 pg_am 里出现.类似的,amsupport 只是访问模式需要的支持过程个数.实际的过程在其他地方列出.
顺便说一句,amorderstrategy 字段报告此访问模式是否支持排序的扫描。零意味着它不支持;如果该访问模式支持排序的扫描,amorderstrategy 就是对应排序操作符的策略过程的数目。例如,btree 的 amorderstrategy = 1,就是它的"小于"策略数目。
下一个让人感兴趣的表是 pg_opclass.这个表的存在只是用于把一个名称和一个缺省类型与一个对象标识(oid)联结起来.在 pg_amop,每个 B-tree 操作符表有一套过程,象上面那样从一到五.一些现有的 opclasses 是 int2_ops,int4_ops,和 oid_ops。你需要用你的 opclass 名称(例如,complex_abs_ops)增加一条记录到 pg_opclass 里面.这条记录的 oid 是其他表的外部键字,尤其是 pg_amop.
INSERT INTO pg_opclass (opcname, opcdeftype)
SELECT 'complex_abs_ops', oid FROM pg_type WHERE typname = 'complex';
SELECT oid, opcname, opcdeftype
FROM pg_opclass
WHERE opcname = 'complex_abs_ops';
oid | opcname | opcdeftype
--------+-----------------+------------
277975 | complex_abs_ops | 277946
(1 row)
注意你的 pg_opclass 记录的对象标识(oid)将会不一样!先不考虑这些。我们将在稍后从系统获取这些数字,就象我们在这里获取该类型的 oid 一样。
上面的例子假设你想把这个新的 opclass 做为 complex 数据类型的缺
Tags:PostgreSQL,手册,程序员,手册,扩展,索引,接口

