Chapter 3. 系统表

概述

系统表是关系型数据库存放结构元数据的地方, 比如表和字段,以及内部登记信息等. PostgreSQL 的系统表就是普通表. 你可以删除然后重建这些表,增加列,插入和更新数值, 然后彻底把你的系统搞垮. 通常我们从来不需要手工修改系统表,通常总有 SQL 命令可以做这些事情. (比如,CREATE DATABASEpg_database 表插入一行 -- 并且实际上 在磁盘上创建该数据库.) 有几种神秘的操作例外,比如增加访问方法.

Table 3-1. 系统表

表名字表用途
pg_aggregate聚集函数
pg_am索引访问方法
pg_amop访问方法操作符
pg_amproc访问方法支持过程
pg_attrdef字段缺省值
pg_attribute表的列(属性,字段)
pg_class表,索引,序列(“关系”)
pg_database数据库
pg_description数据库对象的描述或注释
pg_group用户组
pg_index附加的索引信息
pg_inheritproc(未使用)
pg_inherits表继承分级
pg_ipl(未使用)
pg_language用于写函数的语言
pg_largeobject大对象
pg_listener异步通知
pg_opclass索引访问方法操作符表
pg_operator操作符
pg_proc函数和过程
pg_relcheck检查约束
pg_rewrite查询重写规则
pg_shadow数据库用户
pg_statistic优化器统计
pg_trigger触发器
pg_type数据类型

大多数表更详细的信息在下面. 与索引访问方式有关的表在 程序员手册 里解释. 有些表还没有任何文档.

pg_aggregate

pg_aggregate 存储与聚集函数有关的信息. 聚集函数是对一个数值集(通常每行一个匹配查询条件的字段) 进行操作的函数,它返回从这些值中计算出的一个数值. 典型的聚集函数是 sumcount,和 max

Table 3-2. pg_aggregate 字段

名字类型引用描述
aggnamename 聚集函数的名字
aggownerint4pg_shadow.usesysid聚集函数的所有者(创建者)
aggtransfnregproc (function) 转换函数
aggfinalfnregproc (function) 终处理函数
aggbasetypeoidpg_type.oid从SQL里调用的时候此函数操作的类型
aggtranstypeoidpg_type.oid此聚集函数的内部转换(状态)数据的类型
aggfinaltypeoidpg_type.oid结果类型
agginitvaltext  转换状态的初始值.这是一个文本数据域,它将转换为 aggtranstype 的类型.

新聚集函数是用 CREATE AGGREGATE 命令注册的. 参阅程序员手册获取关于写聚集函数 以及转换函数的含义等的更多信息.

聚集函数是通过名字参数类型标识的. 因此 aggname 和 aggname 是组合主键.

pg_attrdef

这个表存储字段缺省值.字段的主要信息存放在 pg_attribute (见下文).只有明确声明一个缺省值(该表何时创建或字段何时增加) 的字段在这里有元组.

Table 3-3. pg_attrdef 字段

名字类型引用描述
adrelidoidpg_class.oid这个字段所属的表
adnumint2  字段数目;参阅 pg_attribute.pg_attnum
adbintext 字段缺省值的内部表现形式
adsrctext 人类可读的缺省值的内部表现形式

pg_attribute

pg_attribute 存储关于表的字段的信息.数据库里每个表的每个字段都在 pg_attribute 里有一行. (还有用于索引和其它对象的属性元组,见 pg_class.)

术语 属性 等效于 列/字段,使用它是历史原因.

Table 3-4. pg_attribute 字段

名字类型引用描述
attrelidoidpg_class.oid此列/字段所属的表
attnamename 字段名字
atttypidoidpg_type.oid这个字段的数据类型
attdispersionfloat4  attdispersion 是该字段的离散统计(0.0到1.0), 或者为零,如果统计信息还未计算,或者 -1.0 -- 如果 VACUUM 发现该字段没有重复的元组(这种情况下 离散性应该是 1.0/numberOfRows 代表的当前表尺寸). -1.0 的设计非常有用,因为行数可能比 attdispersion 更新得更频繁. 我们假设该行将返回它的非重复元组属性.
attlenint2  是本字段类型 pg_type.typlen 的拷贝.
attnumint2  字段数目.普通列是从 1 开始计数的.系统字段, 比如 oid, 有(任意)正数.
attnelemsint4 如果该字段是数组,那么是维数
attcacheoffint4  在磁盘上总是 -1,但是如果装载入内存中的元组描述器中, 它可能会更新,缓冲在元组中字段的偏移量.
atttypmodint4  atttypmod 元组在创建表的时候 提供的类型相关的数据(比如,一个 varchar 字段的最大长度). 它传递给类型相关的输入和输出函数当做第三个参数. 其值对那些不需要 typmod 的类型而言通常为 -1.
attbyvalbool  这个字段的类型的 pg_type.typbyval 的拷贝
attstoragechar  这个字段的类型的 pg_type.typstorage 的拷贝
attissetbool  如果为真,这个字段是一个结果集.这种情况下,在该字段真正存储的是 在 pg_proc 表里的一条元组的 OID. pg_proc 那条元组包含定义这个结果集的查询字串. - 也就是说,那条能够返回这个结果集的查询. 所以 atttypid (见上面) 指向这个查询返回的类型,但是这个字段的实际长度是一个 oid 的长度(尺存).--- 至少理论如此. 不过这些东西现在可能已经相当残破了.
attalignchar  这个字段的类型的 pg_type.typalign 的拷贝
attnotnullbool  这代表一个 NOT NULL 约束.我们可以改变这个字段以打开或者关闭这个约束.
atthasdefbool  这个字段有一个缺省值,此时它对应 pg_attrdef 表里实际定义此值的元组.

pg_class

pg_class 记载表和几乎所有有 字段或者是那些类似表的东西.包括索引(不过还要参阅 pg_index),序列,视图和一些特殊关系类型. 在下面,当我们指所有这些对象的时候我们说 “relations”. 不是所有字段对所有关系类型都有意义.

Table 3-5. pg_class 字段

名字类型引用描述
relnamename 表,索引,视图等的名字.
reltypeoidpg_type.oid 对应这个表的数据类型(没有用,只是为系统表设置)
relownerint4pg_shadow.usesysid关系所有者
relamoidpg_am.oid如果元组是索引,那么就是所用的访问模式(btree,hash,等等)
relfilenodeoid 这个关系在磁盘上的文件的名字
relpagesint4  以页(大小为BLCKSZ)的此表在磁盘上的形式的大小. 它只是一个近似值,在 vacuum 的时候计算.
reltuplesint4  表中元组的数目.只是规划器使用的一个估计值,由 VACUUM 更新.
reltoastrelidoidpg_class.oid 与此表关联的TOAST表的OID,如果没有为0. TOAST 表在一个从属表里“离线”存储大字段.
reltoastidxidoidpg_class.oid此表对应的在TOAST表上的索引的Oid,如果没有则为0Oid of the index on the TOAST table for this table, 0 if none
relhasindexbool 如果它是一个表而且至少有一个索引,则为真
relissharedbool XXX(看上去不象应该是的东西)
relkindchar  'r' = 普通表,'i' = 索引,'S' = 序列,'v' = 视图, 's' = 特殊,'t' = 从属TOAST表
relnattsint2  关系中字段数目,除了系统字段以外. 在 pg_attribute 里肯定有许多对应元组. 又见 pg_attribute.attnum.
relchecksint2  表里的检查约束的数目;参阅 pg_relcheck
reltriggersint2  表里的触发器的数目;参阅 pg_trigger
relukeysint2 未用 (不是唯一键字或者其它什么东西的数目)
relfkeysint2 表中外键的数目
relhaspkeybool  未用(不,它不是说这个表是否有一个主键.它真的没有用.)
relhasrulesbool 表有规则
relhassubclassbool 至少有一个表继承这个表
relaclaclitem[]  访问权限.参阅 GRANTREVOKE 的描述获取详细信息.

