PostgreSQL的pg_depend详解
发布时间:2020-12-13 17:29:40 所属栏目:百科 来源:网络整理
导读:pg_depend是postgres的一张系统表,用来记录数据库对象之间的依赖关系,除了常见的主外键,还有其他一些内部依赖关系,可以通过这个系统表呈现出来。 一、表结构: postgres=# d+ pg_depend Table "pg_catalog.pg_depend" Column | Type | Modifiers | Stora
pg_depend是postgres的一张系统表,用来记录数据库对象之间的依赖关系,除了常见的主外键,还有其他一些内部依赖关系,可以通过这个系统表呈现出来。
一、表结构: postgres=# d+ pg_depend Table "pg_catalog.pg_depend" Column | Type | Modifiers | Storage | Stats target | Description -------------+---------+-----------+---------+--------------+------------- classid | oid | not null | plain | | 系统OID objid | oid | not null | plain | | 对象OID objsubid | integer | not null | plain | | refclassid | oid | not null | plain | | 引用系统OID refobjid | oid | not null | plain | | 引用对象ID refobjsubid | integer | not null | plain | | deptype | "char" | not null | plain | | pg_depend类型 Indexes: "pg_depend_depender_index" btree (classid,objid,objsubid) "pg_depend_reference_index" btree (refclassid,refobjid,refobjsubid) Has OIDs: no --BTW:OID是Object Identifier的缩写,是对象ID的意思,因为是无符号的4字节类型,不够足够大,所以一般不用来做主键使用,仅系统内部,比如系统表等应用,可以与一些整型数字进行转换。与之相关的系统参数是default_with_oids,默认是off pg_depend.deptype字段类型9.1之后多了一个extension的类型,目前类型有 DEPENDENCY_NORMAL (n) :普通的依赖对象,如表与schema的关系 DEPENDENCY_AUTO (a) :自动的依赖对象,如主键约束 DEPENDENCY_INTERNAL (i) :内部的依赖对象,通常是对象本身 DEPENDENCY_EXTENSION (e) :9.1新增的的扩展依赖 DEPENDENCY_PIN (p) :系统内置的依赖 二、例子 wiki上有一个SQL可以列出系统和用户对象的各种依赖关系,低版本的可以看wiki上的另一个写法 SELECT classid::regclass AS "depender object class",CASE classid WHEN 'pg_class'::regclass THEN objid::regclass::text WHEN 'pg_type'::regclass THEN objid::regtype::text WHEN 'pg_proc'::regclass THEN objid::regprocedure::text ELSE objid::text END AS "depender object identity",objsubid,refclassid::regclass AS "referenced object class",CASE refclassid WHEN 'pg_class'::regclass THEN refobjid::regclass::text WHEN 'pg_type'::regclass THEN refobjid::regtype::text WHEN 'pg_proc'::regclass THEN refobjid::regprocedure::text ELSE refobjid::text END AS "referenced object identity",refobjsubid,CASE deptype WHEN 'p' THEN 'pinned' WHEN 'i' THEN 'internal' WHEN 'a' THEN 'automatic' WHEN 'n' THEN 'normal' END AS "dependency type" FROM pg_catalog.pg_depend WHERE (objid >= 16384 OR refobjid >= 16384); BTW:我通常喜欢在where后面加个条件 and deptype <>'i' 排除internal依赖建一张普通的表,执行上面的SQL postgres=# create table tbl_parent(id int); CREATE TABLE postgres=# 执行上面的SQL; depender object class | depender object identity | objsubid | referenced object class | referenced object identity | refobjsubid | dependency type -----------------------+--------------------------+----------+-------------------------+------------- pg_class | tbl_parent | 0 | pg_namespace | 2200 | 0 | normal (1 row) --普通用户来看只是建了个表,但是没有约束,其实因为这个表是建立在schema下面,表是依赖于schema上面的加一个主键约束 postgres=# alter table tbl_parent add primary key(id); ALTER TABLE depender object class | depender object identity | objsubid | referenced object class | referenced object identity | refobjsubid | dependency type -----------------------+--------------------------+----------+-------------------------+------- pg_class | tbl_parent | 0 | pg_namespace | 2200 | 0 | normal pg_constraint | 16469 | 0 | pg_class | tbl_parent | 1 | automatic (2 rows) --多了一个约束的信息,下面的这条信息表明这个主键约束是依赖于表上的,并且是自动模式,详细信息可以在系统表pg_constrant里面查询三、非正常删除 正常情况下用户删除有依赖关系的对象时会提示需要先删除最里层没依赖的对象,但是如果通过删除系统表,但又删得不对,就会导致异常,比如上面这个例子会出现 cache lookup failed for constraint postgres=# select oid,conname,connamespace,contype from pg_constraint where conname like 'tbl_parent%'; oid | conname | connamespace | contype -------+-----------------+--------------+--------- 16469 | tbl_parent_pkey | 2200 | p (1 row) postgres=# delete from pg_constraint where conname like 'tbl_parent%'; DELETE 1 postgres=# select oid,contype from pg_constraint where conname like 'tbl_parent%'; oid | conname | connamespace | contype -----+---------+--------------+--------- (0 rows) postgres=# drop table tbl_parent; ERROR: cache lookup failed for constraint 16469 --16496是约束的OID postgres=# --出现这个问题,是因为手工把约束对象删除了,但是在pg_depend依赖关系里面却仍然存在关系,所以删除该表时发现最里层的依赖对象找不到了就报错了,解决: 1.手工恢复该表的约束对象,比较难也比较烦 2.删除该表所有的系统依赖信息 上面的问题需要删除 postgres=# delete from pg_depend where objid = 16469 or refobjid = 16469 ; DELETE 2 postgres=# drop table tbl_parent; DROP TABLE3.要说一点的是不要去手工删除一些系统表信息来达到删除约束的目的,容易因删不干净而造成各种异常 参考: http://wiki.postgresql.org/wiki/Pg_depend_display (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |