请使用支持现代 CSS 与 JavaScript 的浏览器播放课件
DBPA · 5.1

数据库完整性与约束

让每一次数据变化都满足已定义的语义规则

VER. 2608.2 Built with impress.js

学习目标

数据库完整性约束把现实语义、表间相容性和业务规则交给 DBMS 定义与检查

  1. 01区分完整性与安全性的防范对象
  2. 02描述定义、检查和违约处理三项功能
  3. 03用 PRIMARY KEY 保证实体完整性
  4. 04用 FOREIGN KEY 保证非 NULL 外码引用存在,并维护表间相容性
  5. 05用 NOT NULL、UNIQUE、CHECK 表达业务规则,并用约束名和域支持维护
  6. 06按业务语义选择拒绝、级联或置空,并判断置空前提
2/16
LEARNING OBJECTIVES

完整性约束限定合法数据库状态及其变化

完整性与安全性都保护数据库,但完整性约束数据状态,安全性控制访问行为

关注点防范对象典型问题
完整性数据正确且表间相容成绩超范围、孤立外码
安全性非法用户或非法操作未授权读取、越权修改
Takeaway

完整性规则描述合法数据库状态以及状态如何变化

3/16
INTEGRITY SCOPE

DBMS 用三项功能形成一个运行循环

启用约束并由 DBMS 执行时,正常写入路径都会经过相应检查

定义

DBMS 把语义规则存入模式与数据字典

检查

DBMS 按约束类型在数据变化后或提交时验证

处理

一般违约会被拒绝;参照动作可以拒绝、级联或置空

4/16
INTEGRITY CONTROL

组合主码让每条选课记录有稳定身份

Sno、Cno 可各自重复;组合值必须唯一非空,且组合主码需表级定义

Student、Course 与 SC 之间的主码和外码联系
SQL
CREATE TABLE SC (
  Sno CHAR(8) NOT NULL,
  Cno CHAR(5) NOT NULL,
  Grade SMALLINT,
  PRIMARY KEY (Sno, Cno)
);
5/16
ENTITY INTEGRITY

组合主码约束如何生效

唯一与非空是完整性语义;索引只是实现手段

语义/实现违反或作用目的
组合值唯一拒绝重复插入或修改避免重复选课
主码属性非空拒绝 NULL保证元组可识别
主码索引加速查找与检查实现手段,不等于语义
6/16
ENTITY INTEGRITY

非 NULL 外码值必须找到被参照主码

允许 NULL 时,NULL 表示暂时没有引用;本例的 Sno、Cno 另有 NOT NULL

SQL
-- CREATE TABLE SC 中的外码子句;标准 SQL/MySQL 8.4 InnoDB 常见语法示意
CREATE TABLE SC
(
  Sno CHAR(8) NOT NULL,
  Cno CHAR(5) NOT NULL,
  PRIMARY KEY (Sno, Cno),
  FOREIGN KEY (Sno) REFERENCES Student(Sno),
  FOREIGN KEY (Cno) REFERENCES Course(Cno)
);
Takeaway

外码是否允许为空,要结合主属性、NOT NULL 和业务语义判断;空值不等于引用了不存在的对象

7/16
REFERENTIAL INTEGRITY

参照完整性:同时检查两端变化

SC 是参照表;Student 和 Course 是被参照表

变化可能问题默认思路
SC 插入外码找不到 Student 或 Course 主码拒绝(NO ACTION / RESTRICT)
SC 修改外码新值无对应主码拒绝(NO ACTION / RESTRICT)
Student/Course 删除被引用主码SC 出现悬空引用拒绝或按策略处理
Student/Course 修改被引用主码原引用可能失效拒绝或按策略处理
Takeaway

未指定动作时通常拒绝;级联或置空必须在外码定义中显式选择

8/16
REFERENTIAL CHECK

参照动作的处理要服从业务语义

级联不是默认答案,而是一种有后果的设计选择

SQL
FOREIGN KEY (Sno) REFERENCES Student(Sno)
  ON DELETE CASCADE
  ON UPDATE CASCADE,
FOREIGN KEY (Cno) REFERENCES Course(Cno)
  ON DELETE NO ACTION
  ON UPDATE CASCADE

拒绝

拒绝策略阻止会破坏引用的删除或修改

级联

级联策略在从属关系明确时同步相关变化

置空

置空策略保留记录但解除引用;外码必须允许 NULL 且不能属于主码

Takeaway

本例 Sno、Cno 不能 SET NULL;MySQL 8.4 InnoDB 中,NO ACTIONRESTRICT 同为立即拒绝

9/16
REFERENTIAL ACTIONS

业务语义可以写成列级与元组级约束

