您的位置:首页 > 数据库 > MySQL

mysql三范式说明

2016-06-30 18:30 260 查看


1、mysql三范式:


第一范式(1NF,normal format):字段不可再分。

例如:字段“用户身份标识”:userType-userId。 这个字段“用户身份表”可以再分为“用户类型”和“用户id标识”。


第二范式(2NF):主键没有部分依赖。

常规做法:只要给表一个“id”字段,并设置自动增长,其实就是取消掉复合主键。通过另一个单一字段的主键来代替。一句话,没有复合主键,就没有部分依赖。


第三范式(3NF):取消传递依赖,也就是说表不可再分。

举例:S1(SNO,SNAME,DNO,DNAME,LOCATION) 各属性分别代表学号, 姓名,所在系,系名称,系地址。 关键字SNO决定各个属性。由于是单个关键字,没有部分依赖的问题,肯定是符合第二范式的。但这关系肯定有大量的冗余,有关学生所在的几个属性DNO,DNAME,LOCATION将重复存储,插入,删除和修改时也将产生类似以上例的情况。 

解决方法:分为两个关系 S(SNO,SNAME,DNO),D(DNO,DNAME,LOCATION)。


2、三范式的好处: 

通过范式理论所设计的数据库Schema 逻辑清晰,关系明确,扩展方便,就连存储的数据量也做到了尽可能的少,尤其是当范式级别较高的时候,几乎找不到任何的冗余数据。


3、符合三范式并不一定是最好的:

       尽量三范式去除数据的冗余,让我们查询相同的数据量的时候能够多返回几条记录,还有一个很重要的原因就是在当时的那个年代,数据的存储空间是及其昂贵的,而且存储设备的容量也都非常的小,这一点在硬件存储设备发展如此迅速的如今,空间大小已经不再是太大的问题了。而范式理论中的数据一致性和使数据修改简单保证主要是依靠添在数据库中添加各种约束来保证,而各种约束对于数据库来说本身其实就是一个非常消耗资源的事情。 所以,对于基于性能的数据库Schema 设计,我们并不能完全以规范化范式理论来作为唯一的指导。在设计过程中,应该从实际需求出发,以性能提升为根本目标来展开设计工作,很多时候为了尽可能提高性能,我们必须做反范式设计。

举例:如果有两张表:用户表(用户id,用户昵称,用户真实姓名,用户手机号); 用户绑定银行卡表(银行卡id,用户id,用户卡号,银行类别信息)。

现在有个需求就是用户提现、转账、支付等操作。用户提现记录中只保存有用户的银行卡id信息,而提现需要银行卡号、真实姓名、银行类别。那么首先就需要一次join查询出需要的银行卡信息。
select a.realname,b.cardNum,b.bankcardName  from bankcard  b ,account a where a.id = b.userId ;

但是如果能在用户银行卡绑定表中冗余一个“用户真实姓名”字段,直接一次查询即可完成操作:
select b.realname,b.cardNum,b.bankcardName from bankcard  b ;

从数据库范式理论来看,这样的设计是不合理的。因为可能造成用户 表和银行卡表中的用户真实姓名数据不一致。每次更新用户真实姓名的时候,都需要更新两个表的数据,为了尽可能让两者数据保证一致,应用程序中需要处理更多的逻辑。但是,从性能角度来看的话,这种冗余是非常有价值的,虽然我们的数据更新逻辑复杂了,但是我们在考虑更新带来的附加成本的时候,还应该考虑我们到底会有多少更新发生在用户真实上面呢?我们需要考虑的是一个系统的整体性能,而不是系统中单个行为的性能。就像示例中的真实姓名数据,虽然更新的成本增加了,但是查询的效率提高了,而且发生示例中查询的频率要远大于更新的频率,通过少部分操作的成本投入换取更大的性能收获,实际上增加一个冗余字段也是值得的,有价值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql 三范式