那一天,人们终于回想起了被BUG支配的恐惧
Toggle navigation
Home
AboutMe
Links
Archives
Tags
数据库设计范式
? MySQL ?
2016-03-02 22:30:27
339
0
0
weibo-007
? MySQL ?
#数据库设计范式介绍 关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴德斯科范式(BCNF)、第四范式(4NF)和第五范式(5NF) * `第一范式(确保每列保持原子性)` 第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式 * `第二范式(确保表中的每列都和主键完全依赖)` 需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中 * `第三范式(在第二范式的基础上,消除传递依赖)` 需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关 当然还有更高的范式,单是它们的关系总是先满足1NF,然后在1NF上改进成2NF,以此类推,所以范式之间的关系可以用以下图表示: <img src="http://leanote.com/api/file/getImage?fileId=56d5b318ab64417fb10022b3" width="500" /> #第一范式 1NF是数据库设计的最基本范式,在关系型数据库中,如果一个域是原子的,并且该域的元素`被认为`是不可分的单元,我们就称符合这种设计的表满足1NF,比如下面一张商品表: `商品信息表` |商品ID|商品名称|颜色|价格|商家名字|商家联系方式| |- |1|韩版休闲裤|蓝|50.0|张三|13634589384| |1|韩版休闲裤|黄|60.0|张三|13634589384| |2|欧式西装|黑|140.0|李四|13234534543| 这张表就符合1NF,每一列都不可再分。 1NF的缺点有以下 1. **数据冗余太大**,商家名字和商家联系方式大量冗余 2. **更新异常**,需要更改商家联系方式的时候,需要修改大量的信息 3. **插入异常**,如果一个商家刚成立,没有发布商品,插入会导致异常 4. **删除异常**,如果一个商家的商品全部删除,商家随着被删除 **思考?** 下面这收件地址张表符合1NF吗? |收件人|省|市|区|街道|详细地址| |- |张三|江西省|赣州市|章贡区|钟楼大街|幸福小区503号楼22#| 还有很多设计成json格式存储的表是否符合1NF? |地名|地址| |- |北京市|{"东经":"116","北纬":'39"}| #第二范式 第二范式是在第一范式的基础上升级而来的,一个满足第二范式的表,一定满足第一范式。再看第一个范式中商品信息表的例子,有各种各样的缺点都可以通过范式升级来解决。第二范式`表中的每列都和主键完全依赖`,两个概念 1. 主键 2. 完全依赖 `主键`不是数据库的主键,在关系模式里,主键叫码,主键可以是一个属性或者属性组合,可以怎么认为,当主键确定后,其他的数据也就确定了,比如商品信息表中,只有当(商品ID, 颜色)确定后,其他的属性都可以确定了,那么`(商品ID,颜色)`就是主键 `完全依赖`,当主键是一个组合的时候,其他属性必须有主键内的所有元素决定,就称之为符合完全依赖。比如主键(商品ID,颜色)->其他属性(商品名称),这时,商品名称对主键就不是一种完全依赖,因为主键中的商品ID足以确定商品名称,正是因为这一点,第一范式例子中的商品信息表不符合2NF. 用主键,依赖的角度理符合1NF表关系: <img src="http://leanote.com/api/file/getImage?fileId=56d6d167ab64417fb1002b6f" width="500" /> 既然表中有联合主键(商品ID,颜色),商品名称只和联合主键的(商品ID)相关,所以这张表的设计不符合2NF,只能认为是1NF。按照第二范式的规定,必须消除这种部分相关(其他列只与主键的某一部分相关)。对表进行拆分: `商品价格表` |商品ID|颜色|价格| |- |1|蓝|50.0| |1|黄|60.0| |2|黑|140.0| `商品信息表` |商品ID|商品名称|商家名称|商家联系方式| |- |1|韩版休闲裤|张三|13634589384| |2|欧式西装|李四|13234534543| 商品价格表的主键(商品ID,颜色)两者决定价格,而不是价格之和主键中的一个相关,商品信息表主键(商品ID)决定了商品名称,商家名称,商家联系方式。所以这个表是符合2NF的,2NF表设计后: 1. **数据冗余太大**,商家名字和商家联系方式大量冗余,有改进,不彻底 2. **更新异常**,需要更改商家联系方式的时候,有改进,不彻底 3. **插入异常**,如果一个商家刚成立,没有发布商品,插入会导致异常,无改进 4. **删除异常**,如果一个商家的商品全部删除,商家随着被删除,无改进 #第三范式 在2NF的基础上,如果商品继续增多,商品信息表会变成这样: **商品信息表** |商品ID|商品名称|商家名称|商家联系方式| |- |1|韩版休闲裤|张三|13634589384| |2|欧式西装|李四|13234534543| |3|欧式西裤|李四|13234534543| 结果,你会发现,数据又开始出现了冗余,当有一天想修改商家联系方式的时候,发现要修改好多行信息。这个时候需要再将表升级到3NF来解决问题。3NF要确保其他列都和主键(商品ID)直接相关,而不能间接相关,就目前这个商品信息表,由于商品ID->商家名称,商家名称->商家联系方式;所以主键(商品ID)和商家联系方式间接相关联了,3NF就是在2NF的基础上`消除间接关联`。 用传递依赖的角度看2NF的关系: <img src="http://leanote.com/api/file/getImage?fileId=56d6db83ab64417fb1002bac" width="500" /> 所以再将商品信息表拆分: `商品价格表` |商品ID|颜色|价格| |- |1|蓝|50.0| |1|黄|60.0| |2|黑|140.0| `商品信息表` |商品ID|商品名称|商家ID| |- |1|韩版休闲裤|1| |2|欧式西装|2| `商家信息表` |商家ID|商家名称|商家联系方式| |- |1|张三|13634589384| |2|李四|13234534543| 按照第三方的定义,每列都必须和主键直接相关,而不是间接相关。`商品价格表`主键(商品ID,颜色)直接决定价格。`商品信息表`中主键(商品ID)直接决定商品名称,同时也直接决定商家ID。`商家信息表`中主键(商家ID)直接决定商家名称和联系方式。所以这样的表符合3NF。 再看3NF带来的改变: 1. **数据冗余太大**,商家名字和商家联系方式大量冗余,已解决 2. **更新异常**,需要更改商家联系方式的时候,需要修改大量的信息,已解决 3. **插入异常**,如果一个商家刚成立,没有发布商品,插入会导致异常,已解决 4. **删除异常**,如果一个商家的商品全部删除,商家随着被删除,已解决 #范式总结 在实际生产应用中,不可能像上面一样经过那么繁琐的过程建立表关系。范式放在现实生活中就是归类,服务化的提现。比如上面的表,商家的信息拆分成商家部分,形成商家服务;商品信息拆分成商品部分,形成商品服务;商品价格拆分成sku系统,形成价格库存服务。当这样设计之后,其实表的结构已经基本服务3NF。
Pre:
PHP自动加载
Next:
Nginx状态码
0
likes
339
Weibo
Wechat
Tencent Weibo
QQ Zone
RenRen
Submit
Sign in
to leave a comment.
No Leanote account?
Sign up now.
0
comments
More...
Table of content
No Leanote account? Sign up now.