PostgreSQL 约束
约束是对表中数据列强制执行的规则。它们用于防止无效数据进入数据库。这确保了数据库中数据的准确性和可靠性。
约束可以是列级别的或表级别的。列级别的约束仅应用于一列,而表级别的约束应用于整个表。为列定义数据类型本身就是一种约束。例如,日期类型的列限制该列只能包含有效的日期。
以下是在PostgreSQL中常用的约束:
- NOT NULL约束 - 确保列不能为空。
-
UNIQUE约束 - 确保列中的所有值都不同。
-
主键约束 - 在数据库表中唯一标识每一行/记录。
-
外键约束 - 基于其他表中的列对数据进行约束。
-
CHECK约束 - CHECK约束确保列中的所有值满足特定条件。
-
EXCLUSION约束 - EXCLUSION约束确保如果对指定列或表达式使用指定的运算符比较任意两行,不会返回全部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
);
唯一约束
唯一约束防止特定列中的两条记录具有相同的值。例如,在COMPANY表中,您可能希望防止两个或多个人具有相同的年龄。
示例
例如,下面的PostgreSQL语句创建一个名为COMPANY3的新表,并添加五个列。这里,AGE列被设置为唯一,这样您就不能有两条具有相同年龄的记录。
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
);
主键约束
主键约束在数据库表中唯一标识每个记录。表中可以有多个唯一约束列,但只能有一个主键。主键在设计数据库表时非常重要,它们是唯一的标识符。
我们使用主键来引用表的行。当创建表之间的关系时,主键成为其他表中的外键。由于“长期存在的编码疏忽”,在SQLite中主键可以为空。而其他数据库不允许主键为空。
主键是表中用于唯一标识每一行/记录的字段。主键必须包含唯一的值。主键列不能有空值。
一个表只能有一个主键,可以由单个或多个字段组成。当多个字段用作主键时,称为 复合键 。
如果表中的任何字段上定义了主键,则不能有两条记录具有相同的字段值。
示例
您已经在上面的示例中看到了各种不同的例子,其中我们使用ID作为主键创建了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约束
外键约束指定某一列(或一组列)的值必须与另一个表中某一行中的值匹配。我们称之为保持两个相关表之间的引用完整性。它们被称为外键是因为约束是外部的,即在表之外。外键有时也被称为引用键。
示例
例如,以下的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是外键,引用了表COMPANY6的ID字段。
CREATE TABLE DEPARTMENT1(
ID INT PRIMARY KEY NOT NULL,
DEPT CHAR(50) NOT NULL,
EMP_ID INT references COMPANY6(ID)
);
CHECK约束
CHECK约束允许检查要输入记录的值是否满足条件。如果条件为假,该记录将违反约束并不会被插入表中。
示例
例如,下面的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)
);
排除约束
排除约束确保如果在指定列或表达式上使用指定运算符比较任意两行,则这些运算符比较中至少有一个会返回false或null。
示例
例如,以下PostgreSQL语句创建了一个名为COMPANY7的新表,并添加了五个列。在这里,我们添加了一个排除约束。
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 <>)
);
这里,使用gist是要构建和使用的索引类型,用于强制执行。
您需要执行命令CREATE EXTENSION btree_gist,每个数据库执行一次。这将安装btree_gist扩展,该扩展定义了对纯量数据类型的排除约束。
由于我们强制年龄必须相同,让我们通过向表中插入记录来验证这一点-
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;