数据库范式解析
2015-12-02 14:17
330 查看
前言
前段时间自己写项目,在设计数据库的过程中,重新审视了关系型数据库,在此记录整理如下。但是只有通过实际开发,并在其中运用、体会才能深刻学习和领会到前辈们创造的理论的优美!
什么是关系型数据库的范式?
范式英语:Normal Form ,如果我们在设计关系型数据库过程中遵循一定的规范,那么我们的数据库设计就会冗余少。现在数据库设计最多满足3NF,普遍认为范式过高,虽然具有对数据关系更好的约束性,但也导致数据关系表增加而令数据库IO更易繁忙。
每一级NF都有必须保证满足上一级NF。
概述
1NF:列的原子性,不可再分;
2NF:非主键列必须完全依赖于主键;
3NF:非主键列必须直接依赖于主键列,不能存在传递依赖(传递依赖:非主属性A依赖非主属性B,B再依赖主属性C);
详解
1NF
1.1 解决的问题排除重复组
1.2 例子
Table_交易
顾客 | 日期 | 数量 |
---|---|---|
Pete | Monday | 19.00 -28.20 |
Pete | Monday | -84.00 |
Sarah | Friday | 100.00 -48.20 |
1.3 解析
理论上不可能有RDBMS能让你设计出违反1NF的数据表,也就是说RDBMS已经保证其列的原子性了。例如,你定义了一个整数字段来存放数量,你肯定写不出”25,30”这样的值,它是违法的(如果你硬把2530连着写,那表示这是一个原子值)。
不过就算这样,你还是可以设计出骨子里违反1NF的表,例如
一、单一字段中有多个有意义的值
Table_不喜欢的食物
人 | 不喜欢的食物(varchar类型) |
---|---|
Pete | 白菜,面包 |
Pete | 泡菜,白菜,西兰花 |
b) 以这样的设计,如果要查询不喜欢白菜的人就很不清晰该怎么做了(还能叫关系型数据库表吗)可能必须使用like%%了。
二、用很多字段来表达一个事实
Table_不喜欢的食物
人 | 不喜欢的食物1 | 不喜欢的食物2 | 不喜欢的食物3 |
---|---|---|---|
Pete | 白菜 | 小龙虾 | 芹菜 |
Alan | 泡菜 | 龙虾 | 大闸蟹 |
2NF
1.1 解决的问题如果一个数据表只有单一一个主键字段的话,它就一定符合第二范式。
错误一般只会发生在想设计有一对多/多对一中多的一方或者是多对多关联表中的联合主键时发生。
1.2 例子
Table_组件来源
组件ID(主键) | 价格 | 供应商ID(主键) | 供应商名称 | 供应商住址 |
---|---|---|---|---|
65 | 59.99 | 1 | Stylized Parts | VA |
74 | 20.00 | 1 | Stylized Parts | VA |
65 | 69.99 | 2 | ACME Industries | CA |
首先,上表是按多对一设计的(设计错误问题正是我们要说的),1个组件来自于1个供应商,1个供应商可能供应多个组件。
其次,上表满足了列的原子性,所以符合第一范式。组件ID和供应商ID是联合主键。
价格根据不同组件和不同供应商才能确定,没问题。
但供应商名称和供应商地址只是依赖于供应商ID的,跟组件没有关系,这就叫非完全依赖。
一、正确设计
Table_供应商↓
供应商ID(主键) | 名称 | 价格 |
---|---|---|
1 | Stylized Parts | VA |
2 | ACME Industries | CA |
组件ID(主键) | 价格 | 供应商ID(主键) |
---|---|---|
65 | 59.99 | 1 |
74 | 20.00 | 1 |
65 | 69.99 | 2 |
3NF
1.1 解决的问题在2NF基础上,非主键列必须直接依赖于主键。
1.2 解析
例子其实可以是上边2NF的列子,它也是不符合3NF的。
在做数据库表设计时,仔细考虑你写下的非关键字段到底是否直接依赖于主键,这样就能遵守第三范式了。
相关文章推荐
- Mysql学习笔记七,存储过程和函数
- SQLSERVER聚集索引和主键(Primary Key)的误区认识
- Oracle 未明确定义列的错误
- MySql运算符
- mysql技术内幕学习笔记-查询优化器及索引(一)
- SQL Server DATEADD() 函数和DATEDIFF() 函数
- psql-03数据类型(1)
- oracle控制文件
- oracle数据恢复----------之oracle各种闪回操作
- oracle----sqlldr用法
- 使用sqlldr将文件中的数据导入到数据库
- SQLLDR
- sql loader
- redis在linux中安装,java端代码jedis和jedisPool
- mysql新建用户及授权
- Redis学习手册
- sqlite3总结篇
- Sql Server Data compression 预估和选择,以及查看成功压缩的数据页
- zabbix实现mysql数据库的监控(四)
- mongoDB的初步配置