(作为对比,简单看了下Oracle 12c的手册。Oracle也可以支持类型定制,但看上去比PG弱。Oracle的自定义数据类型依赖于已有的原生数据类型,自定义操作符的使用方法也比较怪异更像是函数调用,自定义索引类型看上去很复杂没多看)
1. 数据类型
pg_type
http://58.58.27.50:8079/doc/html/9.3.1_zh/catalog-pg-type.html----------------------------------------------------------------
47.51.pg_type
pg_type存储有关数据类型的信息。基本类型和枚举类型(标量类型)是用CREATE TYPE创建的,域是使用CREATE DOMAIN创建的。 同时还为数据库中每个表自动创建一个复合类型,以表示该表的行结构。还可以用CREATE TYPE AS创建复合类型。
Table 47-51.pg_type字段
名字 | 类型 | 引用 | 描述 |
---|---|---|---|
oid@H_301_42@ | oid@H_301_42@ | @H_301_42@ | 行标识符(隐藏属性;必须明确选择)@H_301_42@ |
typname@H_301_42@ | name@H_301_42@ | @H_301_42@ | 数据类型名@H_301_42@ |
typnamespace@H_301_42@ | oid@H_301_42@ | pg_namespace.oid@H_301_42@ | 包含这个类型的名字空间的OID@H_301_42@ |
typowner@H_301_42@ | oid@H_301_42@ | pg_authid.oid@H_301_42@ | 该类型的所有者@H_301_42@ |
typlen@H_301_42@ | int2@H_301_42@ | @H_301_42@ | 对于定长类型是该类型内部表现形式的字节数目。对于变长类型是负数。 -1 表示一种"变长"类型(有长度字属性的数据), -2 表示这是一个 NULL 结尾的 C 字符串。@H_301_42@ |
typbyval@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 判断内部过程传递这个类型的数值时是通过传值还是传引用。 如果该类型不是 1,2,4,8 字节长将只能按引用传递,因此 typbyval 最好是假。 即使可以传值,typbyval 也可以为假。@H_301_42@ |
typtype@H_301_42@ | char@H_301_42@ | @H_301_42@ | 对于基础类型是b,对于复合类型是c(比如,一个表的行类型)。对于域类型是d,对于枚举类型是e, 对于伪类型是p,对于范围类型是r。 又见typrelid和typbasetype。@H_301_42@ |
typcategory@H_301_42@ | char@H_301_42@ | @H_301_42@ | typcategory是数据类型的任意分类, 该数据类型被触发器用来决定哪种隐式转换应该是"首选"。 参阅Table 47-52。@H_301_42@ |
typispreferred@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 如果类型在它的typcategory里是首选转换目标则为真。@H_301_42@ |
typisdefined@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 如果定义了类型则为真,如果是一种尚未定义的类型的占位符则为假。如果为假, 那么除了该类型名称,名字空间,和 OID 之外没有可靠的信息。@H_301_42@ |
typdelim@H_301_42@ | char@H_301_42@ | @H_301_42@ | 当分析数组输入时,分隔两个此类型数值的字符。请注意该分隔符是与数组元素数据类型相关联的, 而不是和数组数据类型关联。@H_301_42@ |
typrelid@H_301_42@ | oid@H_301_42@ | pg_class.oid@H_301_42@ | 如果是复合类型(见typtype)那么这个字段指向pg_class中定义该表的行。对于自由存在的复合类型,pg_class记录并不表示一个表, 但是总需要它来查找该类型连接的pg_attribute记录。对于非复合类型为零。@H_301_42@ |
typelem@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 如果不为 0 ,那么它标识pg_type里面的另外一行。 当前类型可以像一个数组产生类型为typelem的值一样当做下标。 一个"真正的"数组类型是变长的(typlen= -1), 但是一些定长的(typlen> 0)类型也拥有非零的typelem(比如name和point)。如果一个定长类型拥有一个typelem, 那么他的内部形式必须是typelem数据类型的某个数目的个数值, 不能有其它数据。变长数组类型有一个该数组子过程定义的头(文件)。@H_301_42@ |
typarray@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 如果typarray非零,那么它在pg_type里定义另外一行,该行是将这个类型作为元素的"真正的"数组类型。@H_301_42@ |
typinput@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 输入转换函数(文本格式)@H_301_42@ |
typoutput@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 输出转换函数(文本格式)@H_301_42@ |
typreceive@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 输入转换函数(二进制格式),如果没有则为 0@H_301_42@ |
typsend@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 输出转换函数(二进制格式),如果没有则为 0@H_301_42@ |
typmodin@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 类型修饰符输入函数,如果类型不支持修饰符则为0@H_301_42@ |
typmodout@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 类型修饰符输出函数,如果使用标准格式则为0@H_301_42@ |
typanalyze@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 自定义的ANALYZE函数,如果使用标准函数,则为 0@H_301_42@ |
typalign@H_301_42@ | char@H_301_42@ | @H_301_42@ | 当存储此类型的数值时要求的对齐性质。它应用于磁盘存储以及该值在Postgresql内部的大多数形式。如果数值是连续存放的,比如在磁盘上以完全的裸数据的形式存放时, 那么先在此类型的数据前填充空白,这样它就可以按照要求的界限存储。对齐引用是该序列中第一个数据的开头。 可能的值有:
|
typstorage@H_301_42@ | char@H_301_42@ | @H_301_42@ | 告诉一个变长类型(那些有typlen= -1的) 说该类型是否准备好应付非常规值,以及对这种类型的属性的缺省策略是什么。可能的值有
请注意m域也可以移到从属表里存储,但只是最后的解决方法 (e和x域先移走)。 @H_301_42@ |
typnotnull@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 代表在某类型上的一个 NOTNULL 约束。目前只用于域。 @H_301_42@ |
typbasetype@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 如果这是一个域(参阅typtype), 那么标识作为这个类型的基础的类型。如果不是域则为零。 @H_301_42@ |
typtypmod@H_301_42@ | int4@H_301_42@ | @H_301_42@ | 域使用typtypmod记录要作用到它们的基础类型上的typmod(如果基础类型不使用typmod则为 -1)。如果这种类型不是域,那么为 -1 。 @H_301_42@ |
typndims@H_301_42@ | int4@H_301_42@ | @H_301_42@ | 如果是一个域数组,那么typndims是数组维数的数值(也就是说,typbasetype是一个数组类型)。非域非数组类型为零。 @H_301_42@ |
typcollation@H_301_42@ | oid@H_301_42@ | pg_collation.oid@H_301_42@ | 指定类型的排序规则。如果类型不支持排序,则为0。一个支持排序的基础类型将有DEFAULT_COLLATION_OID。一个可排序类型的域可以有一些其他排序OID, 如果为该域指定了一个的话。 @H_301_42@ |
typdefaultbin@H_301_42@ | pg_node_tree@H_301_42@ | @H_301_42@ | 如果为非 NULL ,那么它是该类型缺省表达式的nodeToString()表现形式。 目前这个字段只用于域。 @H_301_42@ |
typdefault@H_301_42@ | text@H_301_42@ | @H_301_42@ | 如果某类型没有相关缺省值,那么typdefault是 NULL 。如果typdefaultbin不是 NULL ,那么typdefault必须包含一个typdefaultbin代表的缺省表达式的人类可读的版本。如果typdefaultbin为 NULL 但typdefault不是,那么typdefault是该类型缺省值的外部表现形式, 可以把它交给该类型的输入转换器生成一个常量。 @H_301_42@ |
typacl@H_301_42@ | aclitem[]@H_301_42@ | @H_301_42@ | 访问权限;参阅GRANT和REVOKE获取细节。@H_301_42@ |
Table 47-52列出了系统定义的typcategory的值。 任何未来添加到这个列表的也是大写的ASCII字母。所有其他ASCII字符为用户定义的范畴保留。
Table 47-52.typcategory代码
代码 | 种类 |
---|---|
A@H_301_42@ | 数组类型@H_301_42@ |
B@H_301_42@ | 布尔类型@H_301_42@ |
C@H_301_42@ | 复合类型@H_301_42@ |
D@H_301_42@ | 日期/时间类型@H_301_42@ |
E@H_301_42@ | 枚举类型@H_301_42@ |
G@H_301_42@ | 几何类型@H_301_42@ |
I@H_301_42@ | 网络地址类型@H_301_42@ |
N@H_301_42@ | 数值类型@H_301_42@ |
P@H_301_42@ | 伪类型@H_301_42@ |
R@H_301_42@ | 范围类型@H_301_42@ |
S@H_301_42@ | 字符串类型@H_301_42@ |
T@H_301_42@ | 时间间隔类型@H_301_42@ |
U@H_301_42@ | 用户定义类型@H_301_42@ |
V@H_301_42@ | 位串类型@H_301_42@ |
X@H_301_42@ | 未知类型@H_301_42@ |
----------------------------------------------------------------
比较关键是4个输入输出函数:typinput,typoutput,typreceive,typsend。PG通过这4个函数读写数据,所以扩展数据类型时,只要按要求实现好这4个函数,可以自由定义数据的内部存储格式。
例: jsonb类型
postgres=# select oid,* from pg_type where typname='jsonb'; -[ RECORD 1 ]--+----------- oid | 3802 typname | jsonb typnamespace | 11 typowner | 10 typlen | -1 typbyval | f typtype | b typcategory | U typispreferred | f typisdefined | t typdelim |,typrelid | 0 typelem | 0 typarray | 3807 typinput | jsonb_in typoutput | jsonb_out typreceive | jsonb_recv typsend | jsonb_send typmodin | - typmodout | - typanalyze | - typalign | i typstorage | x typnotnull | f typbasetype | 0 typtypmod | -1 typndims | 0 typcollation | 0 typdefaultbin | typdefault | typacl |
创建新的数据类型的sql:
CREATE TYPE --定义一个新数据类型
详细用法参考手册:http://58.58.27.50:8079/doc/html/9.3.1_zh/sql-createtype.html
2. 操作符
----------------------------------------------------------------
47.33.pg_operator
pg_operator存储有关操作符的信息。参阅 CREATE OPERATOR 和 节33.12 获取这些操作符参数的细节。
Table 47-33.pg_operator字段
名字 | 类型 | 引用 | 描述 |
---|---|---|---|
oid@H_301_42@ | oid@H_301_42@ | @H_301_42@ | 行标识符(隐藏属性;必须明确选择)@H_301_42@ |
oprname@H_301_42@ | name@H_301_42@ | @H_301_42@ | 操作符的名字@H_301_42@ |
oprnamespace@H_301_42@ | oid@H_301_42@ | pg_namespace.oid@H_301_42@ | 包含此操作符的名字空间的 OID@H_301_42@ |
oprowner@H_301_42@ | oid@H_301_42@ | pg_authid.oid@H_301_42@ | 操作符所有者@H_301_42@ |
oprkind@H_301_42@ | char@H_301_42@ | @H_301_42@ | b= infix = 中缀("两边"),l= 前缀("左边"),r= 后缀("右边")@H_301_42@ |
oprcanmerge@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 这个操作符支持合并连接@H_301_42@ |
oprcanhash@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 这个操作符支持 Hash 连接@H_301_42@ |
oprleft@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 左操作数的类型@H_301_42@ |
oprright@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 右操作数的类型@H_301_42@ |
oprresult@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 结果类型@H_301_42@ |
oprcom@H_301_42@ | oid@H_301_42@ | pg_operator.oid@H_301_42@ | 此操作符的交换符,如果存在的话@H_301_42@ |
oprnegate@H_301_42@ | oid@H_301_42@ | pg_operator.oid@H_301_42@ | 此操作符的反转器,如果存在的话@H_301_42@ |
oprcode@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 实现这个操作符的函数@H_301_42@ |
oprrest@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 此操作符的约束选择性计算函数@H_301_42@ |
oprjoin@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 此操作符的连接选择性计算函数@H_301_42@ |
未用的字段包含零。比如,oprleft对于前缀操作符而言是零。
例: jsonb的@>操作符
postgres=# select oid,* from pg_operator where oprleft=3802 and oprname='@>'; -[ RECORD 1 ]+--------------- oid | 3246 oprname | @> oprnamespace | 11 oprowner | 10 oprkind | b oprcanmerge | f oprcanhash | f oprleft | 3802 oprright | 3802 oprresult | 16 oprcom | 3250 oprnegate | 0 oprcode | jsonb_contains oprrest | contsel oprjoin | contjoinsel
创建新的操作符的sql:
CREATE OPERATOR --定义一个新操作符
3. 索引扩展
索引访问方法
索引访问方法代表了索引算法, 目前PG提供了5种 索引访问方法,btree,hash,gist,gin和spgist。 其中 gist 和 spgist可以 支持多种多维数据的索引 算法。比如基于gist的R-tree,RD-tree,基于spgist的quad-trees,k-d trees和 radix trees。索引访问方法相关的信息存储在系统表pg_am中。
操作符类
一个索引方法的过程并不直接知道任何该索引方法将要操作的数据类型的信息。 而是 操作符类 表明索引方法在操作特定数据类型的时候需要使用的操作集合。这么说比较抽象,实际一点,create index的using子句中可以指定的索引字段数据类型的某个操作符类作为具体的索引实现(不指定的话,使用该数据类型的默认操作符类)。索引访问方法相关的信息存储在系统表pg_am中。操作符类相关的信息存储在系统表pg_opclass中。
索引方法策略
索引方法策略是操作符在操作符类环境里的内部表示。比如,B-tree索引的”等于“操作对应的策略号为3。因为Postgresql允许用户定义操作符,Postgresql 无法仅通过查看操作符的名字(比如<或>=)就明白它进行的比较是什么,所以索引方法定义了一套"策略",它可以看作一般性的操作符。比如,你可以把你的数据类型的等于操作符的名字定义成"="也可以定义成"==",只要把它的策略号设定为3,B-tree就可以知道它的语义是"等于"了。 操作符类包含的操作符集合和索引方法策略号的对应关系存储在系统表 pg_amop 中 。
索引方法支持函数
有时候,策略的信息还不足以让系统决定如何使用某个索引。在实际中, 索引方法需要附加的一些过程来保证正常工作。例如, B-tree 索引方法必须能够比较两个键字以决定其中一个是大于、等于、还是小于另外一个。与策略号相似,索引方法通过“支持号”识别支持函数。 操作符类包含的支持函数集合和支持号的对应关系存储在系统表 pg_amproc 中 。
操作符族
一个操作符类代表一种数据类型,而一个操作符族则可以包含一个或多个操作符类,它们代表一类相似的数据类型,比如int2,int4和int8。这样可以在操作符族上定义一些交叉数据类型操作符(比如int4和int8的比较)。操作符族相关的信息都存储在系统表pg_opfamily中,并且pg_opclass,pg_amop和pg_amproc通过pg_opfamily的oid聚集成一个整体。
为了说明这索引扩展相关的几个系统表的关系,后面的例子采用下面的 操作符类(族)gist__int_ops2进行说明。
下面这个例子,为int4数组创建一个 操作符 类gist__int_ops2(pg_opclass),并且由于没有指定 操作符族,所以创建一个同名的操作符族 gist__int_ops ( pg_opfamily ) 。OPERATOR相关的定义会存到 pg_amop ,FUNCTION相关的定义会存到 pg_amproc 。
CREATE OPERATOR CLASS gist__int_ops2 FOR TYPE _int4 USING gist AS OPERATOR 3 &&,OPERATOR 6 = (anyarray,anyarray),OPERATOR 7 @>,OPERATOR 8 <@,OPERATOR 13 @,OPERATOR 14 ~,OPERATOR 20 @@ (_int4,query_int),FUNCTION 1 g_int_consistent (internal,_int4,int,oid,internal),FUNCTION 2 g_int_union (internal,FUNCTION 3 g_int_compress (internal),FUNCTION 4 g_int_decompress (internal),FUNCTION 5 g_int_penalty (internal,internal,FUNCTION 6 g_int_picksplit (internal,FUNCTION 7 g_int_same (_int4,internal);
pg_am
----------------------------------------------------------------
47.3.pg_am
pg_am存储有关索引访问方法的信息。系统支持的每种索引访问方法都有一行。 这个表的内容在Chapter 54详细讨论。
Table 47-3.pg_am字段
名字 | 类型 | 引用 | 描述 |
---|---|---|---|
oid@H_301_42@ | oid@H_301_42@ | @H_301_42@ | 行标识符(隐藏属性; 必须明确选择)@H_301_42@ |
amname@H_301_42@ | name@H_301_42@ | @H_301_42@ | 访问方法的名字@H_301_42@ |
amstrategies@H_301_42@ | int2@H_301_42@ | @H_301_42@ | 这个访问方法的操作符策略个数,或者如果访问方法没有一个固定的操作符策略集则为0。@H_301_42@ |
amsupport@H_301_42@ | int2@H_301_42@ | @H_301_42@ | 这个访问方法的支持过程个数@H_301_42@ |
amcanorder@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 这种访问方式是否支持通过索引字段值的命令扫描排序?@H_301_42@ |
amcanorderbyop@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 这种访问方式是否支持通过索引字段上操作符的结果的命令扫描排序?@H_301_42@ |
amcanbackward@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 这种访问方式是否支持向后扫描?@H_301_42@ |
amcanunique@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 这种访问方式是否支持唯一索引?@H_301_42@ |
amcanmulticol@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 这种访问方式是否支持多字段索引?@H_301_42@ |
amoptionalkey@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 这种访问方式是否支持第一个索引字段上没有任何约束的扫描?@H_301_42@ |
amsearcharray@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 这种访问方式是否支持ScalarArrayOpExpr搜索?@H_301_42@ |
amsearchnulls@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 这种访问方式是否支持IS NULL/NOT NULL搜索?@H_301_42@ |
amstorage@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 允许索引存储的数据类型与列的数据类型不同?@H_301_42@ |
amclusterable@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 允许在一个这种类型的索引上群集?@H_301_42@ |
ampredlocks@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 允许这种类型的一个索引管理细粒度的谓词锁定?@H_301_42@ |
amkeytype@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 存储在索引里的数据的类型,如果不是一个固定的类型则为0@H_301_42@ |
aminsert@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | "插入这个行"函数@H_301_42@ |
ambeginscan@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | "准备索引扫描"函数@H_301_42@ |
amgettuple@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | "下一个有效行"函数,如果没有则为0@H_301_42@ |
amgetbitmap@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | "抓取所有有效行"函数,如果没有则为0@H_301_42@ |
amrescan@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | "(重新)开始索引扫描"函数@H_301_42@ |
amendscan@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | "索引扫描后清理"函数@H_301_42@ |
ammarkpos@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | "标记当前扫描位置"函数@H_301_42@ |
amrestrpos@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | "恢复已标记的扫描位置"函数@H_301_42@ |
ambuild@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | "建立新索引"函数@H_301_42@ |
ambuildempty@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | "建立空索引"函数@H_301_42@ |
ambulkdelete@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 批量删除函数@H_301_42@ |
amvacuumcleanup@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | VACUUM后的清理函数@H_301_42@ |
amcanreturn@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 检查是否索引支持唯一索引扫描的函数,如果没有则为0@H_301_42@ |
amcostestimate@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 估计一个索引扫描开销的函数@H_301_42@ |
amoptions@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 为一个索引分析和确认reloptions的函数@H_301_42@ |
目前PG提供了5种索引访问方法。PG没有提供扩展索引访问方法的sql语句,但通过往pg_am中插入记录也不是不可以扩展出新的索引访问方法。
postgres=# select oid,amname,amstrategies,amsupport from pg_am; oid | amname | amstrategies | amsupport ------+--------+--------------+----------- 403 | btree | 5 | 2 405 | hash | 1 | 1 783 | gist | 0 | 8 2742 | gin | 0 | 6 4000 | spgist | 0 | 5 (5 rows)
pg_opfamily
http://58.58.27.50:8079/doc/html/9.3.1_zh/catalog-pg-opfamily.html
----------------------------------------------------------------
47.34.pg_opfamily
pg_opfamily表定义操作符族。每个操作符族是一个操作符和相关支持例程的集合, 其中的例程实现为一个特定的索引访问方式指定的语义。另外,族中的操作符都是"兼容的", 通过由访问方式指定的方法。操作符族的概念允许交叉数据类型操作符和索引一起使用, 并且合理的使用访问方式的语义的知识。
操作符族在Section 35.14里面描述。
Table 47-34.pg_opfamily字段
名字 | 类型 | 引用 | 描述 |
---|---|---|---|
oid@H_301_42@ | oid@H_301_42@ | @H_301_42@ | 行标识符(隐藏属性; 必须明确选择)@H_301_42@ |
opfmethod@H_301_42@ | oid@H_301_42@ | pg_am.oid@H_301_42@ | 操作符族使用的索引方法@H_301_42@ |
opfname@H_301_42@ | name@H_301_42@ | @H_301_42@ | 这个操作符族的名字@H_301_42@ |
opfnamespace@H_301_42@ | oid@H_301_42@ | pg_namespace.oid@H_301_42@ | 这个操作符的名字空间@H_301_42@ |
opfowner@H_301_42@ | oid@H_301_42@ | pg_authid.oid@H_301_42@ | 操作符族的所有者@H_301_42@ |
定义一个操作符族的大多数信息不在它的pg_opfamily行里面, 而是在相关的行pg_amop,pg_amproc和pg_opclass里。
----------------------------------------------------------------例:查询操作符族gist__int_ops2
postgres=# select oid,* from pg_opfamily where opfname = 'gist__int_ops2'; oid | opfmethod | opfname | opfnamespace | opfowner -------+-----------+----------------+--------------+---------- 32904 | 783 | gist__int_ops2 | 2200 | 10 (1 row)
创建新的操作符族的sql:
CREATE OPERATOR FAMILY--定义一个新操作符族
pg_opclass
http://58.58.27.50:8079/doc/html/9.3.1_zh/catalog-pg-opclass.html
----------------------------------------------------------------
47.32.pg_opclass
pg_opclass定义索引访问方法操作符类。 每个操作符类为一种特定数据类型和一种特定索引访问方法定义索引字段的语义。 一个操作符类本质上指定一个特定的操作符族适用于一个特定的可索引的字段数据类型。 索引的字段实际可用的族中的操作符集是接受字段的数据类型作为它们的左边的输入的那个。
操作符类在Section 35.14里有比较详细的描述。
Table 47-32.pg_opclass字段
名字 | 类型 | 引用 | 描述 |
---|---|---|---|
oid@H_301_42@ | oid@H_301_42@ | @H_301_42@ | 行标识符(隐藏属性;必须明确选择)@H_301_42@ |
opcmethod@H_301_42@ | oid@H_301_42@ | pg_am.oid@H_301_42@ | 操作符类所服务的索引访问方法@H_301_42@ |
opcname@H_301_42@ | name@H_301_42@ | @H_301_42@ | 这个操作符类的名字@H_301_42@ |
opcnamespace@H_301_42@ | oid@H_301_42@ | pg_namespace.oid@H_301_42@ | 这个操作符类的名字空间@H_301_42@ |
opcowner@H_301_42@ | oid@H_301_42@ | pg_authid.oid@H_301_42@ | 操作符类属主@H_301_42@ |
opcfamily@H_301_42@ | oid@H_301_42@ | pg_opfamily.oid@H_301_42@ | 包含该操作符类的操作符族@H_301_42@ |
opcintype@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 操作符类索引的数据类型@H_301_42@ |
opcdefault@H_301_42@ | bool@H_301_42@ | @H_301_42@ | 如果操作符类是opcintype的缺省,则为真@H_301_42@ |
opckeytype@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 索引数据的类型,如果和opcintype相同则为零@H_301_42@ |
一个操作符类的opcmethod必须匹配包含它的操作符族的opfmethod。 同样,对于任意给定的opcmethod和opcintype的组合, 不能有超过一个pg_opclass行有opcdefault为真。
----------------------------------------------------------------例:查询操作符族gist__int_ops2包含的操作符类
postgres=# select oid,* from pg_opclass where opcfamily=32904; oid | opcmethod | opcname | opcnamespace | opcowner | opcfamily | opcintype | opcdefault | opckeytype -------+-----------+----------------+--------------+----------+-----------+-----------+------------+------------ 32905 | 783 | gist__int_ops2 | 2200 | 10 | 32904 | 1007 | f | 0 (1 row)
CREATE OPERATOR CLASS--定义一个新操作符类
pg_amop
http://58.58.27.50:8079/doc/html/9.3.1_zh/catalog-pg-amop.html
----------------------------------------------------------------
47.4.pg_amop
pg_amop表存储有关和访问方法操作符族关联的信息。 如果一个操作符是一个操作符族中的成员,那么在这个表中会占据一行。 一个族成员是一个search操作符或一个ordering操作符。 一个操作符可以在多个族中出现,但是不能在一个族中的多个搜索位置或多个排序位置中出现。 (尽管不太可能,但这是允许的,一个操作符可以被搜索和排序目的使用。)
Table 47-4.pg_amop字段
名字 | 类型 | 引用 | 描述 |
---|---|---|---|
oid@H_301_42@ | oid@H_301_42@ | @H_301_42@ | 行标识符(隐藏属性;必须明确选择)@H_301_42@ |
amopfamily@H_301_42@ | oid@H_301_42@ | pg_opfamily.oid@H_301_42@ | 这个项的操作符族@H_301_42@ |
amoplefttype@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 操作符的左输入类型@H_301_42@ |
amoprighttype@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 操作符的右输入类型@H_301_42@ |
amopstrategy@H_301_42@ | int2@H_301_42@ | @H_301_42@ | 操作符策略数@H_301_42@ |
amoppurpose@H_301_42@ | char@H_301_42@ | @H_301_42@ | 操作符目的,s为搜索或o为排序@H_301_42@ |
amopopr@H_301_42@ | oid@H_301_42@ | pg_operator.oid@H_301_42@ | 该操作符的OID@H_301_42@ |
amopmethod@H_301_42@ | oid@H_301_42@ | pg_am.oid@H_301_42@ | 索引访问方式操作符族@H_301_42@ |
amopsortfamily@H_301_42@ | oid@H_301_42@ | pg_opfamily.oid@H_301_42@ | 如果是一个排序操作符,则为这个项排序所依据的btree操作符族; 如果是一个搜索操作符,则为0@H_301_42@ |
"搜索"操作符表明这个操作符族的一个索引可以被搜索,找到所有满足WHEREindexed_columnoperatorconstant的行。 显然,这样的操作符必须返回布尔值,并且它的左输入类型必须匹配索引的字段数据类型。
"排序"操作符表明这个操作符族的一个索引可以被扫描,返回以ORDER BYindexed_columnoperatorconstant顺序表示的行。这样的操作符可以返回任意可排序的数据类型,它的左输入类型也必须匹配索引的字段数据类型。ORDER BY的确切的语义是由amopsortfamily字段指定的, 该字段必须为操作符的返回类型引用一个btree操作符族。
Note:目前,假设排序操作符的排序顺序是被族缺省引用的,也就是ASC NULLS LAST。 这可以通过添加附加的行来明确声明排序选项来释放。
一个项的amopmethod必须匹配它包含的操作符族的opfmethod(包括amopmethod是故意违反性能原因的表结构的规范化)。同样,amoplefttype和amoprighttype必须匹配引用的pg_operator的oprleft和oprright。
----------------------------------------------------------------例: 查询操作符族gist__int_ops2 包含的所有 操作符
postgres=# select oid,(select oprname from pg_operator where oid=amopopr),* from pg_amop where amopfamily=32904; oid | oprname | amopfamily | amoplefttype | amoprighttype | amopstrategy | amoppurpose | amopopr | amopmethod | amopsortfamily -------+---------+------------+--------------+---------------+--------------+-------------+---------+------------+---------------- 32906 | && | 32904 | 1007 | 1007 | 3 | s | 32809 | 783 | 0 32908 | @> | 32904 | 1007 | 1007 | 7 | s | 32811 | 783 | 0 32909 | <@ | 32904 | 1007 | 1007 | 8 | s | 32810 | 783 | 0 32910 | @ | 32904 | 1007 | 1007 | 13 | s | 32813 | 783 | 0 32911 | ~ | 32904 | 1007 | 1007 | 14 | s | 32812 | 783 | 0 32912 | @@ | 32904 | 1007 | 32793 | 20 | s | 32801 | 783 | 0 32907 | = | 32904 | 2277 | 2277 | 6 | s | 1070 | 783 | 0 (7 rows)
pg_amproc
http://58.58.27.50:8079/doc/html/9.3.1_zh/catalog-pg-amproc.html
----------------------------------------------------------------
47.5.pg_amproc
pg_amproc存储有关与访问方法操作符族相关联的支持过程的信息。 每个属于某个操作符族的支持过程都占有一行。
Table 47-5.pg_amproc字段
名字 | 类型 | 引用 | 描述 |
---|---|---|---|
oid@H_301_42@ | oid@H_301_42@ | @H_301_42@ | 行标识符(隐藏属性; 必须明确选择)@H_301_42@ |
amprocfamily@H_301_42@ | oid@H_301_42@ | pg_opfamily.oid@H_301_42@ | 该项的操作符族@H_301_42@ |
amproclefttype@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 相关操作符的左输入数据类型@H_301_42@ |
amprocrighttype@H_301_42@ | oid@H_301_42@ | pg_type.oid@H_301_42@ | 相关操作符的右输入数据类型@H_301_42@ |
amprocnum@H_301_42@ | int2@H_301_42@ | @H_301_42@ | 支持过程编号@H_301_42@ |
amproc@H_301_42@ | regproc@H_301_42@ | pg_proc.oid@H_301_42@ | 过程的 OID@H_301_42@ |
amproclefttype和amprocrighttype字段的习惯解释, 他们标识一个特定支持过程支持的操作符的左和右输入类型。对于某些访问方式, 他们匹配支持过程本身的输入数据类型,对其他的则不这样。有一个对索引的"缺省"支持过程的概念,amproclefttype和amprocrighttype都等于索引操作符类的opcintype。
----------------------------------------------------------------例: 查询操作符族gist__int_ops2 包含的所有支持函数
postgres=# select oid,* from pg_amproc where amprocfamily=32904; oid | amprocfamily | amproclefttype | amprocrighttype | amprocnum | amproc -------+--------------+----------------+-----------------+-----------+------------------ 32913 | 32904 | 1007 | 1007 | 1 | g_int_consistent 32914 | 32904 | 1007 | 1007 | 2 | g_int_union 32915 | 32904 | 1007 | 1007 | 3 | g_int_compress 32916 | 32904 | 1007 | 1007 | 4 | g_int_decompress 32917 | 32904 | 1007 | 1007 | 5 | g_int_penalty 32918 | 32904 | 1007 | 1007 | 6 | g_int_picksplit 32919 | 32904 | 1007 | 1007 | 7 | g_int_same (7 rows
4. 参考
http://58.58.27.50:8079/doc/html/9.3.1_zh/xindex.htmlhttp://blog.chinaunix.net/uid-20726500-id-4884626.html
http://58.58.27.50:8079/doc/html/9.3.1_zh/catalogs.html
原文链接:https://www.f2er.com/postgresql/194882.html