pg_database

pg_database 表存储关于可用数据库的信息. pg_database 在所有数据库集群之间共享. 数据库是用 CREATE DATABASE创建的. 参考管理员手册获取一些参数的详细含义.

Table 3-6. pg_database 字段

名字类型引用描述
datnamename 数据库名字
datdbaint4pg_shadow.usesysid数据库所有人,初始值为创建者
encodingint4 数据库的字符/多字节编码方式
datistemplatebool  如果为真则此数据库可以用于CREATE DATABASE “TEMPLATE”子句,把新数据库创建为此数据库的克隆.
datallowconnbool  如果为假则没有人可以联接到这个数据库.这个字段用于保护 template0 数据库不被更改.
datlastsysoidoid  数据库创建之后存在的最后一个 oid; 对 pg_dump 特别有用
datpathtext  如果该数据库存放在另外一个位置,那么这个字段记录该位置. 它要么是一个环境变量名要么是一个绝对路径,取决于它是如何输入的.

pg_description

pg_description 表可以给每个数据库对象存储一个可选的描述或者 注释.你可以用 COMMENT 命令操作这些描述. 客户端应用可以通过连接这个表查看描述.许多内建的系统对象都有 与之相关的注释,可以用psql\d命令显示.

Table 3-7. pg_description 字段

名字类型引用描述
objoidoid任意 oid 属性这条描述所描述的对象的 oid
descriptiontext 作为对该对象的描述的任意文本

pg_group

这个表定义组以及哪些用户属于哪个组的信息. 组是用 CREATE GROUP 命令创建的. 请参考管理员手册获取关于用户权限管理的信息.

Table 3-8. pg_group 字段

名字类型引用描述
gronamename 组名字
grosysidint4 标识这个组的任意数字
grolistint4[]pg_shadow.usesysid一个包含该组中用户 id 的数组

pg_index

pg_index包含关于索引的一部分信息. 其他的信息大多数在 pg_class

Table 3-9. pg_index 字段

名字类型引用描述
indexrelidoidpg_class.oid这个索引在 pg_class 里的元组的 oid
indrelidoidpg_class.oid使用这个索引的表在 pg_class 里的元组的 oid
indprocoidpg_proc.oid如果这是函数索引那么这是那个已注册的过程的 oid
indkeyint2vectorpg_attribute.attnum 这是一个向量(数组),最多有 INDEX_MAX_KEYS 个值,指向该索引应用的表字段. 比如一个值为 1 3 的向量意味着第一个字段和第三个字段组成 这个索引键字.
indclassoidvectorpg_opclass.oid 对于索引键字里面的每个字段,这个字段都包含一个指向所使用的 “操作符表”的引用,参阅 pg_opclass 获取细节.
indisclusteredbool 未用
indislossybool ???
indisuniquebool 如果为真,这是个唯一索引
indisprimarybool 如果为真,该索引是作为对应表的主键的唯一索引.
indreferenceoid 未用
indpredtext 部分索引做预计用的查询规划(不能工作)

pg_inherits

这个表元组关于表继承级别的信息.

Table 3-10. pg_inherits 字段

名字类型引用描述
inhrelidoidpg_class.oid 这个字段是指向子表的引用,也就是,它元组的是这里指出的表是 从其他表继承下来的情况.
inhparentoidpg_class.oid 这里是指向父表的引用,也就是 inhrelid 从哪个表继承的. 这里是指向那个表的引用.
inhseqnoint4  如果存在多于一个子表/父表对(多重继承), 这个数字表明此继承字段的排列顺序.记数从 1 开始.

pg_language

