# 范式
## 为什么要用范式
我们在学习关系型数据库的时候一定有感觉,关系数据库不就是一个二维表格吗,那么数据库有什么用?
数据库看上去像一个表格,其实不然,比如如下的`订单表`,一个订单号X2001对应一个用户,但是还对应了两行产品,非常不规范。
![image.png](http://upload-images.jianshu.io/upload_images/1323506-9cf41deb19483546.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
要想把这个表规范化,可以使用`范式`。引入范式的主要目的在于:**解决冗余的问题**
## 第一范式
那么如何`规范化`呢?可以拆分成两个表格。
一个是`订单表`
![image.png](http://upload-images.jianshu.io/upload_images/1323506-85ee3a38d250ca39.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**一个订单号可以唯一的确定一行**
一个是`细节表`,一个订单号+产品编码才可以唯一的确定一行。
![image.png](http://upload-images.jianshu.io/upload_images/1323506-2c7ed315ee768718.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
拆分以后就可以保证**一个单元格只有一个值了**
所以我们说`订单表`的主键是 (订单号), `细节表`的主键是(订单号,产品编码), 这是一个复合主键
## 第二范式
再看看`订单细节表`, `产品名称`和`单价` 实际上并不依赖于 `订单号`。
如果想添加一个新的产品, 你会发现没法放入这张表, 因为没有订单号!
![image.png](http://upload-images.jianshu.io/upload_images/1323506-bd998331c4a777ce.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
所以还需要再次拆分。
![image.png](http://upload-images.jianshu.io/upload_images/1323506-0067eea7dbc5a782.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
拆分以后,表4.1`订单细节表`的主键还是(订单号,产品编码),但是剩下的属性(数量)肯定是完全依赖于主键的。
表4.2产品表也类似,主键是`产品编码`,剩下的属性都依赖于`产品编码`
> 所有属性都依赖于`主键`的情况就是`第二范式`
## 第三范式
我们再回过头来看一下表格3 `订单表`,它的主键是`订单号`,所有的属性都依赖于主键,已经是第二范式。 但是我们发现,订单号能决定用户ID,用户ID能决定用户名称,这就出现了`依赖传递`:**订单号->用户ID->用户名称**
![image.png](http://upload-images.jianshu.io/upload_images/1323506-9a7220c4066c7ade.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
那么可以再拆分
![image.png](http://upload-images.jianshu.io/upload_images/1323506-31bafaaeb19dd2e1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
> 没有传递依赖了, 我们可以称之为 第三范式
为了满足范式要求,需要把一张大表拆分开,到时候查询岂不是非常麻烦?是的,需要将这些表`Join`起来,如果数据量大的时候,连接非常耗时。有时我们需要违反范式,做点数据冗余。
# 总结
总结一下:
- 第一范式:字段是不可再分的,也就是不存在一个字段中存在两个及以上**值**的情况。
- 第二范式:**所有属性都依赖于主键**,其他不相关的都拆分出去了。
- 第三范式:不存在某个列不依赖于`非主键`的列,没有依赖传递了
# 参考
主要改编自[张大胖学数据库]( https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513430&idx=1&sn=2cb004652353d08db7f3724c7efd26a1&chksm=80d67995b7a1f08313d2f8d2c000c27ee480596849a5bee20d2f82b8409f6da8ec7348c69e5a&scene=21#wechat_redirect)