05_PostgreSQL 约束

本文介绍了PostgreSQL数据库中的约束,包括常用类型、实例演示如何创建约束,以及如何通过查询获取表的约束信息,并进行了约束功能的实战测试。

PostgreSQL约束

常用约束介绍

约束名描述
NOT NULL字段值不能存储NULL
UNIQUE字段值都是唯一的
CHECK字段值需符合指定的条件
DEFAULT字段默认值
PRIMARY KEY主键约束(UNIQUE + NOT NULL)
FOREIGN KEY外键约束(一个表中的数据匹配另一个表中的值的参照完整性)
EXCLUSION排他约束(如果将任何两行的指定列或表达式使用指定操作符进行比较,至少其中一个操作符比较将会返回 false 或空值。)

示例

CREATE TABLE employee(
	id SERIAL PRIMARY KEY,
	name VARCHAR(255) NOT NULL,
	birthdate timestamp NOT NULL,
	info TEXT,
	salary REAL CHECK(salary > 2000),
	is_staff boolean DEFAULT True NOT NULL,
	is_delete boolean DEFAULT False NOT NULL,
	create_time timestamp DEFAULT CURRENT_TIMESTAMP
);

查看表信息

>\d employee
                                                   Table "public.employee"
   Column    |            Type             | Collation | Nullable |                          Default            
              
-------------+-----------------------------+-----------+----------+---------------------------------------------
--------------
 id          | integer                     |           | not null | nextval('employee_id_seq'::regclass)
 name        | character varying(255)      |           | not null | 
 birthdate   | timestamp without time zone |           | not null | 
 info        | text                        |           |          | 
 salary      | real                        |           |          | 
 is_staff    | boolean                     |           | not null | true
 is_delete   | boolean                     |           | not null | false
 create_time | timestamp without time zone |           |          | '2019-08-29 14:22:06.446794'::timestamp with
out time zone
Indexes:
    "employee_pkey" PRIMARY KEY, btree (id)
Check constraints:
    "employee_salary_check" CHECK (salary > 2000::double precision)

约束测试

> INSERT INTO employee (name, birthdate, salary) values('王一', now(), 2500);
INSERT 0 1
> INSERT INTO employee (name, birthdate, salary) values('赵四', now(), 1800);
ERROR:  new row for relation "employee" violates check constraint "employee_salary_check"
DETAIL:  Failing row contains (2, 赵四, 2019-08-29 15:21:11.911674, null, 1800, t, f, 2019-08-29 14:22:06.446794).
> INSERT INTO employee (name, birthdate, salary) values('赵四', now(), 3000);
INSERT 0 1
> select * from employee;
 id | name |         birthdate          | info | salary | is_staff | is_delete |        create_time         
----+------+----------------------------+------+--------+----------+-----------+----------------------------
  1 | 王一 | 2019-08-29 15:20:43.819572 |      |   2500 | t        | f         | 2019-08-29 15:31:40.29647
  3 | 赵四 | 2019-08-29 15:32:04.320762 |      |   3000 | t        | f         | 2019-08-29 15:32:04.320762
