数据库设计教程系列——数据库范式

2014-09-17 17:44:33

请关注唯心的个人微信公众号:craft6-cn(中划线,也可以搜索:领域驱动业务建模)

一、概述

    设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式.

    各种范式呈递次规范,越高的范式数据库冗余越小。

    目前关系数据库有六种范式:

    第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,还又称完美范式)。    

    范式的严格程度按上面的位置依次递增,后面的范式必须在满足前面范式的基础上增加该范式独有规范才能称为该范式。

  

    各范式的关系如下图:

    范式关系.jpg


二、第一范式

   第一范式:确保每一列的值的原子性、不可分割性。或者说:每个属性仅包含一个单一值。
   (其实第一范式的概念是最复杂的)

   
    检查是否满足第一范式有下面几种方式:

  1. 属性的值是否超出定义的范畴

    比如有个属性是“网站”,但却存储了类似这样的值“craft6.cn,唯心六艺,颜超敏”。
    (这个值隐含三个内容:域名、网站名称和站长姓名。也即

    即除了存储了姓名外,连邮箱也存储在该值中。

  2. 属性是否存在重复

    如某个表存在工号、姓名和电话。如果某些职工拥有家庭电话、办公电话(或更多),那么这些
    职工就需要有两条或者多条记录,以便保存这些电话,但是这样导致了在这些记录中工号和姓名
    都重复出现了。


  3. 属性的定义是否范围过大

    比如属性名为“配置”,数据类型是字符串,值格式是JSON。则实际操作中,可以往该属性中存放
    随意的JSON格式字符串,这些字符串的含义只有在程序代码中才能解释,而无法通过sql查询匹配。

  4. 检查是否有重复属性组

   如电子商务的购物车表,设计成如下图:

   第一范式-重复组.jpg

   一个产品SKU ID + 数量 就是一组,从表中可以看到,顾客最多只能选购3个产品,从数据模型的角度
限制了顾客购买产品的数量。

三、第二范式

   第二范式:所有非主码属性完全依赖候选码。

   (注:候选码就是唯一决定一条记录的1个字段或多个字段的组合,所以可以是主键、复合主键 或 唯一键等)


   检查是否满足第二范式有下面几种方式:

  1. 该表是否存在多种实体的数据

    比如该表同时存储了产品和该产品所属供应商的信息,那么就应该将供应商独立出来作为一个新的实体,
    然后为产品 和 供应商 两个实体建立联系。

  2. 是否存在当前实体的主键 或 唯一键无法约束的属性

    依然以产品表为例,对于产品表,产品名称、描述、市场价、销售价等信息是产品本身的,是依赖该产品存在的。
    但如果该表中存在品牌名称、品牌网址等字段,这些字段不是产品主键能够约束,多个产品可以属于同一个品牌,

    有同样的品牌名称、品牌网址等。

    (有时为了查询效率考虑,会将品牌信息冗余到产品表中,这就是反范式的应用)


四、第三范式

     第三范式:所有非主码属性都是相互独立的,或者说非主码属性对主码的依赖是直接的,而不能间接的。
     

     比如 A、B 是非主码,C是主码。不可以A 依赖 B,B 依赖 C。必须A 、B 均直接依赖 C。A 、B 之间

相互独立,不存在依赖关系。


    检查是否满足第三范式有下面几种方式:

  1. 是否有派生属性

    比如订单实体的订单总金额。如果在订单表中存储了产品折扣总价、运费、税费、包装费等,那么总金额
    其实是通过这些费用计算得出。它是派生属性,是依赖计算公式相关的字段,而不是直接依赖订单主码(主键或订单号)。


  2. 是否冗余了其它实体的信息

    比如订单表,冗余了送货地址各项属性,而这些属性应该是归属到客户地址实体中。


    增加派生属性、冗余属性都有利于提高查询效率,但是有些时候需要通过代码来维护数据的完整性。


    在实践中,第三范式往往会因为查询效率而违反,而这个违反有时是有益的。

五、BCNF范式

   BCNF范式是基于第三范式的基础上,满足下列条件:

  1. 当该表存在多个候选码(主键、复合主键、唯一键等)

  2. 至少两个候选码必须是复合的。

  3. 候选码之间有重叠的属性

  4. 这些有重叠属性的候选码存在依赖关系。


   如下图:

BCNF.jpg

  1. 对于供应商而言,供应商 ID 和 供应商名称 均是唯一的。

  2. 对于产品而言,产品ID 和产品名称 也均是唯一的。

  3. 所以供应商ID + 产品ID 可以唯一决定该表的一条记录。
    供应商ID + 产品名称、供应商名称 + 产品ID、供应商名称 + 产品名称 也一样可以决定该表的记录。

  4. 所以此时供应商名称、产品名称均是冗余属性。只有去掉这两个属性,该表的设计
    才符合BCNF范式。

  5. 有时实践中还是这样设计是为了方便查询,但是冗余一般只针对更新频率很低的属性,
    否则需要考虑如何维护数据完整性。


六、第四范式

   第四范式:独立的重复组不应该被组合在一个关系中。


   简单而言,就是不要设计多值属性。


   在实际设计中,我们会使用字符串类型来维护一个多值,比如可选尺寸,可选数量等。

值之间通过逗号(或其它符号)分隔等。这种设计是不符合第四范式的。


    解决的方法就是将多值属性分离成一个独立的表来管理。


    比如下图:

    第四范式.jpg


    对于C6_EAV_ATTR【属性】表而言,当数据类型是可选项时,如果设计一个字段通过逗号分隔的方式

维护可选值,则不符合第四范式。如果按图中所示,将选项独立出来(属性选项表),则符合第四范式。


    在实践中,是否要满足第四范式,还是要看该多值属性的数据复杂度,以及以后扩展要求是否高。

如果比较复杂,扩展要求高,则建议分离出来,满足第四范式。


七、第五范式

     第五范式用来处理“连接依赖”的情况,该情况很少出现,所以一般我们都用不到第五范式。


     第五范式:当存在3个实体存在循环连接时,将该循环连接产生的三元关系分解而3个二元关系。


     如下图:

     第五范式.jpg

   如果业务满足这些约定:客户在商家购买产品(在商家购买的只能是产品,产品只能从商家购买),

则该联系是成立的。但是如果业务并不仅是如此,比如客户可以从其它途径(如平台)购买产品,

或者客户从商家可以购买服务(而服务并没有设计为产品的一类),那么该联系就不成立了,

就不符合第五范式了。


   解决方式,就是中间的三元关系,拆分为3张二元关系表,分别是客户-商家、客户-产品、商家-产品。

   这里就不再贴图了。


可通过扫描左侧二维码阅读本文。本站文章均为颜超敏原创,欢迎转载,请注明出处即可,转载可通过下面的社会化工具快速完成。

分享到:


为您推荐这些文章,如果感兴趣,请继续阅读吧:

数据库设计教程系列——数据库范式

数据库设计范式,第一范式,第二范式,第三范式,BCNF范式,第四范式,第五范式

   本文阐述了数据库设计中的六种范式,包括对各个范式的定义、

检查方式、解决方式等说明。同时也说明了在实践中,对于各个

范式的使用情况。

颜超敏,唯心六艺,Craft6.cn,电子商务博客,电子商务研发,电商研发,电子商务研究,电商研究,电子商务专家,电商专家,电子商务知识,电商知识,电子商务教程,电商教程,电子商务模式,电子商务平台,电子商务商业模式,电子商务数据库设计,电商数据库设计,电子商务系统分析,Java架构设计,Java软件架构,B2C,O2O,o2o模式,o2o电子商务,o2o电子商务平台,中国电子商务,电子商务平台建设方案
粤ICP备14060523号 Copyright @2014 -唯心六艺软件