数据库范式

          范式 :英文名称是 Normal Form。所以  第一范式为1NF,第二范式为2NF,第三范式为:3NF。后边还有很多范式,在数据库设计中最常用的是前三个范式和反范式

          第一范式(1NF): 列不可分!

           举例:表 user_t(name,age,phone),这不符合第一范式。其中手机号phone可以分为home_phone和mobile_phone,所以此时user_t才符合第一范式。如user_t(name,age,home_phone,mobile_phone)。

           第二范式(2NF): 1、先满足第一范式!2、必须有一个主键且其他列必须依赖该主键!

            举例:表 order_detail(order_id,product_id,price,discount,quantity,product_name),该表中有一个联合主键(order_id,product_id),其中discount(折扣)和quantity(数量)一起依赖这个联合主键,而price和product_name则只依赖product_id,此时这两个字段会产生冗余数据。所以order_detail不符合第二范式。此时需要把该表做分割,分成两张表order_detail(order_id,product_id,discount,quantity)和product(product_id,price,product_name),分割之后消除冗余数据,先满足了第一范式,又满足了第二范式。

           第三范式(3NF):1、先满足第二范式!2、不能存在非主键A依赖非主键B,非主键B又依赖主键的关系!

         举例:order_detail(order_id,create_time,user_id,user_name),其中order_id为主键,其他字段都依赖该主键,所以此时满足第二范式。但是user_name直接依赖的却是外键user_id,对order_id则是通过user_id间接依赖,所以此时不符合第三范式。所以分割该表来满足第三范式:order_t(order_id,create_time)和user_t(user_id,username)。

        问:第二范式和第三范式如何区别? 
        第二范式:非主键列是否依赖主键(包括一列通过某一列间接依赖主键),要是有依赖关系的就是第二范式。
        第三范式:非主键列是否是直接依赖主键,不能是那种通过传递关系的依赖的。要是符合这种就是第三范式。

问:范式的存在有什么好处? 
范式可以避免数据冗余,减少数据库的空间,减轻维护数据完整性的麻烦。范式再给我们带来的上面的好处时,同时也伴随着一些不好的地方:按照范式的规范设计出来的表,等级越高的范式设计出来的表越多。如第一范式可能设计 出来的表可能只有一张表而已,再按照第二范式去设计这张表时就可能出来两张或更多张表,如果再按第三范式或更高的范式去设计这张表会出现更多比第二范式多 的表。表的数量越多,当我们去查询一些数据,必然要去多表中去查询数据,这样查询的时间要比在一张表中查询中所用的时间要高很多。我们在利用范式设计表的时候,要根据具体的需求再去权衡是否使用更高范式去设计表。在一般的项目中,我们用的最多也就是第三范式,第三范式也就可以满足我们的项目需求,性能好而且方便管理数据。

当我们业务越来越复杂,表与表之间的关系越来越多,我们又要查询时间短,查询速度非常快,那么此时上边的三个范式就无法满足我们的要求了。因为当数据量特别大的时候连表查询其性能非非常低的,所以这个时候我们可以使用"反范式"。

反范式: 在反范式的设计模式,我们可以允许适当的数据的冗余,用这个冗余去取操作数据时间的缩短。也就是用空间来换取时间,把数据冗余在多个表中,当查询时可以减少或者是避免表之间的关联。

举例:order_t(order_id,order_code,create_time,user_id)和user_t(user_id,user_name)。查询所有的订单号、创建时间,购买人名称。sql如下:

select order_code,create_time,user_name from order_t o,user_t u where o.user_id=u.user_id;

当数据量少时,这个查询很快,没问题,但是当数据量到大上百万的时候,这个连表查询的性能是成倍的下降,慢的不行不行的。所以此时可以适当冗余order_t表:order_t(order_id,order_code,create_time,user_name,user_id)。在这个表中冗余一个user_name字段,此时做单表查询:

select order_code,create_time,user_name from order_t;

单表查询的效率是刚刚地,其性能提升10以上都是有可能的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值