数据库表设计要符合三范式。
三范式是层层叠加的,
第二范式首先满足于第一范式-原子性
第三范式,满足第二范式
第一范式
原子性,数据表每一列的数据都是不可再分的。
譬如数据列为:电话,此列数据可以拆分成:移动电话、固定电话。
第二范式与第三范式一块来理解比较容易。
第二范式
第二范式要求数据表必须有主键,其他属性必须完全依赖于此主键。 此处的完全依赖,可以理解为修改主键,其他数据列都会变更。
| 订单编号 | 商品编号 | 商品单价 | 数量 | 订单总价 | 订单时间 |
|---|---|---|---|---|---|
| dd12323214 | pro45645456 | 3000 | 10 | 30000 | 2024/07/16 |
| dd12323215 | pro45455545 | 1000 | 10 | 10000 | 2024/07/15 |
此数据表 订单编号 和 商品编号 为主键,如果同一个订单,不同的商品变了,但是订单的总价和订单时间不会变。也就不满足主键变更,非主键数据都会变更。订单总价和订单时间只依赖于订单编号。
第三范式
非主键列不传递依赖于主键。
| 借阅编号 | 学生学号 | 书籍号 | 书籍名称 | 书记作者 |
|---|---|---|---|---|
| dd12323214 | 1 | 123 | 傲慢与偏见 | A |
| dd12323215 | 2 | 124 | 汤姆索亚历险记 | B |
此数据表借阅编号为主键,首先看下是否满足第二范式,如果主键,借阅编号变更,借的人员(学生学号)变更,借阅对象(书籍号,书籍名称,书籍作者)都将变更。
所以满足第二范式。
那我们看看第三范式,书籍名称与书籍作者又是 书籍号决定的。书籍号又是借阅编号决定的,所以传递依赖了。
需要将书籍号,书籍名称,书籍作者 单独放一个表中,书籍编号作为外键在 借阅表中使用。
BCNF
除了三大范式,还有补充范式,BCNF是对第三范式的补充。主键之间不会互相依赖。或者是关键元素之间不会互相依赖。 譬如;公交营运表。
| 车次号 | 司机编号 | 乘客数量 | 目的地 | 班次号 |
|---|---|---|---|---|
| K3321 | zs | 60 | 苏州 | T45456 |
| D1340 | ls | 65 | 南京 | T45456 |
关键元素 是 车次号+班次号 或者 司机编号+班次号。 都可以作为 主键,车次号变更,司机编号也会变更,司机编号变更,车次号也会变更。所以车次号和司机编号一一对应。关键元素之间互相依赖,不符合,所以司机编号要拆除去,和车次号绑起来。
好像还有第四第五范式,后续继续探究
但是最近和同事沟通范式,都说反范式。
反范式(时间换空间)
通过冗余数据提高查询性能,但冗余数据会牺牲数据一致性。 譬如上面的借阅表
| 借阅编号 | 学生学号 | 书籍号 | 书籍名称 | 书记作者 |
|---|---|---|---|---|
| dd12323214 | 1 | 123 | 傲慢与偏见 | A |
| dd12323215 | 2 | 124 | 汤姆索亚历险记 | B |
反范式就得将书籍信息和借阅信息放到一个表里面,这样查询 借阅信息,就不需要连表查询,一个表里面的查询就够了。甚至我们可以将学生信息放入这个表里面去。