关系数据库:从一张表说起
关系数据库:从一张表说起
一句话总结:关系数据库的核心就是"关系"(二维表),通过键(主键、外键)建立表之间的联系,并通过实体完整性、参照完整性和用户自定义完整性来约束数据质量。
一、什么是关系?
在关系模型中,关系(Relation)就是一张二维表。但严格来说,它比普通表格有更多的约束和精确的定义。
1.1 关系的数学定义
关系是域的笛卡尔积的子集。
听起来很抽象?拆开来说:
- 域(Domain):属性的取值范围。例如"性别"的域 D1 = {男, 女},"专业"的域 D2 = {计算机, 软件工程, 人工智能}。
- 笛卡尔积:D1 × D2 = {(男, 计算机), (男, 软件工程), (男, 人工智能), (女, 计算机), (女, 软件工程), (女, 人工智能)},共 2×3 = 6 种组合。
- 关系:从笛卡尔积中选出有意义的组合,形成一张表。
实际使用中,你完全不需要手动算笛卡尔积。你只需要知道:关系 = 一张有严格规则的二维表。
1.2 关系的基本性质
| 性质 | 说明 | 示例 |
|---|---|---|
| 列同质 | 每一列的值来自同一个域 | "年龄"列全是整数,不能混进字符串 |
| 列无序 | 列的顺序无关紧要 | 把"姓名"放在"学号"前面,关系不变 |
| 行无序 | 行的顺序无关紧要 | 交换第 1 行和第 3 行,关系不变 |
| 元组唯一 | 任意两行不能完全相同 | 表中不能有两个一模一样的学生记录 |
| 原子性 | 每个单元格的值不可再分 | “电话"列不能存"手机:138xxx, 座机:010xxx”,要拆成两列 |
⚠️ 最后一条"原子性"非常重要。如果一个字段里还能再拆出多个信息,说明你的表设计不符合第一范式(1NF),后续博客会专门讲解。
二、关系模式与关系实例
2.1 关系模式(Relation Schema)
关系模式是对关系的结构描述,相当于"表头定义"。
形式化表示:
R(U, D, DOM, F)
- R:关系名
- U:属性集(有哪些列)
- D:属性所来自的域
- DOM:属性到域的映射
- F:属性间的数据依赖关系(如函数依赖)
简写形式(最常用):
学生(学号, 姓名, 性别, 年龄, 专业)
2.2 关系实例(Relation Instance)
关系实例是关系模式在某一时刻的具体取值,也就是表中的数据。
例如:
关系模式:学生(学号, 姓名, 性别, 年龄, 专业)
关系实例:
| 学号 | 姓名 | 性别 | 年龄 | 专业 |
|---|---|---|---|---|
| 2024001 | 张三 | 男 | 20 | 计算机 |
| 2024002 | 李四 | 女 | 19 | 软件工程 |
| 2024003 | 王五 | 男 | 21 | 计算机 |
类比:关系模式就像类(Class),关系实例就像对象(Object)。
三、键:关系数据库的灵魂
键(Key)用于唯一标识元组,并建立表与表之间的联系。理解键的类型,是学习数据库设计的关键一步。
3.1 超键(Super Key)
能唯一标识一个元组的属性集。
例如:学生表中,{学号} 是超键;{学号, 姓名} 也是超键(因为学号已经唯一了,加上姓名当然也能唯一标识)。
特点:超键可能包含冗余属性。
3.2 候选键(Candidate Key)
最小的超键——去掉其中任何一个属性,就不再是超键了。
例如:学生表中,{学号} 是候选键(假设学号唯一)。{身份证号} 也可能是候选键(如果学校收集了)。
特点:一个表可以有多个候选键。
3.3 主键(Primary Key)
从候选键中选定一个作为表的主键,用于唯一标识每一行。
主键的选择原则:
- 唯一性:不能重复
- 非空性:不能为 NULL
- 稳定性:尽量不要选会频繁变动的属性(如"手机号"不如"学号"稳定)
- 简洁性:尽量选择单个属性,而非组合属性
在 SQL 中,主键用
PRIMARY KEY声明,通常加下划线标识:学生(学号, 姓名, 性别, 年龄, 专业)
3.4 外键(Foreign Key)
一个表中的属性(或属性组),它是另一个表的主键,用于建立表之间的联系。
示例:学生表与系表
系表:
| 系号 | 系名 | 系主任 |
|---|---|---|
| 01 | 计算机系 | 赵教授 |
| 02 | 电子系 | 钱教授 |
学生表:
| 学号 | 姓名 | 性别 | 系号 |
|---|---|---|---|
| 2024001 | 张三 | 男 | 01 |
| 2024002 | 李四 | 女 | 02 |
| 2024003 | 王五 | 男 | 01 |
学生表中的"系号"就是外键,它引用了系表的"系号"(主键)。
通过外键,我们可以:
- 知道张三属于计算机系,李四属于电子系
- 防止输入不存在的系号(如 99)
- 建立表与表之间的关联查询
3.5 键的类型总结图
┌─────────────────────────────────────────┐
│ 超键(Super Key) │
│ ┌─────────────────────────────────┐ │
│ │ 候选键(Candidate Key) │ │
│ │ ┌─────────────────────────┐ │ │
│ │ │ 主键(Primary Key) │ │ │
│ │ │ (唯一被选中的候选键) │ │ │
│ │ └─────────────────────────┘ │ │
│ │ (其他候选键 = 备用键) │ │
│ └─────────────────────────────────┘ │
│ (含冗余属性的超键) │
└─────────────────────────────────────────┘
外键(Foreign Key)= 引用另一个表主键的属性
四、关系数据库的三类完整性约束
数据库的完整性(Integrity)指的是数据的正确性和相容性。关系数据库通过三类完整性约束来防止非法数据进入。
4.1 实体完整性(Entity Integrity)
规则:主键属性不能取空值(NULL),且主键值必须唯一。
为什么? 主键是用来唯一标识每个实体的。如果主键为空,就不知道是哪个实体;如果主键重复,就无法区分两个实体。
-- 以下插入会违反实体完整性
INSERT INTO 学生 VALUES (NULL, '张三', '男', 20); -- 主键为空,报错!
INSERT INTO 学生 VALUES (2024001, '李四', '女', 19); -- 学号重复,报错!
4.2 参照完整性(Referential Integrity)
规则:外键要么取空值(NULL),要么等于被引用表中某个元组的主键值。
为什么? 外键建立的是表与表之间的关联。如果外键指向了一个不存在的主键,就像打电话到一个空号,关系就断了。
-- 假设系表只有 01 和 02 两个系号
INSERT INTO 学生 VALUES (2024004, '赵六', '男', 99); -- 系号 99 不存在,报错!
参照完整性是维护表之间关系的核心机制,也是数据库自动实现级联操作(级联删除、级联更新)的基础。
4.3 用户自定义完整性(User-Defined Integrity)
规则:根据具体应用需求,由用户定义的特殊约束。
常见类型:
- NOT NULL:某些字段不能为空(如姓名)
- UNIQUE:某些字段不能重复(如身份证号)
- CHECK:检查取值范围(如年龄必须在 0~120 之间)
- DEFAULT:默认值(如性别默认为"男")
CREATE TABLE 学生 (
学号 CHAR(10) PRIMARY KEY, -- 实体完整性
姓名 VARCHAR(20) NOT NULL, -- 用户自定义:非空
性别 CHAR(2) DEFAULT '男', -- 用户自定义:默认值
年龄 INT CHECK (年龄 >= 0 AND 年龄 <= 120), -- 用户自定义:检查约束
系号 CHAR(2) REFERENCES 系(系号) -- 参照完整性
);
4.4 完整性约束总结
| 完整性类型 | 约束对象 | 谁负责维护 | 目的 |
|---|---|---|---|
| 实体完整性 | 主键 | DBMS 自动 | 保证每个实体可被唯一识别 |
| 参照完整性 | 外键 | DBMS 自动 | 保证表之间关联的正确性 |
| 用户自定义完整性 | 任意属性 | 用户定义,DBMS 执行 | 满足具体业务规则 |
五、关系代数:数据库的数学语言(了解)
关系模型之所以强大,还因为它有一套完整的数学操作体系——关系代数。SQL 本质上就是关系代数的"语法糖"。
5.1 基本操作
| 操作 | 符号 | 含义 | SQL 对应 |
|---|---|---|---|
| 选择 | σ | 按条件筛选行 | WHERE |
| 投影 | π | 选择列 | SELECT |
| 并 | ∪ | 合并两个同类表 | UNION |
| 差 | − | 在一个表但不在另一个表 | EXCEPT / NOT IN |
| 笛卡尔积 | × | 两表的所有组合 | CROSS JOIN |
| 连接 | ⋈ | 按条件组合两表 | JOIN |
5.2 示例
设学生表 R:
| 学号 | 姓名 | 专业 |
|---|---|---|
| 001 | 张三 | 计算机 |
| 002 | 李四 | 软件 |
| 003 | 王五 | 计算机 |
选择操作:σ_专业='计算机’® → 筛选出计算机专业的学生
投影操作:π_姓名® → 只保留"姓名"列
初学者不必死记符号,但要理解:SQL 的每个操作都有数学依据,这正是关系模型"科学严谨"的体现。
六、动手练习
练习 1:找键
给定以下"选课"表:
| 学号 | 课程号 | 成绩 |
|---|---|---|
| 001 | C01 | 85 |
| 001 | C02 | 90 |
| 002 | C01 | 78 |
- 超键有哪些?(提示:{学号, 课程号}, {学号, 课程号, 成绩}……)
- 候选键是什么?
- 主键应该选什么?
练习 2:判断完整性约束
分析以下场景,违反了哪类完整性?
- 插入一个学生,学号为 NULL(____)
- 删除系表中的"计算机系"记录,但学生表中还有学生属于计算机系(____)
- 插入一个学生,年龄填了 150(____)
- 插入一个学生,学号与已有学生重复(____)
练习 3:设计主键与外键
为"电商订单系统"设计表结构,包含:
- 用户表(用户ID、用户名、邮箱)
- 商品表(商品ID、商品名、价格)
- 订单表(订单ID、用户ID、商品ID、数量、下单时间)
请指出每个表的主键,以及订单表中的外键分别引用哪个表的主键。
七、常见误区与避坑指南
| 误区 | 正确理解 |
|---|---|
| “主键只能用 auto_increment” | 主键可以是自然键(如学号、身份证号),不一定是自增 ID |
| “外键名字必须和主键一样” | 外键名可以和主键不同,但数据类型必须一致 |
| “有了外键就不能删主表数据” | 可以设置 ON DELETE CASCADE(级联删除)或 ON DELETE SET NULL |
| “NULL 就是空字符串’'” | NULL 表示"未知/不存在",‘’ 表示"空字符串",两者完全不同 |
| “关系代数必须学才能写 SQL” | 了解即可,实际写 SQL 不需要手推关系代数 |
八、下篇预告
下一篇,我们将正式学习 SQL 语言基础——如何用数据库的"普通话"来创建表、插入数据、查询数据。掌握了 SQL,你才真正拥有了操作数据库的能力。
更多推荐
所有评论(0)