关于数据库范式的内容这里均不提供标准定义,只记录我自己的理解。如果想看标准定义请google一下或者去翻数据库课本。

数据库范式

指的是数据库满足的某些规范,这里主要说明BCNF、2NF和3NF。

下面这张图来自wiki,说明了范式之间谁更严格谁更宽松的关系。

NormalForm

BCNF

Boyce-Codd Normal Form

对于数据库中任意一个表T,F是其上的函数依赖集。如果对于任意F+(F的闭包)中右侧单值的有意义(指这个函数依赖的左边不包含右边)的函数依赖的左边属性集都是超键。

换句话说,能够控制任意一个其他单一属性的属性集就能控制整个表。如果有例外就不满足BCNF,没有例外就满足。

3NF

对于数据库中任意一个表T,F是其上的函数依赖集。对于任意一个能从F中推出的函数依赖FD:X->A,如果A是单一非主属性,且不在X中,则X是T的超键。没有例外就满足3NF。

非主属性指的是没有出现在任何一个候选键里的属性。

换句话说,能控制单一非主属性的属性集就能控制整张表。没有例外就满足3NF。

BCNF比3NF更严格,因此说只要满足BCNF那就一定满足3NF。

得到3NF分解的算法

有一个不满足3NF的表,其上有函数依赖集F。那么可以通过以下步骤得到一个无损3NF分解:

  1. 用F的最小覆盖替换F
  2. 将F中的每个函数依赖左边和右边的属性集并起来,组成一个小表。小表的数量应该和F中函数依赖个数一样。
  3. 删去被其他表包含的小表。
  4. 如果任何一个表都没包含F的一个候选键,那就随便挑一个候选键组成一个表。

这样得到的所有表就是之前表的一个3NF无损分解了。

2NF

对于数据库中任意一个表T,F是其上的函数依赖集。对任意一个能从F推出的FD:X->A,A为单一非主属性且不在X中,则X不是T任一候选键的真子集。换句话说,第二范式要求每个非主属性完全依赖于某个候选键,而不是依赖于候选键的一部分属性。

如果满足2NF,一定满足3NF。因为X不是T候选键的真子集,除了可能确实包含T之外(这种情况是满足3NF的),还有可能只是和T有交集。