关系型数据库的三范式

1NF

规定了列的原子性。

  1. 列中不会有类型相同的值。例如下表的color字段存了多个颜色值,不符合原子性:

     +--------+----------+
     | toy_id | color    |
     +--------+----------+
     |      1 | red,blue |
     +--------+----------+
    
  2. 表中不会有相同类型的列。例如下表中有多个存储颜色的字段,也不符合原子性:

     +--------+--------+--------+
     | toy_id | color1 | color2 |
     +--------+--------+--------+
     |      1 | red    | blue   |
     +--------+--------+--------+
    

2NF

规定了非主键和主键的关系。

已符合1NF,满足下列条件之一,则满足2NF:

  1. 主键是单列
  2. 主键是多列,没有部分依赖

部分依赖:非主键列依赖于组合主键的一部分。

例如下面的表保存了哪个孩子拥有哪些玩具的关系(child_id和toy_id形成组合主键),其中玩具的颜色是属于玩具的属性,跟孩子没有关系,属于部分依赖,应该把该字段移到玩具表更恰当:

+----------+--------+-------+
| child_id | toy_id | color |
+----------+--------+-------+
|        1 |      1 | blue  |
+----------+--------+-------+

要满足非部分依赖,就是非主键字段要跟主键完全相关,比如’孩子拥有玩具的时间’这个字段就是跟组合主键完全相关的:

+----------+--------+------------+
| child_id | toy_id | own_date   |
+----------+--------+------------+
|        1 |      1 | 2018-06-26 |
+----------+--------+------------+

3NF

规定了非主键之间的关系。

已符合2NF,没有传递依赖。

传递依赖:非主键列依赖于其他非主键列。比如下面的玩玩具的时长是依赖于拥有时间的,当然实际当中这个时长是通过计算得出的,这儿因为想不到其他可以用来说明的字段,只是举个例子:

+----------+--------+------------+----------+
| child_id | toy_id | own_date   | playtime |
+----------+--------+------------+----------+
|        1 |      1 | 2018-06-26 | 3 years  |
+----------+--------+------------+----------+

说白了,传递依赖就是改变一个非主键列会造成其他列的改变。