PostgreSQL 表中可以添加哪些约束?


一般来说,PostgreSQL 表可以使用 6 种类型的约束。它们列出如下并进行了解释:

NOT NULL 约束

这是一个非常常见的约束。如果某个特定列不能包含空值,则在创建表时添加此约束。例如,如果我们创建一个成绩表,该表不允许“姓名”列为空值,则创建表的命令如下所示:

CREATE TABLE marks(
   name VARCHAR NOT NULL,
   roll_no INTEGER,
   marks_obtained INTEGER
);

现在,如果我们尝试在不提供“姓名”列值的情况下向此表中插入一行,将会看到错误。让我们尝试一下:

INSERT INTO marks(roll_no, marks_obtained)
VALUES(25,56)

您将看到的错误类似于以下内容:

ERROR: null value in column "name" violates not-null constraint DETAIL: Failing row
contains (null, 25, 56). SQL state: 23502

UNIQUE 约束

顾名思义,此约束表示相关列不能包含重复值。这同样也是一个非常常见的约束。如果我们现在创建成绩表并希望在“学号”列上设置 UNIQUE 约束,则可以通过以下方式完成:

CREATE TABLE marks(
   name VARCHAR,
   roll_no INTEGER UNIQUE,
   marks_obtained INTEGER
);

现在,如果我们尝试插入重复的学号值,PostgreSQL 将抛出错误。让我们尝试一下:

INSERT INTO marks(name, roll_no, marks_obtained)
VALUES('Yash',25,56),
('Isha',25,64)

您将看到的错误类似于以下内容:

ERROR: duplicate key value violates unique constraint "marks_roll_no_key" DETAIL: Key
(roll_no)=(25) already exists. SQL state: 23505

PRIMARY KEY 约束

这是 NOT NULL 和 UNIQUE 约束的组合。它可以应用于单个列或多个列。如果 PRIMARY KEY 应用于多个列,则这些列的组合应具有唯一值,而各个列可以有重复的值。

让我们看看在单列和多列上应用 PRIMARY KEY 约束的示例:

单列

CREATE TABLE marks(
   name VARCHAR,
   roll_no INTEGER PRIMARY KEY,
   marks_obtained INTEGER
);

多列

CREATE TABLE marks(
   name VARCHAR,
   roll_no INTEGER,
   marks_obtained INTEGER,
   PRIMARY KEY (name, roll_no)
);

对于 Primary Key 约束,添加空值或重复值都会导致 PostgreSQL 抛出错误。检查此错误留作读者的练习。

FOREIGN KEY 约束

此约束有助于维护多个表之间的一致性。假设您已经在前面的示例中创建了一个成绩表,其中“学号”是 PRIMARY KEY。现在,如果您要创建另一个名为 student_info 的表,该表也具有“学号”列,并且您希望确保 student_info 表中只允许存在于成绩表中的“学号”值,则您将在 student_info 表的“学号”列上添加 FOREIGN KEY 约束。您可以这样做:

CREATE TABLE student_info(
   name VARCHAR,
   roll_no INTEGER REFERENCES marks (roll_no),
   age INTEGER,
   gender VARCHAR
);

现在,student_info 表的“学号”列引用了成绩表的“学号”列。因此,您将无法在 student_info 中添加任何“学号”不在成绩表中的值。

如果我的成绩表如下所示:

姓名学号百分比成绩
Siddhi4565
Yash2642
Isha5687

那么,我尝试在 student_info 表中添加学号为 45 的值。

INSERT INTO student_info(name, roll_no, age, gender)
VALUES ('Siddhi',45,23,'F');

此查询成功,因为学号 45 存在于成绩表中。现在,让我们尝试在 student_info 表中添加学号 12。

INSERT INTO student_info(name, roll_no, age, gender)
VALUES ('Aniket',12,26,'M');

PostgreSQL 将在此处抛出错误:

ERROR: insert or update on table "student_info" violates foreign key constraint "student_info_roll_no_fkey" DETAIL: Key (roll_no)=(12) is not present in table "marks". SQL state: 23503

就像我们可以在多列上添加 PRIMARY KEY 约束一样,我们也可以在多列上添加 FOREIGN KEY 约束。下面给出了一个示例:

CREATE TABLE student_info(
name VARCHAR,
roll_no INTEGER,
age INTEGER,
gender VARCHAR,
FOREIGN KEY (name, roll_no) REFERENCES marks (name, roll_no)
);

CHECK 约束

这是一个自定义约束。它允许我们强制列满足布尔表达式。例如,如果我们希望“学号”在成绩表中大于 0,我们可以如下添加该约束:

CREATE TABLE marks(
   name VARCHAR,
   roll_no INTEGER CHECK (roll_no > 0),
   marks_obtained INTEGER
);

现在,如果我尝试向此表中添加学号为 0 的条目,我将看到以下错误:

INSERT INTO marks(name, roll_no, marks_obtained)
VALUES('Yash',0,25)
ERROR: new row for relation "marks" violates check constraint "marks_roll_no_check"
DETAIL: Failing row contains (Yash, 0, 25). SQL state: 23514

EXCLUSION 约束

此约束的解释由 Stack Overflow 的一个答案给出。您可以在此处查看它:https://stackoverflow.com/a/51247705。现在,这是 UNIQUE 约束的更通用的扩展。UNIQUE 表示没有两行可以在相关列中具有相同的值。此约束更进一步。它表示,没有两行应该_______。您可以在空格中填写任何内容。您可以说“没有两行可以不同”,或者“没有两行可以相交”,或者任何其他语句,具体取决于上下文和正在考虑的列。现在,UNIQUE 约束是 EXCLUSION 约束的一个特例。但 UNIQUE 很简单。它只是说没有两行可以相同。因此,我们实际上检查的是 = 运算符。而 = 检查很容易执行。但并非所有运算符检查都一样容易。因此,EXCLUSION 约束要求您在应用约束的列上创建一个索引。这将确保比较速度很快。让我们通过一个示例来理解这一点。

CREATE TABLE marks(
   name VARCHAR,
   roll_no INTEGER,
   marks_obtained INTEGER,
   EXCLUDE USING gist(roll_no WITH <>)
);

请注意,您必须在每个数据库中运行一次 CREATE EXTENSION btree_gist,才能使上述命令正常工作。

现在,<> 是 PostgreSQL 中的不等于运算符。我们实际上告诉 PostgreSQL,对于添加到表的每一行,都使用 NOT EQUAL 运算符检查“学号”与所有其他已存在的“学号”。仅当所有比较结果都为 FALSE 时才允许它。换句话说,只允许所有学号相同,不允许不同的学号。

现在,让我们向上述表中添加一个值:

INSERT INTO marks8(name, roll_no, marks_obtained)
VALUES('Yash',26,55)

这将起作用。现在让我们添加另一个具有不同学号的值。

INSERT INTO marks8(name, roll_no, marks_obtained)
VALUES('Isha',56,65)

这将抛出一个错误:

ERROR: conflicting key value violates exclusion constraint "marks_roll_no_excl"
DETAIL: Key (roll_no)=(56) conflicts with existing key (roll_no)=(26). SQL state:
23P01

如果我想使用 EXCLUSION 强制执行 UNIQUE 约束,我会将 <> 替换为 =。

您也可以在多列上添加 EXCLUDE 约束。此处给出了一个示例:https://tutorialspoint.com/postgresql/postgresql_constraints.htm#:~:text=EXCLUSION%20Constraint。

更新时间: 2021 年 2 月 2 日

178 次查看

启动您的 职业生涯

通过完成课程获得认证

开始学习
广告