一、数据库模式
1.1、三级模式-两级映射结构图
内模式层
概念模式层
外模式层
逻辑独立性
物理独立性
用户级数据库
用户视图
DBA视图
内部视图
外模式A
外模式B
概念模式
内模式
外模式-概念模式映射
概念模式-内模式映射
操作系统
物理数据库
1.2、核心概念定义
外模式:视图级
模式(概念模式):表级
内模式:文件级
注:聚簇索引会影响内模式。
1.3、数据库架构层次
用户级数据库:对应用户视图,包含外模式(如外模式A、外模式B)。
概念级数据库:对应DBA视图,包含概念模式。
物理级数据库:对应内部视图,包含内模式。
底层支撑:操作系统 -> 物理数据库。
1.4、两级映射与数据独立性
1.4.1、逻辑独立性
定义:数据的逻辑结构发生变化后,用户程序也可以不修改。
实现方式 :为了保证应用程序能够正确执行,需要修改外模式和概念模式之间的映像。
1.4.2、物理独立性
定义:当数据的物理结构发生改变时,应用程序不用改变。
实现方式 :为了保证应用程序能够正确执行,需要修改概念模式和内模式之间的映像。
1.5、模式的数量关系
外模式 :可以有多个(不同用户组看到不同的数据视图,保障安全性)。
概念模式 :只有一个(全局逻辑视图,定义所有数据实体及关系)。
内模式 :只有一个(全局物理存储策略)。
1.6、数据独立性的价值
解耦:这是架构设计的核心思想。通过两层映射,将应用层(App)与逻辑层(Schema)、逻辑层与物理层(Storage)解耦。
系统演进:当业务逻辑变更(如拆分表)时,只需调整"外模式-概念模式映射",前端应用无需重写 SQL;当更换存储介质或优化索引时,只需调整"概念模式-内模式映射"。
1.7、聚簇索引分析
聚簇索引会影响内模式,这是因为聚簇索引决定了数据在物理磁盘上的物理排序方式。一个表只能有一个聚簇索引,因此改变聚簇索引等于改变了数据的物理存储结构(内模式)。
架构决策:在设计高性能数据库时,架构师需要慎重选择聚簇索引键(通常是主键),因为它直接影响 IO 效率和分页存储。
1.8、视图(View)的架构用途
对应"外模式"。架构师常利用视图进行权限隔离 (屏蔽敏感字段)和兼容性过渡(旧系统改造时,用视图模拟旧表结构)。
二、数据库视图技术
2.1、视图结构图
虚拟视图层
基础数据表
提供学生信息
提供课程详情
提供关联关系
学生信息表
学号, 姓名, 性别
课程信息表
课程号, 课程名, 授课老师
选课关系表
学号, 课程号, 成绩
学员选课视图
学号, 课程号, 姓名, 课程名, 成绩
2.2、关系的3种类型
基本关系(通常又称为基本表或基表):实际存在的表,实际存储数据的逻辑表示。
查询表:查询结果对应的表。
视图表 :由基表或其他视图表导出的表,本身不独立存储,数据库只存放它的定义,常称为虚表。
- 它是一个虚拟表(逻辑上的表),其内容由查询定义(仅保存SQL查询语句)。
- 同真实的表一样,视图包含一系列带有名称的列和行数据。
- 但是,视图并没有真正存储这些数据,而是通过查询原始表动态生成所需要的数据。
2.3、物化视图
2.3.1、定义
将视图的内容物理存储起来,其数据随原始表变化,同步更新。
2.3.2、特点
它不是传统意义上虚拟视图,是实体化视图,其本身会存储数据。同时当原始表中的数据更新时,物化视图也会更新。
2.3.3、物化视图的刷新策略
ON COMMIT(实时刷新) :基表提交事务时立即更新视图。数据一致性强,但严重影响写入性能,不适合高并发写场景。
ON DEMAND(按需/定时刷新):通过定时任务或手动触发刷新。适合"T+1"报表或对实时性要求不高的分析系统。
2.4、视图的优点
视图能简化 用户的操作。
视图机制可以使用户以不同的方式查询同一数据。
视图对数据库重构提供了(一定程度的)逻辑独立性。
视图可以对机密的数据提供安全保护。
2.5、普通视图 vs 物化视图
| 特性 | 普通视图 (View) | 物化视图 (Materialized View) |
|---|---|---|
| 存储 | 仅存储 SQL 定义,不占数据空间 | 实际存储数据副本,占用磁盘空间 |
| 查询性能 | 较差(每次实时执行复杂 Join/聚合) | 极高(直接读取预计算结果,以空间换时间) |
| 更新成本 | 无(直接写基表) | 高(基表更新时,需同步刷新物化视图) |
| 适用场景 | 简化复杂查询、权限隔离(屏蔽列) | OLAP场景、数据仓库、复杂的报表聚合统计 |
2.6、视图实现"逻辑独立性"
场景 :假设系统演进,需要将一张臃肿的 User 表拆分为 User_Basic 和 User_Profile 两张表。
方案 :为了不修改成百上千个旧的应用程序,架构师可以在数据库层创建一个名为 User 的视图,将那两张新表 Join 起来。
效果 :应用程序仍然查的是 User,感知不到底层表结构的变化。这就是课件中提到的"逻辑独立性"。
2.7、安全架构设计
行级安全 :通过视图 WHERE Department = 'IT',只开放IT部门数据给IT经理。
列级安全 :通过视图只 SELECT Name, Email 而不包含 Salary 字段,对普通员工隐藏薪资敏感信息。
三、数据库索引原理与优化
3.1、索引的核心作用
正面效应 :提升查询效率。
负面效应 :降低添加、修改、删除效率(因为数据变更时,需要同步维护索引结构的排序和指针)。
3.2、常用算法
采用 B树 、B+树 等数据结构。
3.3、映射机制
索引表中存储"关键码(Key)"与"记录指针(Pointer)",指针指向数据表中具体的物理存储位置。
索引表 (B+树逻辑有序)
原始数据表 (物理存储可能乱序)
记录指针
记录指针
记录指针
记录指针
Row: 001 | 张三 | 男
Row: 102 | 李四 | 女
Row: 008 | 王五 | 男
Row: 007 | 赵六 | 男
...
Key: 001 | Ptr
Key: 007 | Ptr
Key: 008 | Ptr
Key: 102 | Ptr
...
3.4、B+ 树 (主流选择)
特点:非叶子节点只存储Key(不存Data),所有数据都存储在叶子节点,且叶子节点之间有指针连接形成链表。
架构优势:
1)磁盘读写代价更低:节点不存数据,一次IO能读入更多索引Key。
2)查询稳定性好:所有查询都要走到叶子节点,路径长度一致。
3)天然支持范围查询 :这是相比B树和Hash最大的优势,适合 BETWEEN、>、< 等操作。
3.5、Hash 索引
特点:基于哈希表,查找复杂度 O(1)。
架构限制 :不支持范围查询 ,不支持排序,存在哈希冲突。仅适用于精确匹配(=)场景(如 Redis Key-Value)。
3.6、聚簇索引 vs 非聚簇索引
3.6.1、聚簇索引(Clustered Index)
定义 :索引的叶子节点就是数据节点。数据行按索引键的顺序物理存储。
架构点:一张表只能有一个聚簇索引(通常是主键)。查询效率最高,因为不用"回表"。
3.6.2、非聚簇索引(辅助索引)
定义 :索引的叶子节点存储的是主键的值(或行指针)。
回表问题:如果查询需要的数据不在索引列中,数据库需要先查辅助索引拿到主键,再通过主键去查聚簇索引获取完整数据,这叫"回表"。
优化策略 :覆盖索引(Covering Index) 。架构师设计SQL时,应尽量让 SELECT 的字段包含在索引中,避免回表。
3.7、索引失效与优化原则
最左前缀原则 :对于组合索引 (a, b, c),查询 a=1 AND b=2 走索引,但 b=2 AND c=3 不走索引。
函数运算失效 :WHERE YEAR(date_col) = 2026 会导致全表扫描,应改为范围查询。
模糊查询 :LIKE '%abc'(前置百分号)会导致索引失效。
选择性(Cardinality) :区分度低的字段(如"性别"、"状态")不适合建索引。
3.8、架构设计决策
写多读少场景:慎用索引,或者使用 LSM-Tree 结构的数据库(如 HBase, Cassandra)代替传统 B+ 树数据库,因为 LSM-Tree 将随机写转换为顺序写。
大宽表优化:当表字段非常多时,考虑垂直分表,将常查询的列和索引放在主表,低频大字段放在附表,减小索引树的大小。
四、分布式数据库
4.1、分布式数据库参考架构模型
局部级 DBMS
分布式扩展层
全局级 DBMS
映像2: 定义如何切割
映像3: 定义存放位置
映像4: 异构转换
全局外模式
全局概念模式
分片模式
分布模式
局部概念模式
局部内模式
局部数据库
4.2、数据分片策略示意图
列切分
行切分
水平分片: 按记录拆分
分片1: ID 1-1000
分片2: ID 1001-2000
分片3: ID 2001-3000
垂直分片: 按字段拆分
表A: 字段1, 字段2
表B: 字段3, 字段4
原始大表
4.3、分布式数据库透明性分类
分片透明 :用户不必关心数据分不分片,怎么分片 。是最高层次 的透明性。用户写 SQL SELECT * FROM User,完全不知道底层分了10张表还是100张表。
位置透明 :用户不必关心数据存放在何处。用户知道分片了,但不知道分片在北京机房还是上海机房。
复制透明 :用户不必关心各个节点数据的复制与同步更新。
逻辑透明(局部映像透明) :用户不必关心局部DBMS支持哪种数据模型、使用哪种语言 。这是最低层次 的透明性。它解决了异构数据库的问题(例如全局是关系型,局部有一个节点是 Oracle,另一个是 MySQL,系统自动转换 SQL 方言)。
4.4、数据分片原则与方式
4.4.1、分片原则
完整性:所有数据必须在某个分片中出现。
重构性:分片后的数据必须能还原。
不相交性:同一个数据(除主键外)不应在多个分片重复出现(针对水平分片)。
4.4.2、分片方式
4.4.2.1、水平分片
按记录分(行切分)。解决数据量大、单表性能瓶颈问题。常用策略:Hash取模、范围分片(Range)、目录映射。
4.4.2.2、垂直分片
按字段分(列切分)。解决单行数据过宽、IO 争用问题。
策略 :将"冷热数据分离"。例如:商品表中,Name, Price(高频查询)放在主表,Description(大文本、低频)放在扩展表。
混合分片。
4.5、分布式数据库架构
4.5.1、核心特性
分布性、自治性、共享性、可用性。
4.5.2、层级结构(从上至下)
全局外模式
全局概念模式
分片模式(增加的)
分布模式(增加的)
局部概念模式
局部内模式
局部数据库
4.5.3、对应映射
映像1:全局外模式 - 全局概念模式
映像2:全局概念模式 - 分片模式
映像3:分片模式 - 分布模式
映像4:分布模式 - 局部概念模式
4.6、分片模式 vs 分布模式
4.6.1、分片模式
解决"怎么分"的问题。
定义:定义全局数据如何逻辑切割(如:ID 1-1000 切一片,1001-2000 切一片)。
架构思考:这里不涉及物理地址,只涉及逻辑切割规则。
4.6.2、分布模式
解决"放在哪"的问题。
定义:定义逻辑切片具体存储在哪个物理节点(Node A, Node B)。
架构思考:这是实现"位置透明"的关键层。
4.7、分布式事务与 CAP 理论
2PC (两阶段提交):为了保证分布模式下多个局部数据库的数据一致性,通常采用 XA 协议/2PC。
CAP / BASE :在分布式设计中,通常为了可用性 (A) 和 分区容错性 § ,会牺牲强 一致性 © ,转而追求 最终一致性。
五、分库、分表与分区策略
5.1、数据库扩展演进图
分表: 水平拆分
分库: 垂直拆分
业务拆分
逻辑拆分
存储拆分
分区: 物理拆分
逻辑表: 用户表
文件A
文件B
文件C
完整数据库
用户库
商品库
国内用户表
国外用户表
分库 :完整数据库 →\rightarrow→ 用户库 + 商品库(垂直拆分)。
分表 :用户表 →\rightarrow→ 国内用户表 + 国外用户表(水平拆分,物理表变多)。
分区 :用户表 →\rightarrow→ 逻辑仍为一个表,底层物理存储文件分开。
5.2、三种分区策略逻辑图
哈希分区 Hash
Res=0
Res=1
Res=2
Key mod 3
分区0: 余数为0
分区1: 余数为1
分区2: 余数为2
列表分区 List
Loc=长沙
Loc=上海
判断地域
分区1: 长沙
分区2: 上海
分区3: 北京
范围分区 Range
ID=300
ID=6000
ID=99999
判断 ID 范围
分区1: ID < 5000
分区2: ID < 10000
分区3: 其他
输入数据流
5.3、分区策略对比
| 分区策略 | 分区方式 | 典型示例 | 数据管理 | 数据分布 | 适用场景 |
|---|---|---|---|---|---|
| 范围分区 (RANGE) | 按数据范围值来作分区 | 按用户编号:0-999999映射到A区;1000000-1999999映射到B区。 或者按年份/日期。 | 能力强 (易于归档) | 不均匀 (可能存在热点) | 周期性数据、流水记录 |
| 列表分区 (LIST) | 根据某字段的某个具体值进行分区 | 长沙用户分一个区,北京用户分一个区。 | 能力强 | 不均匀 | 单属性、离散值 (如地域、部门) |
| 散列分区 (HASH) | 通过对key进行hash运算分区 | Key mod 3。余数相同的,放在一个分区上。 |
能力弱 | 均匀 | 静态数据、这就负载均衡 |
5.4、分区的优点
相对于单个文件系统或是硬盘,分区可以存储更多的数据。
数据管理比较方便 ,比如要清理或废弃某年的数据,就可以直接删除该日期的分区数据即可(DROP PARTITION 比 DELETE 快得多)。
精准定位 分区查询数据,不需要全表扫描查询,大大提高数据检索效率(分区剪枝)。
可跨多个分区磁盘查询 ,来提高查询的吞吐量(I/O 并行)。
在涉及聚合函数查询时,可以很容易进行数据的合并。
5.5、分区 vs 分表
| 维度 | 分区 (Partition) | 分表 (Sharding/Table Split) |
|---|---|---|
| 共性 | 1. 都针对数据表 2. 都使用了分布式存储 3. 都提升了查询效率 4. 都降低了数据库的频繁I/O压力值 | (同左) |
| 差异 | 逻辑上还是一张表 (SQL无需修改) | 逻辑上已是多张表 (需要修改SQL或使用中间件路由) |
5.6、垂直分库
原理:按业务模块拆分。例如电商系统拆分为"用户库"、"订单库"、"库存库"。
解决问题:缓解单机连接数瓶颈,各业务资源隔离。
架构代价 :无法跨库 Join (需要通过接口调用),分布式事务问题(需要 2PC/TCC/Seata)。
5.7、水平分表
原理 :当单表数据量达到瓶颈(如 MySQL 单表超 2000万行),按 ID 取模或按时间将数据分散到多个结构相同的表中(Order_01, Order_02...)。
解决问题:解决单表查询慢、写入锁竞争问题。
架构代价 :ID 生成策略 (不能用自增主键,需用 Snowflake 等),跨表分页查询困难。
5.8、策略选型指南
5.8.1、什么时候用 Hash?
当数据没有明显的时间特征,且希望数据绝对均匀分布,防止某些节点被打爆(数据热点)时。
架构坑点 :扩容困难。一旦节点从 3 变 4,mod 3 变成 mod 4,会导致所有数据迁移。解决方案:一致性 Hash 算法(Consistent Hashing)。
5.8.2、什么时候用 Range?
当业务包含"历史归档"需求时。例如日志表,按月分区。过期直接 Drop Partition,毫秒级释放空间。
架构坑点 :数据热点。例如"双11"当月的订单量是其他月份的10倍,导致该分区所在的磁盘 IO 爆满。
5.9、中间件生态
ShardingSphere (Sharding-JDBC, Sharding-Proxy):Java 生态最主流,Apache 顶级项目。
MyCat:基于 Proxy 模式的数据库中间件。
Vitess:YouTube 开源的,云原生友好。
六、数据库设计过程
6.1、数据库设计的四个核心阶段
6.1.1、阶段一:需求分析
输入:当前和未来应用的数据要求。
产出 :数据流图 (DFD) 、数据字典 (DD)、需求说明书。
核心任务:分析用户对数据的处理要求。
6.1.2、阶段二:概念结构设计
输入:需求分析的结果。
产出 :ER模型(实体-联系图)。
特点 :这是用户的概念模型,即与 DBMS 无关的概念模型。
6.1.3、阶段三:逻辑结构设计
输入 :ER 模型 + 转换规则 + 规范化理论。
产出 :关系模式 (即:二维表,例如 学生[学号, 姓名...])、视图、完整性约束及应用处理说明书。
特别注明 :关系模式的规范化与反规范化都属于逻辑结构设计的任务。
6.1.4、阶段四:物理设计
输入 :逻辑结构 + DBMS特性 + 硬件、OS特性。
产出:物理数据库结构(存储结构、索引、存放路径等)。
6.2、各阶段核心产出物
| 设计阶段 | 核心产出/关键词 | 架构师视角理解 |
|---|---|---|
| 需求分析 | 数据流图 (DFD) 、数据字典 (DD) | 搞清楚业务流程,数据从哪来、到哪去。数据字典是元数据的基础。 |
| 概念设计 | E-R 图 (Entity-Relationship) | 平台无关性。不管底层是用 MySQL 还是 Oracle,ER 图都是一样的。它是业务和技术的桥梁。 |
| 逻辑设计 | 关系模式 、规范化 、反规范化 | 平台相关性开始介入(针对关系型数据库)。核心是将 ER 图转换为表结构,并解决多对多关系拆分问题。 |
| 物理设计 | 索引 、分区 、存储过程 、RAID选型 | 针对具体机器优化性能。例如:决定是否建立 B+ 树索引,决定数据文件存在哪个磁盘分区。 |
6.3、数据库设计过程图
与DBMS无关
规范化/反规范化
当前和未来应用的数据要求
数据处理要求
转换规则/规范化理论
DBMS特性/硬件/OS特性
需求分析
概念结构设计
逻辑结构设计
物理设计
数据流图 DFD / 数据字典 DD
ER模型 / 实体-联系
关系模式 / 二维表 / 视图
物理数据库结构
6.4、ER 图转关系模式
1:1 关系:可以合并到任意一端,通常合并到访问频率高的一端。
1:n 关系:必须将"1"端的主键加入到"n"端作为外键。
m:n 关系 :必须生成一个新的关系模式(中间表),该表的主键是两端主键的组合。
6.5、规范化 vs 反规范化
规范化 (Normalization):目的是消除冗余,解决插入/删除异常(如 3NF)。
反规范化 (De-normalization) :目的是提升查询性能(架构师常用手段)。例如,为了避免 3 张大表 Join,故意在订单表中冗余"用户名"字段。这个决策是在设计表结构(逻辑设计)时做的。
6.6、数据字典 (DD) 的地位
虽然 DFD 属于系统分析师的重点,但 DD (Data Dictionary) 是数据库设计的基石。它定义了数据的名称、类型、长度、取值范围等约束,是后续建表的直接依据。
七、数据库概念结构设计(E-R图集成)
7.1、概念结构设计的详细流程
概念结构设计阶段
核心任务: 消除冲突
核心任务: 消除冗余
需求分析
逻辑设计
抽象数据
设计局部 ER 模型
合并局部模型
重构优化
冲突类型:
-
属性冲突
-
命名冲突
-
结构冲突
7.2、概念结构设计核心流程
输入:需求分析。
步骤1:抽象数据。
步骤2:设计局部 E-R 模型。
步骤3:合并局部模型。
- 核心任务 :消除冲突。
步骤4:重构优化。
- 核心任务 :消除冗余。
输出:逻辑设计。
7.3、集成的方法
一次集成:多个局部 E-R 图一次性集成。
逐步集成:用累加的方式一次集成两个局部 E-R。
7.4、集成产生的冲突及解决办法
属性冲突:包括属性域冲突和属性取值冲突。【针对同一对象】
命名冲突:包括同名异义(Homonym)和异名同义(Synonym)。【针对同一对象】
结构冲突:包括同一对象在不同应用中具有不同的抽象,以及同一实体在不同局部 E-R 图中所包含的属性个数和属性排列次序不完全相同。
| 冲突类型 | 详细解释 | 典型案例 | 解决策略 |
|---|---|---|---|
| 属性冲突 | 数据类型、长度、单位或取值范围不一致。 | 1. 某属性在A部门是 int,在B部门是 char。 2. 重量在仓库用 kg,在物流用 lb。 |
统一格式。通常以范围大、精度高的为准。 |
| 命名冲突 | 语言上的歧义。 | 1. 同名异义 :都叫"项目",科研处指"课题",教务处指"课程设计"。 2. 异名同义:科研处叫"课题",财务处叫"成本中心"。 | 规范命名。建立标准的数据字典,统一术语。 |
| 结构冲突 | 抽象级别的差异(最难处理)。 | 1. "部门"在A系统是实体 ,在B系统被当作属性。 2. 两个"职工"实体,属性列表不同(一个有职称,一个没职称)。 | 统一抽象 。通常将属性升级为实体(Entity)。变换为统一的结构。 |
7.5、重构优化中的消除冗余
在合并完ER图后,可能会发现某些数据是可推导的。
示例:如果ER图中有了"出生日期",又有一个属性叫"年龄",这就是冗余。
架构决策 :在概念设计阶段,通常建议消除 这些冗余以保持模型精简;但在逻辑设计或物理设计阶段,为了性能,架构师可能会选择保留冗余(反规范化)。
7.6、E-R 图设计的策略
自底向上:先画局部(部门级),再画全局(企业级)。
自顶向下:先画全局核心实体,再细化属性。
逐步扩张:先画核心业务,像滚雪球一样添加新业务。
八、数据库逻辑结构设计
8.1、逻辑结构设计的内部处理流程图
逻辑结构设计
概念设计
物理设计
转化为数据模型
关系规范化
模式优化
设计用户子模式
E-R图转关系模式
确定完整性约束
确定用户视图
8.2、逻辑结构设计核心流程
1)转化为数据模型:将E-R图转化为关系模式。
2)关系规范化:优化数据结构,消除异常。
3)模式优化:调整性能。
4)设计用户子模式:定义外模式。
8.3、核心任务详情
E-R图向关系模式的转换:包含"实体向关系模式的转换"和"联系向关系模式的转换"。
关系模式的规范化:基于规范化理论(范式)。
确定完整性约束:为了保证数据的正确性。
用户视图的确定:
- 目的:提高数据的安全性和独立性。
- 依据:根据数据流图确定处理过程使用的视图;根据用户类别确定不同用户使用的视图。
应用程序设计。
8.4、完整性约束
实体完整性约束 :规定基本关系的主属性不能取空值 (即主键不能为空)。保证了数据行的唯一性 和可标识性。类似于"身份证号不能丢,也不能重"。
参照完整性约束 :关系与关系间的引用,其他关系的主键或空值(即外键约束)。保证了数据之间的逻辑一致性。例如:"在成绩表中出现的学号,必须在学生表中真实存在"。如果学生退学删除了,成绩表里的记录要么级联删除,要么置空,不能悬空。
用户自定义完整性约束 :由应用环境决定 (如:年龄必须>0,性别只能是男/女)。约束(Constraint)是声明式的,性能更好,适合通用检查。
触发器(Trigger) :一种特殊的存储过程,用于强制执行复杂的业务规则。触发器 (Trigger)是过程式的(PL/SQL),功能更强但维护成本高,可能会隐式影响性能。架构设计时,尽量优先使用约束。
8.5、E-R 图转关系模式
1:1 联系 :不需要单独建表。可以将联系合并到任意一端的实体表中,并将另一端的主键加入该表作为外键。
1:n 联系:不需要单独建表。必须将"1"端的主键加入到**"n"端**的实体表中作为外键。
m:n 联系 :必须单独建成一个关系模式(新表)。该表的主键 = 两端实体主键的组合。
多元联系(三个实体以上):通常也需要单独转换成一个关系模式。
九、关系代数
9.1、关系的基础概念
垂直方向 :称为属性列 。属性的个数称为**"目"或"度"**(Degree)。
水平方向 :称为元组 、行 、记录。元组的个数称为**"基数"**(Cardinality)或实例。
9.2、两个示例关系
关系 S1:
- 包含数据:
{ (No0001, 张三), (No0003, 李四), (No0004, 王五) }
关系 S2:
- 包含数据:
{ (No0001, 张三), (No0008, 赵六), (No0021, 钱七) }
前提条件 :S1 和 S2 必须同构(即:属性数目相同,对应属性域相同),才能进行集合运算。
9.3、三种集合运算
9.3.1、并 (Union, S1∪S2S1 \cup S2S1∪S2)
定义 :属于 S1 或 属于 S2 的元组组成的集合。
结果 :{ No0001, No0003, No0004, No0008, No0021 } (共5条,自动去重)。
9.3.2、交 (Intersection, S1∩S2S1 \cap S2S1∩S2)
定义 :既属于 S1 又 属于 S2 的元组组成的集合。
结果 :{ No0001 } (共1条)。
9.3.3、差 (Difference, S1−S2S1 - S2S1−S2)
定义 :属于 S1 但不属于 S2 的元组组成的集合。
结果 :{ No0003, No0004 } (共2条)。
9.3.4、图示
运算结果
集合运算
输入关系
关系 S1
No0001, No0003, No0004
关系 S2
No0001, No0008, No0021
并集 Union
交集 Intersect
差集 Difference
S1 U S2
No0001, No0003, No0004, No0008, No0021
S1 n S2
No0001
S1 - S2
No0003, No0004
9.4、SQL 映射与性能优化
9.4.1、Union vs Union All
∪\cup∪ (Union) 对应 SQL 的 UNION。性能开销大 ,因为数据库需要执行排序或哈希操作来去重。
如果业务确认两个数据集没有重复项,架构师应优先设计使用 UNION ALL,直接追加数据,性能极高。
9.4.2、Difference 的实现
对应 SQL 的 EXCEPT (SQL Server/PG) 或 MINUS (Oracle)。
MySQL 不支持 EXCEPT,架构师需要用 LEFT JOIN ... WHERE ... IS NULL 或 NOT IN 来替代实现。
9.6、投影 (π\piπ, Projection)
定义 :选择特定的列(垂直方向截取)。
对应 SQL :SELECT 列名。
示例 :π学号,姓名(S1)\pi_{学号, 姓名}(S1)π学号,姓名(S1) →\rightarrow→ 只保留 S1 表中的"学号"和"姓名"两列。
9.7、选择 (σ\sigmaσ, Selection)
定义 :选择特定的行(水平方向截取)。
对应 SQL :WHERE 条件。
示例 :σ学号=′No0003′(S1)\sigma_{学号='No0003'}(S1)σ学号=′No0003′(S1) →\rightarrow→ 找出学号为 No0003 的那一行记录。
9.8、笛卡尔积 (×\times×, Cartesian Product)
定义:两个关系的所有元组进行"全排列"组合。所有列保留,所有行全映射。
结果规模:
- 属性列数(度) = 关系R的列数 + 关系S的列数。
- 元组行数(基数) = 关系R的行数 ×\times× 关系S的行数。
笛卡尔积 是所有连接运算的基础,但也是性能杀手。
9.9、自然连接 (⋈\bowtie⋈, Natural Join)
定义 :特殊的等值连接。要求两个关系中进行比较的分量必须是同名的属性组 ,并且在结果中去掉重复的属性列。
计算步骤:
- 计算笛卡尔积 (S1×S2S1 \times S2S1×S2)。
- 选择 (σ\sigmaσ) :筛选出同名属性值相等(S1.学号=S2.学号S1.学号 = S2.学号S1.学号=S2.学号)的行。
- 投影 (π\piπ):去掉重复的列(只保留一个"学号"列)。
9.10、查询优化
9.10.1、核心原则
选择(Selection)和投影(Projection)尽早做!
9.10.2、选择下推
在做笛卡尔积或连接之前,先把表中不符合条件的行过滤掉。
优化前 :σAge>20(A×B)\sigma_{Age>20}(A \times B)σAge>20(A×B) →\rightarrow→ 先生成巨大的中间表,再过滤。
优化后 :(σAge>20(A))×B(\sigma_{Age>20}(A)) \times B(σAge>20(A))×B →\rightarrow→ 参与连接的数据量大大减少。
9.10.3、投影下推
在扫描表时,只取需要的列。这在使用列式存储(如 ClickHouse, HBase)时性能提升尤为明显。
9.11、关系代数全图
自然连接 Natural Join
笛卡尔积 Cartesian Product
输入数据
关系 S1 (3行)
关系 S2 (3行)
S1 x S2
行数 = 3 * 3 = 9行
列数 = 3 + 2 = 5列
包含冗余列: S1.学号, S2.学号
Filter: S1.学号 == S2.学号
Project: 去除重复列 S2.学号
结果集
等价公式: π σ (S1 x S2)