关系数据库中的关系必须满足一定的要求。
数据库的 范式 是数据库设计所需要满足的规范。
只有理解数据库的范式,才能设计出高效率、优雅的数据库,否则可能会设计出错误的数据库.
主要有六种范式:
第一范式.
第二范式.
第三范式.
BC范式.
第四范式.
第五范式.
满足最低要求的叫第一范式,简称 1NF . 在第一范式基础上进一步满足一些要求的为第二范式,简称 2NF . 其余依此类推.
范式越高:
优点: 可以避免数据冗余.
缺点: 性能就会越差, 需要联系多个表才能得到所需要数据, 并且操作会 更困难.
权衡利弊, 一般项目会使用 第三范式.
数据冗余小, 且 方便管理.
1NF是关系模式应具备的 最起码的条件,如果数据库设计不能满足第一范式,就不称为关系型数据库.
定义:如果 关系模式R 的每个 关系r 的属性都是不可分的数据项,那么就称R是第一范式的模式.
例如 (学生信息表):
学生编号 | 姓名 | 性别 | 联系方式 |
---|---|---|---|
20080901 | 张三 | 男 | email:zs@126.com,phone:88886666 |
20080902 | 李四 | 女 | email:ls@126.com,phone:66668888 |
以上的表就不符合,第一范式:联系方式字段可以再分.
满足 第一范式(1NF) 的表结构应该如下:
学生编号 | 姓名 | 性别 | 电子邮件 | 电话 |
---|---|---|---|---|
20080901 | 张三 | 男 | zs@126.com | 88886666 |
20080902 | 李四 | 女 | ls@126.com | 66668888 |
第二范式(2NF)
定义:如果 关系模式R 是 1NF,且每个 非主属性 完全函数依赖于 候选键,那么就称R是第二范式.
例如 (产品流水凭证模板表), 产品代码 和 交易类型 是联合 主键:
产品代码 | 交易类型 | 产品名称 | 凭证模板代码 | 差额凭证模板代码 |
---|---|---|---|---|
p1 | 666 | 产品A | t1 | tt1 |
p2 | 777 | 产品B | t2 | tt1 |
p1 | 888 | 产品A | t1 | tt1 |
通过 产品代码 大专栏 第三范式和 交易类型 可以确定 凭证模板代码, 差额凭证模板代码, 产品名称, 所以 可以把 (产品代码, 交易类型) 作为主键.
但是, 产品名称 并不完全 依赖于 (产品代码, 交易类型), 只要 产品代码 就能确定 产品名称, 这种依赖叫 不完全依赖 (或部分依赖).
第二范式 不能有 不完全依赖 .
修改后, 满足第二范式:
产品代码 | 交易类型 | 凭证模板代码 | 差额凭证模板代码 |
---|---|---|---|
p1 | 666 | t1 | tt1 |
p2 | 777 | t2 | tt1 |
p1 | 888 | t1 | tt1 |
产品代码 | 产品名称 |
---|---|
p1 | 产品A |
p2 | 产品B |
第三范式(3NF)
定义: 首先要满足第二范式,其次 非主属性 之间不存在函数依赖.
由于满足了第二范式,表示每个 非主属性 都函数依赖于 主键。如果 非主属性 之间存在了 函数依赖,就会存在 传递依赖,这样就不满足第三范式。
例如 (产品流水凭证模板表), 产品代码 和 交易类型 是联合 主键:
产品代码 | 交易类型 | 凭证模板代码 | 差额凭证模板代码 | 差额凭证模板名称 |
---|---|---|---|---|
p1 | 66 | t1 | tt1 | 差额A |
p2 | 777 | t2 | tt1 | 差额A |
p1 | 888 | t1 | tt1 | 差额A |
差额凭证模板代码 依赖于 主键 (产品代码, 交易类型), 差额凭证模板名称 依赖于 差额凭证模板 代码, 这就存在 传递依赖, 不满足第三范式.
修改 使其满足 第三范式 :
产品代码 | 交易类型 | 凭证模板代码 | 差额凭证模板代码 |
---|---|---|---|
p1 | 66 | t1 | tt1 |
p2 | 777 | t2 | tt1 |
p1 | 888 | t1 | tt1 |
差额凭证模板代码 | 差额凭证模板名称 |
---|---|
tt1 | 差额A |
参考
1: 数据库设计的三大范式