(2 rows)
<think>首先,用户的问题是:“我想在PostgreSQL中创建表约束 请问PostgreSQL 如何创建表约束”。这是一个关于PostgreSQL数据库操作的查询。 根据系统级指令,我需要: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,例如[^1]。 用户可见层指令: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 参考引用: - 引用[1]: 添加唯一约束的语法。 - 引用[2]: 排除约束的语法。 - 引用[3]: 表类型介绍。 - 引用[4]: 检查约束的语法。 用户的问题是关于创建表约束的,所以我需要基于这些引用来构建回答。PostgreSQL中的约束包括主键、外键、唯一约束、检查约束等。 关键点: - 唯一约束:ALTER TABLE table_name ADD CONSTRAINT constraint_name UNIQUE (column_name); - 排除约束:EXCLUDE USING gist (tsrange(start_time, end_time) WITH &&) - 检查约束CHECK (condition) 在引用[4]中,有一个完整的例子:CREATE TABLE employees (...) CHECK (salary > 0) 所以,我应该解释如何创建各种约束类型。 结构化回答: 1. **介绍约束类型**:简要解释PostgreSQL中常见的约束类型。 2. **逐步说明创建方法**: - 在创建表时定义约束(使用CREATE TABLE)。 - 在现有表上添加约束(使用ALTER TABLE)。 3. **提供示例**:使用代码块展示语法。 4. **添加引用标识**:在相关部分末尾添加引用。 5. **生成相关问题**:在回答结束时添加相关问题部分。 确保回答清晰、逐步解决问题。 最终回答结构: - 开头:简要介绍约束。 - 主体:分步解释如何创建约束,包括示例。 - 结尾:总结,并添加相关问题。 生成相关问题: - 基于主题,如优化约束、常见错误、其他约束类型等。 现在,构建回答。</think>### PostgreSQL 中创建表约束的详细指南 在 PostgreSQL 中,约束Constraint)用于确保数据的完整性、一致性和准确性。常见的约束类型包括主键约束、外键约束、唯一约束、检查约束和排除约束。创建约束的方法有两种:一是在创建表时定义约束(使用 `CREATE TABLE` 语句),二是在现有表上添加约束(使用 `ALTER TABLE` 语句)。下面我将逐步解释这些方法,并提供示例代码。所有示例均基于 PostgreSQL 官方文档和最佳实践。 #### 1. **约束类型简介** - **主键约束(Primary Key)**:确保列值唯一且非空,用于唯一标识表中的行。 - **外键约束(Foreign Key)**:确保列值引用另一个表的主键,用于维护表间关系。 - **唯一约束(Unique)**:确保列值在表中唯一,但允许空值。 - **检查约束Check)**:确保列值满足指定条件(如数值范围)。 - **排除约束(Exclude)**:确保行之间不满足特定条件(如时间范围不重叠),需使用 GiST 索引[^2]。 #### 2. **在创建表时定义约束** 在 `CREATE TABLE` 语句中,直接在列定义或表末尾添加约束。语法如下: ```sql CREATE TABLE table_name ( column1 data_type CONSTRAINT constraint_name constraint_type, ... [CONSTRAINT constraint_name] constraint_type (condition) ); ``` - **示例:创建表时定义多种约束** ```sql -- 创建 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), -- 检查约束确保工资大于零 CONSTRAINT fk_department FOREIGN KEY (department_id) REFERENCES departments(department_id) -- 外键约束 ); ``` 解释: - `PRIMARY KEY` 指定主键约束。 - `UNIQUE` 确保 `email` 列值唯一。 - `CHECK (salary > 0)` 确保工资值大于零,防止无效数据[^4]。 - `FOREIGN KEY` 引用另一个表(`departments`)的主键。 #### 3. **在现有表上添加约束** 使用 `ALTER TABLE` 语句添加约束。语法如下: ```sql ALTER TABLE table_name ADD CONSTRAINT constraint_name constraint_type (condition); ``` - **示例:在现有表上添加约束** ```sql -- 添加唯一约束(确保 email 列唯一) ALTER TABLE employees ADD CONSTRAINT unique_email UNIQUE (email); -- 使用 ADD CONSTRAINT 语法[^1] -- 添加检查约束(确保年龄在 18-65 岁之间) ALTER TABLE employees ADD CONSTRAINT age_check CHECK (age BETWEEN 18 AND 65); -- 添加排除约束(防止事件时间重叠) ALTER TABLE events ADD CONSTRAINT no_overlap EXCLUDE USING gist (tsrange(start_time, end_time) WITH &&); -- 使用 GiST 索引[^2] ``` 解释: - `ADD CONSTRAINT` 允许自定义约束名称(如 `unique_email`),便于后续管理。 - 排除约束使用 `EXCLUDE USING gist` 确保时间范围不重叠(`&&` 表示重叠操作符)。 #### 4. **注意事项** - **约束命名**:建议为约束指定名称(如 `CONSTRAINT unique_email`),否则 PostgreSQL 会自动生成名称,这可能在修改时带来不便。 - **性能影响**:添加约束会触发表扫描,对大表操作可能耗时较长。建议在低峰期执行。 - **错误处理**:如果现有数据违反约束,添加操作会失败。可先使用 `VALIDATE CONSTRAINT` 检查数据。 ```sql ALTER TABLE employees ADD CONSTRAINT salary_check CHECK (salary > 0) NOT VALID; -- 先添加约束但不验证 ALTER TABLE employees VALIDATE CONSTRAINT salary_check; -- 后续验证数据 ``` - **约束类型**:PostgreSQL 支持多种表类型(如普通表、分区表),但约束语法通用[^3]。 #### 5. **总结** 在 PostgreSQL 中创建表约束是维护数据质量的关键。您可以选择在 `CREATE TABLE` 时定义约束,或在表创建后使用 `ALTER TABLE` 添加。核心约束包括主键、外键、唯一、检查和排除约束,每种都通过简单语法实现。例如,唯一约束使用 `UNIQUE` 关键字[^1],检查约束使用 `CHECK (condition)`[^4],排除约束则需 GiST 索引支持[^2]。实际应用中,请根据数据模型选择合适的约束类型。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值