主键唯一外键不继承,继承检查约束? 非空继承吗
时间: 2025-06-03 10:48:41 浏览: 11
<think>好的,用户现在问的是PostgreSQL表继承中不同约束的继承行为,包括主键、唯一、外键、检查约束和非空约束是否会被继承。我需要根据之前的回答和提供的引用内容来详细解答。
首先,回顾之前的回答,用户已经知道检查约束会被继承,而主键和唯一约束不会自动继承,外键同样需要显式定义。但这次用户还提到了非空约束,之前的回答可能没有涵盖这一点,所以需要补充。
接下来,我需要检查提供的引用内容。引用[1]提到添加新父表时,子表必须包含所有字段且类型一致,父表的每个约束的名字和表达式都必须包含在子表中。这可能涉及检查约束和非空约束。引用[3]中的例子显示子表leader继承了父表human的列,但没有提到约束,所以可能需要进一步确认非空约束的继承情况。
现在,需要分别分析每种约束类型:
1. **主键约束(PRIMARY KEY)**:根据之前的回答,主键不会继承,因为数据存储在不同物理表,无法保证跨表唯一性。引用中没有直接提到主键,但用户之前的回答已经确认这点。
2. **唯一约束(UNIQUE)**:同样不会自动继承,理由同主键。需要每个子表单独声明。
3. **外键约束(FOREIGN KEY)**:父表的外键不会传递到子表,子表需要显式定义。引用中没有直接说明,但根据之前的逻辑,外键属于表级别的约束,不自动继承。
4. **检查约束(CHECK)**:自动继承,且子表可以添加自己的检查约束。引用[1]和之前的回答都支持这一点。
5. **非空约束(NOT NULL)**:之前没有提到,需要确认。根据PostgreSQL文档,非空约束属于列约束,在表继承中,子表会继承父表的列定义,包括非空约束。例如,如果父表的列有NOT NULL,子表的对应列也会自动带有该约束,除非子表显式覆盖。但需要验证这一点是否正确,可能需要查阅文档或测试。
此外,引用[3]的例子中,子表leader继承了父表human的列,但未明确显示是否有非空约束。如果父表的某个列有NOT NULL,子表是否必须包含该列且同样非空?根据引用[1],当添加新父表时,子表必须包含所有字段且类型一致,这可能包括非空约束,但需要进一步确认。
总结各约束的继承情况:
- 检查约束:自动继承
- 非空约束:自动继承
- 主键、唯一、外键:不自动继承,需显式声明
需要确保回答中明确区分每种约束的行为,并引用提供的参考资料。例如,引用[1]提到子表必须包含父表的约束,这可能适用于检查和非空约束,而主键等则不会自动处理。
最后,用户可能需要知道如何验证这些约束是否被继承,例如通过查询系统表pg_constraint,或者使用\d命令查看表结构。可以在回答中建议这些方法,帮助用户实际操作。</think>根据PostgreSQL的继承机制,不同约束的继承行为存在显著差异。以下是各类型约束的具体继承规则:
### 一、自动继承的约束类型
1. **检查约束(CHECK)**
父表定义的检查约束会自动继承到所有子表,且支持**约束叠加**。例如父表定义:
```sql
CREATE TABLE human (
hid int CHECK (hid > 0), -- 检查约束
name varchar(20)
);
```
子表`leader`将自动继承`hid > 0`的约束[^1]
2. **非空约束(NOT NULL)**
非空约束作为**列级约束**会被继承:
```sql
CREATE TABLE parent (
id int NOT NULL -- 非空约束
);
```
子表字段`id`会自动继承`NOT NULL`特性[^3]
### 二、不继承的约束类型
1. **主键(PRIMARY KEY)**
父表主键不会自动继承到子表。若子表需要主键,必须显式声明:
```sql
CREATE TABLE child (
LIKE parent INCLUDING CONSTRAINTS,
PRIMARY KEY (id) -- 显式声明主键
) INHERITS (parent);
```
2. **唯一约束(UNIQUE)**
唯一性约束**不跨表生效**,需在子表单独声明:
```sql
CREATE TABLE child (
ADD UNIQUE (email) -- 子表单独声明
) INHERITS (parent);
```
3. **外键(FOREIGN KEY)**
父表的外键关系**不会自动传递**,子表需要独立建立关联:
```sql
CREATE TABLE orders (
customer_id int REFERENCES customers(id) -- 子表显式定义外键
) INHERITS (transactions);
```
### 三、约束继承验证方法
1. 通过`\d+ 表名`查看完整约束:
```sql
\d+ leader -- 显示继承表的约束详情[^3]
```
2. 查询系统目录表:
```sql
SELECT conname, conrelid::regclass
FROM pg_constraint
WHERE confrelid = 'human'::regclass; -- 查询继承体系的约束[^1]
```
### 四、特殊场景处理
当使用`ALTER TABLE ... INHERIT`动态添加父表时,必须满足:
1. 子表已包含父表的所有字段(含约束)
2. 字段类型完全一致
3. 父表的每个约束名称和表达式都已存在于子表[^1]
$$
\begin{array}{|c|c|c|}
\hline
\text{约束类型} & \text{是否继承} & \text{强制要求} \\
\hline
主键(PRIMARY KEY) & × & \text{需显式声明} \\
唯一约束(UNIQUE) & × & \text{需显式声明} \\
外键(FOREIGN KEY) & × & \text{需显式声明} \\
检查约束(CHECK) & √ & \text{自动叠加} \\
非空约束(NOT NULL) & √ & \text{自动继承} \\
\hline
\end{array}
$$
### 五、性能影响
不继承主键/唯一约束的设计避免了跨表唯一性校验带来的性能损耗,这种设计使PostgreSQL的继承机制更适合数据分片场景,而非强一致性要求的业务系统[^2]。
[^1]: 表继承要求子表必须包含父表所有字段和约束
[^2]: 主键不继承避免性能损耗
[^3]: 非空约束作为列属性自动继承
阅读全文
相关推荐


















