核心而言,数据库规范化(亦称数据规范化)助力企业与机构更高效地组织、查询和维护海量的、复杂的、相互关联的动态数据。尽管当今企业数据生成存储规模空前,规范化需求并非新事物。其历史早于云存储乃至数据仓库的诞生。
自 20 世纪 60 年代起,企业便持续面临海量数据集管理挑战。20 世纪 70 年代,IBM 数学家 Edgar F. Codd——以其介绍关系型数据库的开创性论文闻名——指出:数据库规范化可规避属性(列)间的“不良” 依赖关系及其可能引发的问题。
换言之,当数据库结构中数据记录相互关联时,对庞大复杂表中单值或单行的修改可能引发非预期后果(如数据不一致性及数据丢失)。数据库规范化正是为最小化此类风险而设计。
数据库规范化的优点包括:
将庞大复杂的表分解(或划分)为更小、更简单的表后:数据库修改更简易、操作错误率降低、变更范围限于关联数据子表。
规范化减少数据冗余也能加快数据查询速度,因为冗余降低通常意味着搜索过程中需要处理的数据量减少。
数据结构规范化可预防三类关键异常:
插入异常:插入异常指因数据记录缺少表中某列或多列的必要值而无法插入表格的情况。
删除异常:删除异常指删除记录时意外丢失该记录中包含的重要数据的现象。
更新异常:更新异常则发生在数据库中某处数据实例被更新,但存储相同数据的其他位置未同步更新,导致数据不一致的情形。
由两列或以上组成的键称为复合键。当主键由多列构成时,可称为复合主键。
候选键是具备主键特性但尚未被指定为主键的列或列组合。
一个表中的外键引用另一个表中的特定主键,以定义表之间的关系。在规范化过程中将大表拆分为小表时,外键与主键共同建立新表间的关联关系。
超键虽与复合主键类似,但包含超出唯一标识记录所需的多余列。
数据库规范化的若干约束建立在主键与既非主键也非候选键的列之间的关系(也称为依赖关系)之上。后者被称为非键属性。
数据库中一个属性(决定因子)决定另一个属性值的关系称为函数依赖关系。属性间的函数依赖类型包括:部分依赖、传递依赖、多值依赖和连接依赖。在讨论相关规范化规则集(即范式)的语境下,最能清晰地理解这些关系。
在数据模型中执行规范化涉及设计符合一个或多个规范化级别的表,这些级别也称为范式。常见范式包括:
第一范式是最基本的数据库规范化标准,要求数据库表模式包含主键,同时排除列之间的重复。具体地说,一个满足第一范式的表不应包含包含数组的字段(或多值字段)(例如,单个单元格中包含三个不同的姓名),也不应包含重复组(即存储同类型数据的不同列)。
深入理解第一范式:以下列表示例说明:1
rec_num | lname | fname | bdate | anniv | child1 | child2 | child3 |
该列集合构成记录父母信息的表,包含姓名、生日、结婚纪念日、电子邮箱及子女姓名。
此表违反第一范式,因其存在三个独立列存储同类信息(子女姓名)。这种表结构尤其可能导致插入异常。现实中许多父母的子女数量不足三人。
但在此表结构中无法添加这类父母的记录。此外,若需查询特定子女姓名,需要在每一行中检索三个不同的列,导致查询效率低下。
要使表中数据符合第一范式,需将原表拆分为两个表。一个表保留原表大部分属性,另一个表专门存储子女信息。
表 1
rec_num | lname | fname | bdate | anniv |
表 2
rec_num child_name
在此例中,新表通过“rec_num”列保持关联——该列是表 1 的主键,同时被表 2 的“rec_num”列(该列作为外键)所引用。
虽然满足第一范式未必减少数据冗余(当父母有多名子女时,“rec_num”值将在表2的多行重复出现),但消除重复组能简化查询操作。
在第二范式中,任何非键属性都不能部分依赖于表的主键。换言之,若主键为复合主键,则非键属性必须依赖于该复合键的所有列。
假设某库存表记录特定仓库存储的零件数量。下图展示该库存实体的属性。2
part | warehouse | quantity | warehouse_address |
在此例中,“part”和“warehouse”列构成一个复合主键(或复合键)。但属性“warehouse_address”仅函数依赖于“warehouse”,因此该表违反第二范式。
此表还存在数据冗余问题——每当同一仓库的零件记录出现时,“warehouse_address”的值都会重复列出。若在某行更新地址而未同步其他行,将导致更新异常风险。删除操作同样可能引发异常:倘若某仓库停止存储零件,如果删除这些零件的记录,仓库地址也会随之被删除。
为实现第二范式并降低错误风险,可将数据分配到两个新表中:
表 1
part | warehouse | quantity |
表 2
warehouse warehouse_address
满足第三范式的表需同时符合第一、第二范式,且避免非键属性不依赖于主键,而是依赖于其他非键属性的情况。当非键属性依赖于其他非键属性时,称为传递依赖——这违反了第三范式。
以员工信息表为例:3
emp_num | emp_fname | emp_lname | dept_num | dept_name |
0200 | David | Brown | D11 | Manufacturing System |
0320 | Ramlal | Mehta | E21 | 软件支持 |
0220 | Jennifer | Lutz | D11 | Manufacturing System |
该表主键为“emp_num”列。但“dept_name”列依赖于非键属性“dept_num”列。因此该表不符合第三范式,存在更新异常等风险(例如若“manufacturing system”部门更名,则需在当前表结构中更新多行数据)。
在规范化数据库中将数据组织为第三范式可避免此类错误。本例需将数据结构拆分为三个独立表:EMPLOYEE、DEPARTMENT 和 EMPLOYEE_DEPARTMENT4
EMPLOYEE 表
emp_num | emp_fname | emp_lname |
0200 | David | Brown |
0320 | Ramlal | Mehta |
0220 | Jennifer | Lutz |
DEPARTMENT 表
dept_num | dept_name |
D11 | Manufacturing System |
E21 | 软件支持 |
EMPLOYEE_DEPARTMENT 表
dept_num | emp_num |
D11 | 0200 |
D11 | 0220 |
E21 | 0320 |
BC 范式 (BCNF) 是第三范式的更严格版本。BCNF 要求使用超键作为依赖依据。
满足第四范式的表不得存在多值依赖。多值依赖发生在两个或更多列的值彼此独立,且仅依赖于主键时。
教程中常见案例涉及同时记录员工技能与语言的表。员工可具备多项技能并掌握多门语言。存在员工-技能和员工-语言两种关系。
若单表同时表示这两种关系,则违反第四范式。需将数据拆分为两个表——员工技能表与员工语言表以满足第四范式。
第五范式通常被视为规范化最高级别,是一个以连接依赖性为核心的标准。当表被拆分为较小表后,可以将新表重新组合以无损地复原原始表——不会丢失任何数据,也不会意外地创建出新的数据行。此过程如同完成拼图后拆解碎片,仍能精准还原为原貌。
仅当连接依赖可实现时,才应将表拆分为更小的表(以满足第五范式)。然而,若试图从小表重组原始表时意外生成了结构存在差异的表,则不应执行原始表的分解。回到拼图的比喻,这就如同将拼图重新拼合后,发现少了一块拼图块,或是神秘地多出了一块额外的拼图块。
尽管优势显著,数据库规范化仍需权衡取舍。例如规范化前,用户查询特定数据可能只需访问单表。而规范化后表数量增加,用户可能需要查询多个表——这可能是一个更慢且计算开销更大的过程。
此外,规范化虽简化单表结构,却可能提升整体数据库复杂度,要求数据库设计者和管理员具备深厚的专业知识,以确保正确实施。
设计数据战略,消除数据孤岛、降低复杂性并提高数据质量,以获得卓越的客户和员工体验。
watsonx.data 支持您通过开放、混合和已治理数据,利用您的所有数据(无论位于何处)来扩展分析和 AI。
通过 IBM® Consulting 发掘企业数据的价值,建立以洞察分析为导向的组织,实现业务优势。
1“第一范式”。IBM 文档,关于 Informix 服务器。2024 年 11 月 19 日。
2,3,4 “数据库设计中 的规范化”。IBM 文档,关于 Db2 for z/OS。2025 年 1 月 22 日。