把规则放在 DBMS 中,可以让所有应用面对同一边界

SQL
CREATE TABLE Student
(
  Sno CHAR(8) PRIMARY KEY,
  Sname CHAR(20) NOT NULL,
  Semail VARCHAR(100) UNIQUE,
  Ssex CHAR(6) CHECK (Ssex IN ('男', '女')),
  Smajor VARCHAR(40)
);
-- SC 已有 Grade 列,仅展示新增约束片段
ALTER TABLE SC ADD CONSTRAINT CK_SC_Grade
  CHECK (Grade >= 0 AND Grade <= 100);
变化约束结果处理
Semail 重复非 NULL 值UNIQUE 违约拒绝
Ssex = NULLCHECK 为 UNKNOWNMySQL 8.4 可能放行
Ssex = '其他'CHECK 为 FALSE拒绝
Takeaway

UNIQUE 的可空列可能允许多个 NULL;若要求“非空且合规”,要同时写 NOT NULL 与 CHECK

10/16
USER DEFINED RULES

约束范围决定它能表达什么

约束范围可以从单列扩展到同一元组、可复用域以及跨表规则

  1. 01属性级 CHECK:限制一个列的取值范围或集合
  1. 01元组级 CHECK:比较同一元组中的多个属性
  1. 01域用于复用取值规则;ASSERTION 用于表达跨表或聚集规则
SQL
-- 元组级 CHECK 片段
CHECK (StartDate <= EndDate)

同一行的两个列共同决定能否通过检查

Takeaway

元组级 CHECK 不能直接表达跨表存在性;复杂跨表规则需要 ASSERTION、触发器等机制

11/16
CONSTRAINT SCOPE

约束命名让规则可以维护

约束修改要同时考虑语义、已有数据和 DBMS 语法

SQL
-- 标准 SQL 语义示意:把旧范围改为新范围
CREATE TABLE Student
(
  Sno CHAR(8),
  CONSTRAINT StudentKey PRIMARY KEY (Sno),
  CONSTRAINT CK_Student_SnoRange CHECK (Sno BETWEEN '10000000' AND '29999999')
);

ALTER TABLE Student
DROP CONSTRAINT CK_Student_SnoRange;

ALTER TABLE Student
ADD CONSTRAINT CK_Student_SnoRange
CHECK (Sno BETWEEN '90000000' AND '99999999');

-- MySQL 8.4 删除 CHECK 约束使用 DROP CHECK
ALTER TABLE Student
DROP CHECK CK_Student_SnoRange;
Takeaway

维护约束时先明确要删除或新增的规则,再按当前 DBMS 选择语法;新增规则前要检查已有数据和依赖应用

12/16
MAINTAINABLE CONSTRAINTS

域:集中管理共享取值规则

域可以复用类型与约束;下例采用标准/其他 DBMS 语法,不用于 MySQL 8.4 实践

SQL
CREATE DOMAIN GenderDomain CHAR(6)
CHECK (VALUE IN ('男', '女'));

CREATE TABLE Student
(
  Ssex GenderDomain,
  EmergencyContactSex GenderDomain
);
Takeaway

域负责复用取值规则;ASSERTION 可表达跨表或聚集约束,二者均是标准/其他 DBMS 概念,MySQL 8.4 实践用列定义和 CHECK

13/16
DOMAIN

用完整性类型和维护边界判断约束

每项约束都要说明保护对象、检查边界和违约处理

实体

PRIMARY KEY 保证组合值唯一,并要求主码属性非空

参照

非 NULL 外码必须引用真实主码,参照动作还要选择处理策略

用户定义

NOT NULL、UNIQUE 和 CHECK 表达用户规则,还要注意 NULL/UNKNOWN

约束维护

约束名、ALTER TABLE 和域支持模式维护,具体语法取决于 DBMS

Takeaway

实体和用户定义约束通常在违约时拒绝;参照约束还可以按定义级联或置空

14/16
RECAP

本节知识地图

15/16
KNOWLEDGE MAP

本节问题

  1. 01Student 无 S999,向 SC 插入 S999/C01 会违反什么约束?
  2. 02Sno、Cno 为何可重复,而组合主码不能重复或含 NULL?
  3. 03删除被 SC 引用的学生时,RESTRICT/CASCADE/SET NULL 各怎样处理?本例为何不能 SET NULL?
  4. 04可空 UNIQUE 遇到两个 NULL 会怎样?何时还需 NOT NULL?
  5. 05CHECK 如何处理 Ssex=NULLSsex='其他'?能否检查另一表?
  6. 06约束命名为何便于 ALTER TABLE?域与 ASSERTION 有何产品边界?
16/16
CHECK YOUR UNDERSTANDING