PostgreSQL - 约束


约束是对表上的数据列强制执行的规则。这些用于防止无效数据输入数据库。这保证了数据库中数据的准确性和可靠性。

约束可以是列级或表级。列级约束仅应用于一列,而表级约束应用于整个表。为列定义数据类型本身就是一个约束。例如,DATE 类型的列将该列限制为有效日期。

以下是 PostgreSQL 中常用的约束。

  • NOT NULL 约束- 确保列不能有 NULL 值。

  • UNIQUE Con​​straint - 确保列中的所有值都不同。

  • 主键- 唯一标识数据库表中的每一行/记录。

  • FOREIGN Key - 基于其他表中的列约束数据。

  • CHECK 约束- CHECK 约束确保列中的所有值满足特定条件。

  • EXCLUSION 约束- EXCLUDE 约束确保如果使用指定的运算符在指定的列或表达式上比较任何两行,则并非所有这些比较都会返回 TRUE。

非空约束

默认情况下,列可以保存 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 约束可防止两个记录在特定列中具有相同的值。例如,在 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 约束唯一标识数据库表中的每条记录。一张表中可以有多个UNIQUE列,但只能有一个主键。在设计数据库表时主键很重要。主键是唯一的 ID。

我们使用它们来引用表行。在表之间创建关系时,主键将成为其他表中的外键。由于“长期的编码监督”,SQLite 中的主键可以为 NULL。其他数据库不会出现这种情况

主键是表中的一个字段,它唯一标识数据库表中的每一行/记录。主键必须包含唯一值。主键列不能有 NULL 值。

一张表只能有一个主键,主键可以由单个或多个字段组成。当多个字段用作主键时,它们称为复合键

如果表在任何字段上定义了主键,则不能有两条记录具有相同的该字段值。

例子

您已经看到了上面的各种示例,其中我们创建了以 ID 作为主键的 COMAPNY4 表 -

CREATE TABLE COMPANY4(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

外键约束

外键约束指定一列(或一组列)中的值必须与另一个表的某些行中出现的值相匹配。我们说这维护了两个相关表之间的引用完整性。它们被称为外键,因为约束是外来的;也就是说,在桌子外面。外键有时称为引用键。

例子

例如,以下 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 约束启用一个条件来检查输入到记录中的值。如果条件计算结果为 false,则该记录违反约束并且不会输入到表中。

例子

例如,以下 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 的新表并添加五列。在这里,我们添加一个 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 扩展,它定义了普通标量数据类型的排除约束。

由于我们强制要求年龄必须相同,让我们通过向表中插入记录来查看这一点 -

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 表名在这里会很有帮助。一般语法是 -

ALTER TABLE table_name DROP CONSTRAINT some_name;