目录
第一范式(1NF)
- 字段具有原子性,即数据库表的每个字段都是不可分割的原子数据项,不能是集合、数组、记录等非原子数据项
- 当实体中的某个属性有多个值时,必需拆分为不同的属性
举例
student:
name | mobile | username | address |
---|---|---|---|
eddie | 131xxxxxxxx | eddie | 广东省广州市x路x号z房 |
address字段可以拆分省市等等,之后就可以方便归类
修改如下:
name | mobile | username | province | city | address |
---|---|---|---|---|---|
eddie | 131xxxxxxxx | eddie | 广东省 | 广州市 | x路x号z房 |
第二范式(2NF)
- 满足 1NF 的基础上,要求每一行数据具有唯一性,并且非主键字段完全依赖主键字段
举例
student: PK(no, classname)
no | classname | score | credit |
---|---|---|---|
10001 | 英文 | 100 | 6 |
改造拆分两张同类型表:
student: PK(no)
no | classname | score |
---|---|---|
10001 | 英文 | 100 |
class:PK(classname)
classname | credit |
---|---|
英文 | 6 |
第三范式(3NF) - 防止冗余
- 满足 2NF 的基础上,不能存在传递依赖
举例
student: PK(id)
id | no | age | sex | school | school_addr | school_phone |
---|---|---|---|---|---|---|
1 | 007 | 20 | M | 社会大学 | GZxx | 020-xxx |
改造拆分两张同类型表:
student: PK(id)
id | no | age | sex | school |
---|---|---|---|---|
1 | 007 | 20 | M | 社会大学 |
school:PK(school)
school | school_addr | school_phone |
---|---|---|
社会大学 | GZxx | 020-xxx |
反模式设计
- 适当增加冗余,从而提升查询效率
比如有两张如下表:
student: PK(id)
id | no | age | sex | school |
---|---|---|---|---|
1 | 007 | 20 | M | 社会大学 |
school:PK(school)
school | school_addr | school_phone |
---|---|---|
社会大学 | GZxx | 020-xxx |
如果需要查询学生的学校地址:
student: PK(id)
id | no | age | sex | school | school_addr |
---|---|---|---|---|---|
1 | 007 | 20 | M | 社会大学 | GZxx |
school:PK(school)
school | school_addr | school_phone |
---|---|---|
社会大学 | GZxx | 020-xxx |
那么就只查询 student 就可以,单表查询绝对会好过关联查询
表设计原则
- 字段少而精,建议20个以内,超过可以侧分
- 把常用的字段放到一起
- 把不常用的字段独立出去
- 大字段(TEXT、BLOB、CLOB等等)独立出去
- 尽量用小型字段
- eg.用数字第一字符串 (比如:IP地址就可以使用 int, 而不是使用 varchar(15))
- 避免使用允许为 NULL 字段
- 允许 NULL 字段很难查询优化
- 允许为 NULL 字段的索引需要额外的空间
- 合理平衡范式和冗余
- 如果数据量庞大,可以考虑分库分表