数据库原理与应用 第 5 章 · 第三节
课程 › 第 5 章 › 第三节 唯一约束主键约束主键与唯一外键约束删除规则检查约束 版式
第 5 章 数据表的管理和表中数据操纵 · 第三节

唯一、主键、外键与检查约束

UNIQUE、PRIMARY KEY、FOREIGN KEY、CHECK 的作用和写法
本 节 知 识 点
  1. 10UNIQUE 约束
  2. 11PRIMARY KEY 约束
  3. 12PRIMARY KEY 与 UNIQUE 的区别
  4. 13FOREIGN KEY 约束
  5. 14外键的删除和更新规则
  6. 15CHECK 约束
10
第 5 章 · 第三节 · 课件第 14、15 页合并重做

UNIQUE 约束

UNIQUE 约束保证字段的值在表中不重复。

5.2 MySQL 数据表管理课件第 14、15 页合并

UNIQUE 约束:字段的值不能重复

定义了 UNIQUE 约束的字段(或几个字段的组合),表中任意两行在这个字段上的值都不能相同。
列级约束 写在字段后面
CREATE TABLE s_unique (
  sno CHAR(10) NOT NULL,
  sn VARCHAR(45) UNIQUE,
  ……
);
表级约束 写在所有字段之后
CREATE TABLE s_unique (
  sno CHAR(10) NOT NULL,
  sn VARCHAR(45),
  ……
  UNIQUE (sn)
);
  • 要求几个字段组合起来不重复时,只能用表级约束,括号里写多个字段
  • 一张表可以定义多个 UNIQUE 约束
  • UNIQUE 字段允许为 NULL。MySQL 会为 UNIQUE 约束自动建立一个唯一索引

练一练

要求同一院系内学生不重名,应该怎样写?
  1. Asn 和 dept 后面各写一个 UNIQUE
  2. BUNIQUE (sn, dept)
  3. CPRIMARY KEY (sn)
  4. DCHECK (sn, dept)
答案 B

选项 A 是两个独立的约束,姓名在全表不能重复,院系也不能重复。B 才是两个字段组合起来不重复。

实 验

实验 1-2 建立课程表 c

11
第 5 章 · 第三节 · 课件第 16、17 页合并重做

PRIMARY KEY 约束

主键唯一标识表中的一行,不能为空,也不能重复。

5.2 MySQL 数据表管理课件第 16、17 页合并

PRIMARY KEY 约束:唯一标识表中的每一行

主键字段的值不能为 NULL,也不能重复。一张表只能有一个主键,主键可以是一个字段,也可以由几个字段组合而成。
一个字段做主键
CREATE TABLE s_primary (
  sno CHAR(10) NOT NULL PRIMARY KEY,
  sn VARCHAR(45),
  ……
);

也可以在最后写成 PRIMARY KEY (sno)

两个字段合起来做主键
CREATE TABLE sc_primary (
  sno CHAR(10) NOT NULL,
  cno CHAR(10) NOT NULL,
  score DECIMAL(5,2),
  PRIMARY KEY (sno, cno)
);

多个字段组成的主键,只能用表级写法

一名学生可以选多门课,一门课也有多名学生选,只有学号和课程号合在一起才能确定一条选课记录。

想一想

学生表能不能用姓名做主键?

实 验

实验 1-3 建立选课表 sc

12
第 5 章 · 第三节 · 课件第 18 页

PRIMARY KEY 与 UNIQUE 的区别

两者都保证不重复,区别在于个数和能否为空。

课件第 18 页

试一试主键和唯一约束,三处不同

试一下
主键
唯一
两种约束都保证不重复,点按钮看它们的差别。

知道更多UNIQUE 与空值

UNIQUE 字段可以有多个 NULL,NULL 之间不算重复。

13
第 5 章 · 第三节 · 课件第 19、21 页合并重做

FOREIGN KEY 约束

外键把两张表联系起来,从表中外键的值必须在主表中存在。

5.2 MySQL 数据表管理课件第 19、21 页合并

FOREIGN KEY 约束:从表中的值必须在主表中存在

主表 s(sno 是主键) 从表 sc(sno 是外键) snosn s1王彤 s2苏乐 snocno s1c1 s2c1 s9c1 引用 ? 主表中没有 s9,这一行不能插入(报 1452) 主表中被引用的 s1、s2 也不能随便删除(报 1451)
CREATE TABLE sc_foreign (
  sno CHAR(10) NOT NULL,
  cno CHAR(10) NOT NULL,
  score DECIMAL(5,2),
  PRIMARY KEY (sno, cno),
  FOREIGN KEY (sno) REFERENCES s (sno),
  FOREIGN KEY (cno) REFERENCES c (cno)
);
  • 主表必须已经存在,所以要先建 s 和 c,再建 sc
  • 外键引用的是主表的主键,两边字段的数据类型必须一致

关键术语

主表Parent Table
被引用的表,如学生表 s。
从表Child Table
定义外键的表,如选课表 sc。

实 验

实验 1-3 建立选课表 sc

14
第 5 章 · 第三节 · 课件第 20 页

外键的删除和更新规则

主表的行被删除或修改时,从表按指定的规则处理。

课件第 20 页

试一试删除学生 s1,三种规则三种结果

ON DELETE
主表 学生表 s
snosn
s1王彤
s2苏乐
从表 选课表 sc
sno(外键)cno
s1c1
s1c2
s2c1
执行 DELETE FROM s WHERE sno = 's1',选课表中还有 s1 的两条记录。

重 点

不写 ON DELETE 时默认是 NO ACTION,在 InnoDB 中与 RESTRICT 的效果相同。

15
第 5 章 · 第三节 · 课件第 22、23 页合并重做

CHECK 约束

CHECK 约束规定字段的取值范围,不满足条件的值不能写入。

5.2 MySQL 数据表管理课件第 22、23 页合并

CHECK 约束:字段的值必须满足条件

写法是 CHECK (条件)。插入或修改数据时,条件不成立的值不能写入表中。
列级约束
CREATE TABLE sc_check (
  sno CHAR(10) NOT NULL,
  cno CHAR(10) NOT NULL,
  score DECIMAL(5,2)
    CHECK (score >= 0 AND score <= 100),
  PRIMARY KEY (sno, cno)
);
表级约束,并起名为 ck_score
CREATE TABLE sc_check (
  sno CHAR(10) NOT NULL,
  cno CHAR(10) NOT NULL,
  score DECIMAL(5,2),
  PRIMARY KEY (sno, cno),
  CONSTRAINT ck_score
    CHECK (score >= 0 AND score <= 100)
);
  • 条件中可以用 AND、OR、BETWEEN 等把几个条件组合起来
  • 用 CONSTRAINT 起了名字的约束,以后可以按名字删除。不起名时 MySQL 会自动命名

练一练

成绩定义了 CHECK (score >= 0 AND score <= 100),插入 NULL 会怎样?
  1. A报 3819,违反 CHECK
  2. B插入成功
  3. C自动改成 0
  4. D报 1048,不能为空
答案 B

NULL 与任何值比较的结果都是未知,不算违反条件。CHECK 只拒绝条件为假的值。

知道更多版本差别

MySQL 8.0.16 起才真正检查 CHECK 约束,更早的版本只接受写法,不做检查。

实 验

实验 1-3 建立选课表 sc

保山学院·人工智能教研室·曹鼎鼎