4、关系数据库基础:关系、元组、属性、码、关系模式、关系数据库的完整性约束

关系数据库是现代数据库系统的理论基石,其核心思想源于E.F. Codd于1970年提出的关系模型。与层次模型和网状模型不同,关系模型将数据及其联系统一表示为二维表结构,通过集合论与谓词逻辑为数据操作提供了坚实的数学基础。理解关系、元组、属性、码以及完整性约束,是掌握SQL语言、进行数据库设计与应用开发的前提。本章将系统梳理这些核心概念,并重点剖析各类完整性约束在实际工程中的应用与权衡。

关系模型核心概念与完整性约束体系 关系模式 R(A1, A2, ..., An) 表结构 = 关系名 + 属性集合 + 约束 关系(Relation) 二维表 / 实体的集合 行 ↔ 元组 列 ↔ 属性 元组(Tuple) 表中的一行数据记录 属性(Attribute) 表中的一列,具有原子性 码(Key)体系 超键 → 候选键 → 主键 外键(FK)关联表间数据 代理键 / 自然键选择 唯一标识元组的最小属性集 完整性约束 实体完整性(主键非空) 参照完整性(外键匹配) 用户定义完整性(业务规则) 域完整性(数据类型/范围) 关系模型:数据结构(表)+ 关系操作(SQL)+ 完整性约束(规则)

4.1 关系模型的基本概念

4.1.1 关系的数学定义与直观理解

在关系模型中,关系(Relation)对应一张二维表。从数学角度看,关系是定义在若干域(Domain)上的笛卡尔积的子集。设属性 A1, A2, ..., An 的域分别为 D1, D2, ..., Dn,则关系 R 是 D1 × D2 × ... × Dn 的一个有限子集。每个元素是一个元组(Tuple),即表中的一行;每个属性对应表中的一列,列名称为属性名(Attribute Name)。

关系具有以下重要特征:

  • 元组唯一性:关系中不允许出现完全相同的两行(集合无重复元素)。
  • 属性原子性:每个属性值都是不可再分的原子值,不允许“表中套表”。
  • 无序性:元组之间、属性之间均无顺序要求,但实际存储时可通过索引加速访问。
  • 列名唯一性:同一关系中属性名必须唯一,不同属性可来自同一域。
经验提醒:在工程实践中,虽然关系理论要求元组无序,但SQL查询结果默认按插入顺序或索引顺序返回。若业务需要稳定排序,务必使用 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)的完整体系

码是关系中用于唯一标识元组的属性或属性组,是关系模型中最关键的概念之一。码的体系包括:

  1. 超键(Super Key):能唯一标识元组的属性集合。超键可能包含冗余属性。
  2. 候选键(Candidate Key):不含多余属性的最小超键。一个关系可能有多个候选键。
  3. 主键(Primary Key, PK):从候选键中选定一个作为主键,用于唯一标识每一行。主键值不能为NULL。
  4. 外键(Foreign Key, FK):一个关系中的属性(组),其取值必须参照另一个关系的主键或唯一键,用于建立表间关联。
  5. 代理键(Surrogate Key):为满足唯一性而额外添加的无业务含义的键(如自增ID),常用于替代复杂的自然键。
核心原理:主键的选择应遵循“最小性、稳定性、唯一性、非空性”原则。在电商系统中,订单表使用自增ID作为代理键,而将“订单号+商品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 约束,需通过触发器或应用层校验实现。设计时应先确认目标数据库的约束支持能力。
总结复盘:关系数据库的完整性约束体系可归纳为“一个中心、三个基本点”——以主键(实体完整性)为中心,以参照完整性(外键)、用户定义完整性(业务规则)、域完整性(数据类型)为基本点。在数据库设计阶段,应优先通过声明式约束(DDL)实现数据规则,减少应用层判断逻辑;同时权衡约束的严格性与业务灵活性,必要时采用软删除、状态机等设计模式替代物理删除。

掌握关系模型的基本概念与完整性约束,是进行规范化设计、编写高质量SQL、排查数据异常的前提。下一阶段的学习中,应重点练习将业务规则转化为约束定义,并理解不同约束在并发环境下的行为差异。