重庆思庄Oracle、KingBase、PostgreSQL、Redhat认证学习论坛

标题: 深入解析 PostgreSQL 约束底层 [打印本页]

作者: mahan    时间: 2026-1-4 20:01
标题: 深入解析 PostgreSQL 约束底层
什么是约束
在定义表或列时,可以为数据附加校验或强制规则的,这些规则称为约束。

数据类型本身只能提供较粗粒度的限制,例如 numeric 无法限定只能为正数。更具体的规则(如唯一性、取值范围等)需要通过约束来实现。

约束用于保障数据完整性。当插入或默认值违反约束时,PostgreSQL 会直接报错。

本质上,约束是数据库层面强制执行的数据规则。一旦缺失或使用不当,数据问题往往会悄然积累,并最终演变为难以排查的缺陷。

pg_constraint 系统目录
从内部实现来看,PostgreSQL 中的所有约束,都会以记录的形式存储在 pg_constraint 系统目录中。

🗄️ 什么是系统目录(Catalog)

系统目录是 PostgreSQL 用来保存元数据的系统表。用户表存储业务数据,而系统目录则记录“数据库自身的信息”,例如表、列、索引、约束等。

除 pg_constraint 之外,常见的系统目录还包括:

pg_class:所有关系对象(表、索引、视图等)
pg_attribute:表的列信息
pg_type:数据类型(含域和自定义类型)
pg_namespace:模式(schema)
pg_index:索引相关信息(其余信息主要在 pg_class 中)
pg_proc:函数、过程及聚合函数
这些表都位于 pg_catalog 模式中,该模式在 search_path 中默认优先,因此通常无需显式指定。

pg_constraint 用于存储表上的 CHECK、NOT NULL、主键、唯一、外键和排他约束。

需要注意的是,在 PostgreSQL 18 之前,表上的 NOT NULL 约束并不存储在 pg_constraint 中,而是记录在 pg_attribute;从 PostgreSQL 18 开始,NOT NULL 才在 pg_constraint 中拥有独立记录。

PostgreSQL 17:

pg_constraint 目录用于存储 CHECK、主键、唯一、外键、排他约束,以及定义在域上的 NOT NULL 约束。

表上的 NOT NULL 约束仍然记录在 pg_attribute 中,而非 pg_constraint。

因此,每一个约束都会在 pg_constraint 中以一条记录存在,并通过 contype 字段标识约束类型。后文将对这些类型逐一说明,其中也包括一个较为特殊的类型:t。

91477695a56755d36a.png
登录/注册后可看大图