【PostgreSQL】入门篇——介绍表的创建、主键、外键、唯一约束和检查约束的概念及其应用

PostgreSQL表与约束确保数据完整性

1. 表的创建

描述

表是数据库中用于存储数据的基本结构。每个表由行和列组成,行表示记录,列表示字段。每个字段有特定的数据类型(如整数、字符串、日期等),并且可以设置各种约束来确保数据的完整性。

语法

CREATE TABLE table_name (
    column1 datatype [constraint],
    column2 datatype [constraint],
    ...
);

应用场景

  • 数据存储:表是存储各种数据的基本单位,几乎所有的数据库操作都涉及到表。
  • 数据组织:通过表可以有效地组织和管理数据。

示例

创建一个名为 employees 的表,包含员工的基本信息:

CREATE TABLE employees (
    employee_id SERIAL PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    department VARCHAR(50),
    salary NUMERIC(10, 2)
);

解释

  • employee_id SERIAL PRIMARY KEY:定义了一个自增的主键,用于唯一标识每个员工。
  • first_namelast_namedepartment:存储员工的名字、姓氏和部门,使用 VARCHAR 数据类型。
  • salary NUMERIC(10, 2):存储员工的工资,最多 10 位数字,其中 2 位为小数。

2. 主键 (Primary Key)

描述

主键是表中用于唯一标识每一行记录的字段或字段组合。主键的值必须是唯一的,并且不能为空。主键的主要作用是确保数据的唯一性和完整性。

应用场景

  • 唯一标识:每个记录必须有一个唯一的标识符,主键正是用于这个目的。
  • 数据完整性:通过主键可以确保没有重复的记录。

优缺点

  • 优点:确保数据的唯一性,提升查询效率。
  • 缺点:主键一旦设置,无法更改,可能导致数据迁移时的复杂性。

示例

在 employees 表中,employee_id 是主键,使用 SERIAL 数据类型自动生成唯一值。

CREATE TABLE employees (
    employee_id SERIAL PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    department VARCHAR(50),
    salary NUMERIC(10, 2)
);

解释

  • PRIMARY KEY 约束确保 employee_id 的值是唯一的,不能重复。

3. 外键 (Foreign Key)

描述

外键是一个表中的字段,它引用另一个表的主键。外键用于建立表之间的关系,确保数据的参照完整性。外键约束确保在子表中插入的值必须在父表中存在。

应用场景

  • 表关系:用于表示表之间的关系,如订单与客户、员工与部门等。
  • 数据完整性:确保在子表中引用的值在父表中是有效的。

优缺点

  • 优点:维护数据的一致性,防止无效数据的插入。
  • 缺点:可能影响性能,特别是在涉及大量数据的情况下。

示例

创建一个 departments 表,并在 employees 表中添加外键,引用 departments 表的主键:

CREATE TABLE departments (
    department_id SERIAL PRIMARY KEY,
    department_name VARCHAR(50) UNIQUE
);

CREATE TABLE employees (
    employee_id SERIAL PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    department_id INT,
    salary NUMERIC(10, 2),
    FOREIGN KEY (department_id) REFERENCES departments(department_id)
);

解释

  • FOREIGN KEY (department_id) REFERENCES departments(department_id):这条语句确保 employees 表中的 department_id 必须在 departments 表中存在。

4. 唯一约束 (Unique Constraint)

描述

唯一约束确保某一列或多列的值在表中是唯一的。允许空值,但每个非空值必须是唯一的。唯一约束可以应用于多个列的组合。

应用场景

  • 防止重复数据:确保某些字段(如电子邮件、用户名)在表中是唯一的。
  • 组合唯一性:可以对多个列组合设置唯一约束。

优缺点

  • 优点:确保数据的唯一性,避免重复记录。
  • 缺点:可能会影响插入性能,尤其是在高并发情况下。

示例

在 employees 表中,添加唯一约束以确保每个员工的电子邮件地址是唯一的:

CREATE TABLE employees (
    employee_id SERIAL PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    email VARCHAR(100) UNIQUE,
    department_id INT,
    salary NUMERIC(10, 2),
    FOREIGN KEY (department_id) REFERENCES departments(department_id)
);

解释

  • UNIQUE 约束确保 email 字段的值在 employees 表中是唯一的。

5. 检查约束 (Check Constraint)

描述

检查约束用于限制列中的值,确保它们满足特定条件。可以用于确保数据的有效性,如数值范围、字符串格式等。

应用场景

  • 数据有效性:确保插入的数据符合业务规则。
  • 范围限制:限制数值在特定范围内。

优缺点

  • 优点:增强数据的完整性,防止无效数据的插入。
  • 缺点:复杂的检查条件可能影响性能。

示例

在 employees 表中,添加检查约束以确保员工的工资大于零:

CREATE TABLE employees (
    employee_id SERIAL PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    email VARCHAR(100) UNIQUE,
    department_id INT,
    salary NUMERIC(10, 2) CHECK (salary > 0),
    FOREIGN KEY (department_id) REFERENCES departments(department_id)
);

解释

  • CHECK (salary > 0) 约束确保 salary 字段的值必须大于零,防止插入无效的工资数据。

总结

在数据库设计中,合理使用表、主键、外键、唯一约束和检查约束,可以确保数据的完整性和一致性。以下是这些概念的简要总结:

  • 表的创建:定义数据的存储结构。
  • 主键:唯一标识表中的每一行记录,确保数据的唯一性。
  • 外键:建立表之间的关系,确保参照完整性,防止无效数据。
  • 唯一约束:确保某一列的值在表中是唯一的,防止重复数据。
  • 检查约束:限制列中的值以确保数据的有效性。

通过这些约束,数据库能够更好地维护数据的完整性和一致性,防止无效或重复的数据被插入。

<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]: 非空约束作为列属性自动继承
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值