数据库范式
先说明范式中涉及两个索引概念:主键和复合主键。
- 主键: 创建表时可以不设置主键 , 但是没有设置主键的表 ,底层会认为所有的键都是主键 ,所以在创建时使用了所有的字段创建索引 , 在查询时索引的存在几乎没有意义 。
- 复合主键: 两个或两个以上的字段作为评价一条数据记录的唯一性标志 。
第一范式:
- 确保每一列的原子性(列不可再分):保证数据表中每个字段都是不可再分的最小数据单元,则满足第一范式(一般关系型数据库都遵循第一范式原则)。例如:address地区表,包含字段id,address
原则上,该表address字段还可以再继续拆分成下表,
但是最终还是得根据用户需求来设计,所以两表都可以说是遵循第一范式原则。
第二范式:
- 在第一范式的基础上,确保表中的非主键的每列完全依赖于主键:是指每个表必须有且仅有一个数据元素为主键(Primary key),其他数据元素与主关键字一一对应。换而言之,如果数据表中只有一个主键,则都符合第二范式原则。
货物类型 | 货物ID | 货物名称 |
瓷碗 | 1 | 白色瓷碗 |
瓷碗 | 2 | 青花瓷碗 |
瓷碗 | 3 | 雕花瓷碗 |
三合板 | 1 | 普通三合板 |
在该表中的主键依然是(货物类型、货物ID),非主键字段“货物名称”,完全依赖于这两个主键,那么我们就可以说,该表是符合数据库第二范式的。
第三范式:
- 在第二范式的基础上更进一步,目标是确保表中的列都和主键直接相关,而不是间接相关:一个数据表中不包含 其他数据表中的非主键字段
不符合第三范式例子:
学生表ID | 学生 | 所在院系 | 院系地址 |
1 | 张三 | 计算机系 | 行政楼1号 |
2 | 李四 | 数学系 | 行政楼2号 |
3 | 王五 | 计算机系 | 行政楼1号 |
符合第三范式例子:
学生表ID | 学生 | 院系ID |
1 | 张三 | 1 |
2 | 李四 | 2 |
3 | 王五 | 1 |
院系表ID | 所在院系 | 院系地址 |
1 | 计算机系 | 行政楼1楼 |
2 | 数学系 | 行政楼2楼 |
反范式:
- 通过增加冗余或重复的数据来提高数据库的读性能(以内存换时间)。例如,学生表中的“所在院系”字段,本来应该通过关联院系表再进行查询的,实际情况综合考虑后,想节省关联查询的时间成本不惜付出数据冗余的内存成本为代价,使用了反范式原则。
学生表ID | 学生 | 院系ID | 所在院系 |
1 | 张三 | 1 | 计算机系 |
2 | 李四 | 2 | 数学系 |
3 | 王五 | 1 | 计算机系 |
院系表ID | 所在院系 | 院系地址 |
1 | 计算机系 | 行政楼1楼 |
2 | 数学系 | 行政楼2楼 |
优点与缺点:
范式的优点:更新数据快,重复数据少,修改数据少,表很小可以在内存中执行,查询时需要更少的distinct或group by
范式的缺点:查询时需要更多的关联,可能引起索引策略无效
反范式的优点:所有的数据可以在一张表上显示,可以避免关联,可以设计有效的索引
反范式的缺点:冗余字段较多,删除记录会造成有用数据丢失