跳到主要内容

数据键、函数依赖与规范化

各种键如何标识一条记录?​

术语精确定义
超键足以唯一标识记录的属性集合,可以包含多余属性
候选键不含多余属性的最小超键
主键被选作主要标识的候选键
备用键未被选为主键的其他候选键
复合键由多个属性组合而成的键
外键引用另一关系中受唯一性约束的键,也可自引用
代理键系统生成、通常不承载业务含义的标识
  • 原文修正: 非主键列不都叫备用键;“所有键的集合”也不是超键的定义;

函数依赖怎样暴露重复事实?​

  • 函数依赖: 若 X 的值相同就必然决定相同的 Y,记作 X → Y,表达的是业务约束而非偶然数据现象;
  • 部分依赖: 非主属性只依赖某个复合候选键的一部分,而不是整个键;
  • 传递依赖: 通过中间属性间接决定另一属性,例如员工决定部门、部门决定部门电话;
  • 原文修正: “主键决定其他属性”本身并不叫部分依赖,关键是只依赖复合键的真子集;

冗余数据为何产生插入、更新和删除异常?​

  • 插入异常: 想保存一种事实却被迫提供尚不存在的另一种事实,例如员工和团队强绑导致未分组员工无法录入;
  • 更新异常: 同一事实重复多行,修改时漏掉一行就出现矛盾,例如同一个人的角色在多行不一致;
  • 删除异常: 删除最后一条关联记录时连带丢失独立事实,例如删除团队记录同时丢掉成员资料;
  • 判断条件: 异常取决于实际键与非空等约束,不能只凭某个表里出现重复名字就认定是同一个人;

范式如何约束依赖关系?​

范式核心要求
1NF属性值在所选模型中不可再拆为重复组,记录结构明确
2NF满足 1NF,非主属性完全依赖每个候选键
3NF每个非平凡依赖 X→A 中,X 是超键或 A 是主属性
BCNF每个非平凡函数依赖的决定项都是超键
  • 常见理解: 3NF 通常用于消除非键属性经由其他非键属性产生的传递依赖,正式定义还能处理多个候选键;
  • BCNF: 比 3NF 更严格,原文也称 3.5NF,重点是决定项必须能唯一标识记录;
  • 更高范式: 4NF、5NF、6NF 属于原文列出的延伸主题,本文不把未展开内容伪装成已覆盖知识;
  • 收益: 减少冗余、强化参照完整性并让结构更清楚,代价是建模、联接与维护工作;

反规范化如何换取读性能?​

  • 反规范化: 为明确的查询路径有意保存派生或冗余数据,减少联接与跨节点取数;
  • 适用条件: 已找到高成本读取,并能说明每份冗余数据由谁生成、何时更新及如何修复;
  • 代价: 增加空间与写入成本,部分更新失败会造成不一致,读查询更简单不等于系统总维护更简单;
  • 原则: 先理解正确的数据关系,再有意识加入冗余;它不是取消所有规范化规则;

如何把重复事实拆成明确的关系?​

  • 示例: 若员工所在部门决定部门电话,把部门电话移到以部门为键的表,员工只引用部门,更新电话就不必修改每个员工行;
  • 连接要求: 分解后应能无损恢复需要的关系,不能为了去重把本来不同的事实错误合并;
  • 实施检查: 确认外键、唯一性与非空要求表达真实业务规则,再用代表性查询检查联接成本;