PostgreSQL - 约束
约束是对表中数据列强制执行的规则。这些规则用于防止无效数据进入数据库,从而确保数据库中数据的准确性和可靠性。
约束可以是列级别的或表级别的。列级别约束仅应用于一列,而表级别约束应用于整个表。为列定义数据类型本身就是一种约束。例如,DATE 类型的列会将该列限制为有效的日期。
以下是 PostgreSQL 中常用的约束。
NOT NULL 约束 − 确保列不能有 NULL 值。
UNIQUE 约束 − 确保列中的所有值都不同。
PRIMARY Key − 唯一标识数据库表中的每一行/记录。
FOREIGN Key − 基于其他表中的列来约束数据。
CHECK 约束 − CHECK 约束确保列中的所有值满足特定条件。
EXCLUSION 约束 − EXCLUDE 约束确保在使用指定操作符对指定列或表达式进行比较的任意两行时,并非所有比较都返回 TRUE。
NOT NULL 约束
默认情况下,列可以包含 NULL 值。如果不希望列有 NULL 值,则需要在该列上定义此类约束,指定该列不允许 NULL 值。NOT NULL 约束始终作为列约束来编写。
NULL 与无数据不同;它表示未知数据。
示例
例如,以下 PostgreSQL 语句创建一个名为 COMPANY1 的新表,并添加五个列,其中三个列 ID、NAME 和 AGE 指定不接受 NULL 值 −
CREATE TABLE COMPANY1( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
UNIQUE 约束
UNIQUE 约束防止两条记录在特定列中有相同的值。例如,在 COMPANY 表中,可能希望防止两个或更多人有相同的年龄。
示例
例如,以下 PostgreSQL 语句创建一个名为 COMPANY3 的新表,并添加五个列。其中 AGE 列设置为 UNIQUE,因此不能有两条具有相同年龄的记录 −
CREATE TABLE COMPANY3( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL UNIQUE, ADDRESS CHAR(50), SALARY REAL DEFAULT 50000.00 );
PRIMARY KEY Constraint
PRIMARY KEY 约束唯一标识数据库表中的每条记录。表中可以有多个 UNIQUE 列,但只能有一个 primary key。设计数据库表时,primary key 非常重要。Primary key 是唯一的 ID。
我们使用它们来引用表行。在创建表之间的关系时,primary key 会成为其他表中的 foreign key。由于一个“长期存在的编码疏忽”,在 SQLite 中 primary key 可以为 NULL。其他数据库则不是这种情况。
Primary key 是表中的一个字段,它唯一标识数据库表中的每一行/记录。Primary key 必须包含唯一值。Primary key 列不能有 NULL 值。
一个表只能有一个 primary key,它可以由单个字段或多个字段组成。当使用多个字段作为 primary key 时,它们被称为 composite key。
如果表中对任何字段定义了 primary key,那么不能有两条记录在该字段上的值相同。
Example
您已经在上面的各种示例中看到,我们创建了带有 ID 作为 primary key 的 COMAPNY4 表 −
CREATE TABLE COMPANY4( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
FOREIGN KEY Constraint
FOREIGN KEY 约束规定某列(或一组列)中的值必须与另一张表中某行出现的值匹配。我们称这维护了两个相关表之间的 referential integrity。它们被称为 foreign key,因为这些约束是外部的,即在表外部。有时 foreign key 也被称为 referencing key。
Example
例如,以下 PostgreSQL 语句创建一个名为 COMPANY5 的新表,并添加五个列。
CREATE TABLE COMPANY6( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
例如,以下 PostgreSQL 语句创建一个名为 DEPARTMENT1 的新表,并添加三个列。列 EMP_ID 是 foreign key,并引用 COMPANY6 表的 ID 字段。
CREATE TABLE DEPARTMENT1( ID INT PRIMARY KEY NOT NULL, DEPT CHAR(50) NOT NULL, EMP_ID INT references COMPANY6(ID) );
CHECK Constraint
CHECK 约束允许设置一个条件来检查插入记录的值。如果条件评估为 false,则该记录违反约束,无法插入表中。
Example
例如,以下 PostgreSQL 语句创建一个名为 COMPANY5 的新表,并添加五个列。在此,我们为 SALARY 列添加了一个 CHECK 约束,因此不能将 SALARY 设置为零。
CREATE TABLE COMPANY5( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL CHECK(SALARY > 0) );
EXCLUSION 约束
Exclusion 约束确保如果使用指定的操作符对指定列或表达式进行任意两行的比较,这些操作符比较中至少有一个将返回 false 或 null。
示例
例如,以下 PostgreSQL 语句创建一个名为 COMPANY7 的新表,并添加五列。在此,我们添加一个 EXCLUDE 约束 −
CREATE TABLE COMPANY7( ID INT PRIMARY KEY NOT NULL, NAME TEXT, AGE INT , ADDRESS CHAR(50), SALARY REAL, EXCLUDE USING gist (NAME WITH =, AGE WITH ) );
这里,USING gist 是用于强制执行的索引类型。
您需要在每个数据库中执行一次 CREATE EXTENSION btree_gist 命令。这将安装 btree_gist 扩展,该扩展为普通标量数据类型定义了 exclusion 约束。
由于我们强制要求年龄必须相同,让我们通过向表中插入记录来验证这一点 −
INSERT INTO COMPANY7 VALUES(1, 'Paul', 32, 'California', 20000.00 ); INSERT INTO COMPANY7 VALUES(2, 'Paul', 32, 'Texas', 20000.00 ); INSERT INTO COMPANY7 VALUES(3, 'Paul', 42, 'California', 20000.00 );
对于前两个 INSERT 语句,记录被添加到 COMPANY7 表中。对于第三个 INSERT 语句,将显示以下错误 −
ERROR: conflicting key value violates exclusion constraint "company7_name_age_excl" DETAIL: Key (name, age)=(Paul, 42) conflicts with existing key (name, age)=(Paul, 32).
删除约束
要删除一个约束,您需要知道其名称。如果知道名称,则删除很容易。否则,您需要找出系统生成的名称。psql 命令 \d table name 在这里可能会有帮助。一般语法为 −
ALTER TABLE table_name DROP CONSTRAINT some_name;