数据库范式

范式

数据库设计的⼀套要求。
要求要说满⾜,所以有“满⾜第⼏范式”。

⽬的

消除数据冗余。即,做到同样的数据不存第⼆遍。

惯例

现在数据库设计最多满⾜3NF,普遍认为范式过⾼,虽然具有对数据关系更好的约束性,但也导致数据关系表增加⽽令数据库 I/O 更易

繁忙,原来交由数据库处理的关系约束现更多在数据库使⽤程序中完成。
( 参考:https://zh.wikipedia.org/wiki/数据库规范化 )

“三范式”虽然有⽤,但仍然要具体问题、具体分析,该打破打破。

套路


问题⼀:如何解决 “两条记录完全重复”?

学号 姓名 年龄
20125112 张三 22
20125113 李四 21
20125112 张三 22

法1:加主键,要求主键不能重复。

「第⼀范式要求:1.要有主键」

法2:设计⼀张只有⼀个字段的表。(字段名info,字符串型)

info
20125112_张三_22

这样就不会有重复数据了,但是傻⼦才会这样设计。
这样不便查询年龄等原⼦信息,需全部拿出正则切割。

傻⼦都能设计出满⾜1NF的表格。

「第⼀范式要求:2.列不可分」

  • 例外
    “产品批号”往往以位段藏蕴多层信息,却不必分割保存,只作为⼀个⾃然单位。

  • 注意
    列不可分,却也不能重复。

    1. 两个字段都是“年龄”
    2. “出⽣年⽉”与“年龄”。
  • 灵活
    有些故意存在的冗余是为了程序好写。


问题⼆:设计“多对多”关系表时有哪些注意?

学⽣选课表。
学号、学⽣姓名、⼯号、教师姓名。
学⽣姓名、⽼师姓名冗余。若觉还好,那同时再有“教师简介”字段呢?
如何解决冗余?

  • 思路
    表要有主键,思考主键担当。
    学号可以重复,不能担当主键。
    学号和教师编号⼀起,担当“组合主键”
    于是,该表就不合2NF了。

「第⼆范式要求:当⼀张表有多个字段作为“组合主键”时,不是主键的那些字段,不能够依赖于“组合主键”的一部分(“部分主

键”)。」

⽩话⽂:
某些字段不能依赖于⼀部分主键,⽽要依赖于整个主键的组合。
叫,不能存在“部分依赖”。
(字段不能部分依赖于主键 → 翻译成人话字段不能依赖于部分主键
(有组合主键,才谈得上部分依赖)

如,学⽣姓名依赖于学号,学号不是主键,学号是主键的⼀部分。
这叫“部分依赖”,会产⽣数据冗余。

  • 对策
    拆表。

    • 学⽣表(id学号,学⽣姓名)
    • 教师表(id⼯号,教师姓名)
    • 关系表(学号,⼯号)
  • 检索
    表连接。


问题三:Student (id学号, 姓名, 年龄, 性别, 系别, 系办地址, 系办电话) 有啥问题?

  • 概念
    a→b 意为 a决定b,b依赖a

  • 可知
    (学号)→ (姓名,年龄,性别,系别,系办地址,系办电话)
    却⼜:
    (学号)→ (系别)→(系办地点,系办电话)
    于是,该表就不合3NF了。

「第三范式要求:不是主键的这些字段必须“直接依赖”于主键。」

⽩话⽂:
某些字段除了依赖主键,不能还可以依赖于不是主键的字段。
叫,不能存在“传递依赖”。
(主键字段 → ⾮主键字段x → ⾮主键字段y)
(直接依赖于的字段,就是紧贴在前的决定字段)
(直接依赖,对应的是传递依赖)
如,系办地点、系办电话直接依赖于系别,系别直接依赖于学号。这叫,系办地点、系办电话“传递依赖”于学号,会产⽣数据冗余。

  • 对策
    拆表。

  • 学⽣(id学号,姓名,年龄,性别,系别)

  • 系别(id系别,系办地址,系办电话)

  • 检索
    表连接。


以下可略:BCNF范式

「BCNF范式的要求:不存在主键字段决定主键字段的情况。」

  • 对策
    将主键中能“⼀对⼀”的关系,拆出来另建表存。
  • 仓库管理关系表(仓库ID, 存储物品ID, 管理员ID, 数量)

⼀个管理员只在⼀个仓库⼯作。⼀个仓库可以存储多种物品。

  • 可知
    (仓库ID, 存储物品ID) → (管理员ID, 数量)
    (管理员ID, 存储物品ID) → (仓库ID, 数量)
    却⼜:
    (仓库ID) → (管理员ID)
    (管理员ID) → (仓库ID)

参考:数据库范式1NF 2NF 3NF BCNF实例分解
http://blog.csdn.net/fpf_721521/article/details/548927

你可能感兴趣的:(数据库范式)