4、关系数据库基础:关系、元组、属性、码、关系模式、关系数据库的完整性约束
关系数据库是现代数据库系统的理论基石,其核心思想源于E.F. Codd于1970年提出的关系模型。与层次模型和网状模型不同,关系模型将数据及其联系统一表示为二维表结构,通过集合论与谓词逻辑为数据操作提供了坚实的数学基础。理解关系、元组、属性、码以及完整性约束,是掌握SQL语言、进行数据库设计与应用开发的前提。本章将系统梳理这些核心概念,并重点剖析各类完整性约束在实际工程中的应用与权衡。
4.1 关系模型的基本概念
4.1.1 关系的数学定义与直观理解
在关系模型中,关系(Relation)对应一张二维表。从数学角度看,关系是定义在若干域(Domain)上的笛卡尔积的子集。设属性 A1, A2, ..., An 的域分别为 D1, D2, ..., Dn,则关系 R 是 D1 × D2 × ... × Dn 的一个有限子集。每个元素是一个元组(Tuple),即表中的一行;每个属性对应表中的一列,列名称为属性名(Attribute Name)。
关系具有以下重要特征:
- 元组唯一性:关系中不允许出现完全相同的两行(集合无重复元素)。
- 属性原子性:每个属性值都是不可再分的原子值,不允许“表中套表”。
- 无序性:元组之间、属性之间均无顺序要求,但实际存储时可通过索引加速访问。
- 列名唯一性:同一关系中属性名必须唯一,不同属性可来自同一域。
ORDER BY 显式指定,不要依赖默认顺序。
4.1.2 关系模式与关系实例
关系模式(Relation Schema)是对关系结构的描述,形式化为 R(A1, A2, ..., An),其中 R 为关系名,Ai 为属性名。关系模式是“型”,一旦定义便相对稳定;关系实例(Relation Instance)是某一时刻关系中的数据集合,是“值”,随数据更新而变化。
| 对比维度 | 关系模式 | 关系实例 |
|---|---|---|
| 本质 | 表结构(DDL定义) | 表数据(DML操作) |
| 稳定性 | 长期不变 | 频繁变化 |
| SQL对应 | CREATE TABLE | INSERT / UPDATE / DELETE |
| 示例 | Student(Sno, Sname, Sage) | (‘001’, ‘张三’, 20) |
4.1.3 码(Key)的完整体系
码是关系中用于唯一标识元组的属性或属性组,是关系模型中最关键的概念之一。码的体系包括:
- 超键(Super Key):能唯一标识元组的属性集合。超键可能包含冗余属性。
- 候选键(Candidate Key):不含多余属性的最小超键。一个关系可能有多个候选键。
- 主键(Primary Key, PK):从候选键中选定一个作为主键,用于唯一标识每一行。主键值不能为NULL。
- 外键(Foreign Key, FK):一个关系中的属性(组),其取值必须参照另一个关系的主键或唯一键,用于建立表间关联。
- 代理键(Surrogate Key):为满足唯一性而额外添加的无业务含义的键(如自增ID),常用于替代复杂的自然键。
4.2 关系数据库的完整性约束
完整性约束是关系模型保证数据正确性、一致性的规则集合。DBMS在数据插入、修改、删除时自动检查这些约束,违反约束的操作将被拒绝执行。完整性约束分为四大类:
4.2.1 实体完整性(Entity Integrity)
实体完整性规则要求:主键属性值不能为NULL。因为主键用于唯一标识元组,若主键为空,则无法区分不同记录,也无法建立有效索引。实体完整性由DBMS在定义主键时自动强制实施。
-- 违反实体完整性的操作示例
CREATE TABLE Student (
Sno CHAR(10) PRIMARY KEY, -- 主键非空
Sname VARCHAR(20) NOT NULL
);
-- 以下插入将被拒绝:主键为NULL
INSERT INTO Student (Sno, Sname) VALUES (NULL, '李四');
4.2.2 参照完整性(Referential Integrity)
参照完整性规则要求:外键值要么为NULL,要么必须等于被参照表中某个元组的主键值。该约束维护了表间父子关系的有效性,防止“孤儿记录”出现。在SQL中通过 FOREIGN KEY 定义,并可指定删除/更新时的级联策略:
NO ACTION/RESTRICT:默认行为,拒绝删除被引用的父记录。CASCADE:父记录删除/更新时,自动删除/更新子表中匹配的外键记录。SET NULL:父记录删除时,将子表外键置为NULL(要求外键列允许NULL)。
CASCADE 删除虽然方便,但可能造成大量数据意外丢失。例如删除一个“已发货订单”时,级联删除其所有明细记录,若未做备份将无法恢复。生产环境建议使用“软删除”(增加 is_deleted 标志位)替代物理级联删除。
4.2.3 用户定义完整性(User-defined Integrity)
用户定义完整性是针对具体业务场景的约束规则,包括:
- 非空约束(
NOT NULL):某列不允许为空。 - 唯一约束(
UNIQUE):某列或列组合的值不重复,但允许一个NULL。 - 检查约束(
CHECK):限定列值的取值范围或逻辑条件。 - 默认值(
DEFAULT):未显式赋值时使用的默认值。
CREATE TABLE Orders (
OrderID INT PRIMARY KEY,
CustomerID INT NOT NULL,
OrderDate DATE DEFAULT CURRENT_DATE,
Status VARCHAR(10) CHECK (Status IN ('待支付', '已支付', '已发货', '已完成')),
Amount DECIMAL(10,2) CHECK (Amount >= 0)
);
4.2.4 域完整性(Domain Integrity)
域完整性是用户定义完整性的基础,指属性值必须符合其定义域的要求,包括数据类型、长度、格式、取值范围等。例如年龄字段定义为 TINYINT UNSIGNED,则负数和超过255的值都会被拒绝。DBMS通过数据类型系统自动实施域完整性。
4.3 案例拆解:学生选课系统的完整性设计
下面通过一个完整的选课系统案例,展示各类完整性约束的协同应用。
业务背景与约束:某高校开发选课系统,要求:① 学生信息中年龄必须在15~60岁之间;② 每门课程有容量上限(默认50人);③ 选课记录中同一学生不能重复选同一门课;④ 删除课程时,若已有学生选课则禁止删除;⑤ 学生退学后,其选课记录自动清除。
初始表结构设计:
-- 学生表
CREATE TABLE Student (
Sno CHAR(10) PRIMARY KEY,
Sname VARCHAR(20) NOT NULL,
Sage TINYINT CHECK (Sage BETWEEN 15 AND 60),
Sdept VARCHAR(30)
);
-- 课程表
CREATE TABLE Course (
Cno CHAR(6) PRIMARY KEY,
Cname VARCHAR(30) NOT NULL,
Capacity INT DEFAULT 50 CHECK (Capacity > 0)
);
-- 选课表(关联表)
CREATE TABLE SC (
Sno CHAR(10),
Cno CHAR(6),
Grade DECIMAL(5,2) CHECK (Grade BETWEEN 0 AND 100),
PRIMARY KEY (Sno, Cno), -- 实体完整性:联合主键
FOREIGN KEY (Sno) REFERENCES Student(Sno) ON DELETE CASCADE,
FOREIGN KEY (Cno) REFERENCES Course(Cno) ON DELETE RESTRICT
);
关键操作与约束验证:
| 操作场景 | SQL示例 | 约束类型 | 结果 |
|---|---|---|---|
| 插入年龄为70的学生 | INSERT INTO Student VALUES ('001','王五',70,'CS') | 用户定义(CHECK) | 拒绝,违反年龄范围 |
| 插入重复选课记录 | INSERT INTO SC VALUES ('001','C01',85) | 实体完整性(主键) | 拒绝,联合主键重复 |
| 删除被选中的课程C01 | DELETE FROM Course WHERE Cno='C01' | 参照完整性(RESTRICT) | 拒绝,存在子记录 |
| 删除学生001 | DELETE FROM Student WHERE Sno='001' | 参照完整性(CASCADE) | 成功,SC中该生记录自动删除 |
复盘与经验:该设计通过联合主键防止重复选课,通过 ON DELETE CASCADE 实现学生退学后的数据清理,通过 ON DELETE RESTRICT 保护课程数据不被误删。但需注意:RESTRICT 策略下,若课程已有历史选课记录,则永远无法物理删除该课程,需增加“停用”状态字段(如 is_active)来软处理。
4.4 常见误区与总结复盘
UNIQUE 约束与主键混淆。主键隐含非空+唯一,而 UNIQUE 允许一个NULL值。在MySQL中,UNIQUE 列可存在多个NULL;在Oracle中则不允许重复NULL。
CHECK 约束。某些DBMS(如MySQL 8.0之前)不强制实施 CHECK 约束,需通过触发器或应用层校验实现。设计时应先确认目标数据库的约束支持能力。
掌握关系模型的基本概念与完整性约束,是进行规范化设计、编写高质量SQL、排查数据异常的前提。下一阶段的学习中,应重点练习将业务规则转化为约束定义,并理解不同约束在并发环境下的行为差异。