文档章节

PostgreSQL的pg_depend详解

kenyon_君羊
 kenyon_君羊
发布于 2014/04/25 18:49
字数 1016
阅读 1.9K
收藏 0

「深度学习福利」大神带你进阶工程师,立即查看>>>

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,conname,connamespace,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 TABLE
3.要说一点的是不要去手工删除一些系统表信息来达到删除约束的目的,容易因删不干净而造成各种异常

参考:
http://wiki.postgresql.org/wiki/Pg_depend_display
kenyon_君羊
粉丝 506
博文 174
码字总数 125895
作品 0
杭州
其他
私信 提问
加载中
此博客有 2 条评论,请先登录后再查看。
基于ExMobi的外卖系统全端开发实践

如今O2O模式已经进入高速发展阶段,这种模式带给人们的方便快捷不仅催生了各种团购业务,更使订餐、外卖这种传统行业得到了新生。 这不禁让笔者也蠢蠢欲动,尤其是现在企业内部很多时候为了方...

nandy007
2015/12/14
1.6K
11
[用事实说明两个凡是]一个由mysql事务隔离级别造成的问题分析

背景 最近要做一个批跑服务, 基本逻辑就是定时扫描数据库的记录, 有满足条件的就进行处理(一条记录代表一个任务,以下任务与记录含义相同). 要求支持多机部署批跑服务. 批跑支持多机部署实现方...

周翼翼
2015/11/24
3.8K
44
NSQ系列之nsqlookupd代码分析三(详解tcpServer 中的IOLoop方法)

NSQ系列之nsqlookupd代码分析三(详解nsqlookupd tcpServer 中的IOLoop) 上一章我们大致了解了中的的大致的代码,与client也就之间协议处理在这个方法中,今天我们就分析一下这个方法 废话不...

大蓝妹
2015/09/01
736
1
ireport4.0.2父子报表详解

开发步骤: 1、新建一个父报表parent_report 在ireport designer左上角工具栏中点击“文件”,下拉列表中选择“New...",弹出如下对话框: 默认选择"Blank A4",点击“Launch Report Wizard”...

取经和尚
2014/11/18
792
0
PostgreSQL备份加密方法

本文加密方式是在利用pg_dump备份出文件后直接利用openssl进行文件加密。 1、生产密钥: 利用各种参数进行建立公私密钥,这里利用输入参数作为密钥生成的一部分,其他的可以手动添加,脚本如...

PGSmith
2016/03/28
867
1

没有更多内容

加载失败,请刷新页面

加载更多

wasm cpp 传值

简单传递基础值 #include <emscripten.h>extern "C"{ int fib(int n);}int fib(int n){ return n < 2 ? n : fib(n - 1) + fib(n - 2);}int main(int argc, char......

阿豪boy
14分钟前
9
0
全球产业数字化转型趋势及方向研判

中国电子学会研究咨询中心主任、中国数字经济百人会秘书长李颋发布由中国数字经济百人会依托中国电子学会专业研究团队编制的《全球产业数字化转型趋势及方向研判》。该报告结合国内外领军企业...

Idea
15分钟前
0
0
再谈测试浮躁论——深度好文!

目前来说软件测试人员都有这么些问题吧,这大概已经成为中国目前测试的瓶颈了。人心浮躁大概不是某些职业人特有的,其实是我们这些年轻人的通病了。但身为测试人员,当你在应聘找工作的时候是...

程序员一凡
23分钟前
10
0
Spring Boot 教程 - 文件上传下载

在日常的开发工作中,基本上每个项目都会有各种文件的上传和下载,大多数文件都是excel文件,操作excel的JavaAPI我用的是apache的POI进行操作的,POI我之后会专门讲到。此次我们不讲如何操作...

Butterfly-Tri
今天
27
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部