pg_language 登记了所有调用接口或语言, 你可以用这些语言或接口写函数或者存储过程. 参阅 CREATE LANGUAGE程序员手册获取更多关于语言句柄的信息.

Table 3-11. pg_language 字段

名字类型引用描述
lannamename 语言的名字(创建一个函数的时候需要声明)
lanisplbool  对于内部语言而言是假(比如SQL),对于动态装载的语言句柄模块是真. 它实际上意味着,如果为真,则该语言可以删除.
lanpltrustedbool  这是可信语言.参阅 CREATE LANGUAGE 获取其含义.如果这是一种内部语言 (lanispl 为假)那么该字段没有意义.
lanplcallfoidoidpg_proc.oid 对于非内部语言,这是指向该语言句柄的引用,语言句柄是一个特殊函数, 负责执行以某种语言写的所有函数.
lancompilertext 没有用

pg_operator

参阅CREATE OPERATOR程序员手册获取这些操作符参数的细节.

Table 3-12. pg_operator 字段

名字类型引用描述
oprnamename 操作符名字
oprownerint4pg_shadow.usesysid操作符所有者(创建者)
oprprecint2 未用
oprkindchar  'b' = 中缀 (“两边”), 'l' = 前缀 (“左边”), 'r' = 后缀 (“右边”)
oprisleftbool 未用
oprcanhashbool 这个操作符支持散列连接
oprleftoidpg_type.oid左操作数的类型
oprrightoidpg_type.oid右操作数的类型
oprresultoidpg_type.oid结果类型
oprcomoidpg_operator.oid如果存在的话,此操作符的交换符
oprnegateoidpg_operator.oid如果存在的话,此操作符的反转器
oprlsortopoidpg_operator.oid 如果此操作符支持融合连接,这里是对左手边操作数排序的操作符
oprrsortopoidpg_operator.oid 如果此操作符支持融合连接,这里是对右手边操作数排序的操作符
oprcoderegproc 实现这个操作符的函数
oprrestregproc 此操作符的约束选择性计算函数
oprjoinregproc 此操作符的连接选择性计算函数

pg_proc

这个表存储关于函数(或过程)的信息. CREATE FUNCTION程序员手册 包含一些域的更多信息.

Table 3-13. pg_proc 字段

名字类型引用描述
pronamename 函数名字
proownerint4pg_shadow.usesysid函数所有者(创建者)
prolangoidpg_language.oid这个函数的实现语言或调用接口
proisinhbool 未用
proistrustedbool 不能工作
proiscachablebool 函数对相同输入返回相同结果
proisstrictbool  如果任何调用参数是空,那么函数返回空.这时函数实际上连调用都不调用. 不是“strict”的函数必须准备处理空输入.
pronargsint2 参数数目
proretsetbool 函数返回结果集(可能不能工作)
prorettypeoidpg_type.oid返回值的数据类型(如果函数不返回值则为0)
proargtypesoidvectorpg_type.oid带数据类型的函数参数的向量
probyte_pctint4 死代码
properbyte_pctint4 死代码
propercall_pctint4 死代码
prooutin_ratioint4 死代码
prosrctext  这个字段告诉函数句柄如何调用该函数.它实际上对于解释语言来说就是 函数的源程序,或者一个链接符号,一个文件名,或者是任何其他的东西, 取决于语言/调用习惯的实现.
probinbytea ?

pg_relcheck

这个系统表存储各表中的 CHECK 约束.(字段/列约束并没有受到特殊对待 每个列约束都等效于某些表约束.) 参阅 CREATE TABLE 获取更多信息.

Table 3-14. pg_relcheck 字段

名字类型引用描述
rcrelidoidpg_class.oid这个检查约束所在表
rcnamename 约束名
rcbintext 该约束表达式的内部形式
rcsrctext 该约束表达式的人类可读形式

注意: pg_class.relchecks 需要与此表的元组相匹配.

pg_shadow

pg_shadow 包含关于数据库用户的信息. 名字源于此表不应为所有人可读,因为它包含口令. pg_userpg_shadow 把口令域填成空白的视图.

管理员手册包含关于用户和权限管理的详细信息.

Table 3-15. pg_shadow 字段

名字类型引用描述
usenamename 用户名
usesysidint4 用户 id(用于引用这个用户的任意数字)
usecreatedbbool 用户可以创建数据库
usetracebool 未用
usesuperbool 用户是超级用户
usecatupdbool  用户可以更新系统表.(除非这个属性为真, 否则超级用户也不能这么干.)
passwdtext 口令
valuntilabstime 帐户截止日期(只用于口令认证)

pg_type

Table 3-16. pg_type 字段

名字类型引用描述
typnamename 数据类型名字
typownerint4pg_shadow.usesysid该类型的所有人(创建人)
typlenint2 该类型存储形式的长度,如果是变长为 -1
typprtlenint2 未用
typbyvalbool  typbyval 判断内部过程传递这个类型的数值时 是通过传值还是传引用. 只有 charshort,和 int 或相当的项目可以传值,所以如果该类型不是 1,2,4字节长, Postgres 不会有传值的选择,因此 typbyval 最好是假. 变长类似总是传引用.请注意即使长度可以传值, typbyval 也可以为假; 比如,现在 float4就是如此.
typtypechar  typtype对于基础类型 是 b,对于表类型是 c (也就是说,一个表). 如果 typtypec,那么 typrelid 是该类型在 pg_class 里的元组的 OID.
typisdefinedbool ???
typdelimchar 当分析数组输入时,分隔两个此类型数值的字符
typrelidoidpg_class.oid 如果是表类型(见 typtype) 那么这个字段指向 pg_class 中定义该表的元组. 表在理论上应该用做复合数据类型,不过现在不是完全都能工作.
typelemoidpg_type.oid 如果 typelem 不为 0, 那么它标识 pg_type 里面的另外一行. 当前类型可以当做一个产生类型为 typelem 的数组来描述.一个非零的 typelem 并不保证这个类型是一个“真正的”数组类型; 有些普通的定长类型也可以转换(比如,oidvector). 变长类型不能转成这样的伪数组. 因此,判断一个类型是否“真”数组类型的做法是 typelem !=0 并且 typlen < 0.
typinputregproc 输入函数
typoutputregproc 输出函数
typreceiveregproc 未用
typsendregproc 未用
typalignchar 

typalign 是当存储此类型的数值是要求的对齐性质.它应用于磁盘存储以及 该值在 Postgres 内部的大多数形式. 如果数值是连续存放的,比如在磁盘上以完全的裸数据的形式存放时, 那么先在此类型的数据前填充空白,这样它就可以按照要求的界限存储. 对齐引用是该序列中第一个数据的开头.

可能的值有:

  • 'c' = CHAR 对齐,也就是不需要对齐.

  • 's' = SHORT 对齐 (在大多数机器上是 2字节)

  • 'i' = INT 对齐 (在大多数机器上是 4 字节)

  • 'd' = DOUBLE 对齐 (在大多数机器上是 8 字节,但不一定是全部)

Note: 对于在系统表里使用的类型,在 pg_type 里定义的尺寸和对齐必须和编译器在一个表示表的一行的结构里 的布局一样.

typstoragechar 

typstorage 告诉一个变长类型(那些有 typlen = -1的) 说该类型是否准备 toast,以及对这种属性的类型 的缺省策略是什么. 可能的值有

  • 'p': 数值必须总是以平面方式存储

  • 'e': 数值可以存储在一个“从属” 关系中(如果该关系有这么一个,参阅 pg_class.reltoastrelid).

  • 'm': 数值可以以内联的压缩方式存储

  • 'x': 数值可以以内联的压缩方式或者在“从属”表里存储.

请注意 'm' 域也可以移到从属表里存储,但只是最后的解决方法 ('e' 和 'x' 域先移走).

typdefaulttext ???