数据库三大范式讲解实用篇

数据库三大范式

第一范式:

  • 第一范式(1NF)是指在关系模型中,对于添加的一个规范要求,所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合、数组、记录等非原子数据项。
  • 即实体中的某个属性有多个值时,必须拆分为不同的属性。
  • 在符合第一范式(1NF)表中的每个域值只能是实体的一个属性或一个属性的一部分。
  • 简而言之,第一范式就是无重复的域。
    在这里插入图片描述

第二范式

  • 在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)。

  • 候选码:候选键,任何能保证“唯一性”的字段都可以是候选键,例如在“用户”信息中,身份证号、验证过的手机号都是候选键, 任何候选键都可以被选作主键,如果无可用候选键,应创建ID等值不重复的字段。
    在这里插入图片描述
    在这里插入图片描述
    第三范式:

  • 在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

  • 传递依赖:A依赖于B,B依赖于C,完整来看,A也是依赖于C的,这个依赖关系是传递过去的。

引申

  • 关于冗余

  • 只要是“可以不存”、“可以使用id表示”、“存了多次(非id)”的数据,却直接存储到数据库里,都可以称之为“冗余”

  • 遵守数据库范式,设计不冗余的数据表,同时,也会把原本冗余的数据表中的数据拆分到多张表中去,导致“单一的数据表不足于表现数据”,例如当需要查看订单信息时,仅仅只是查询“订单信息表”是完全不够的,因为即使知道商品id是PO01也不知道这到底是什么商品,更不足以显示到软件的界面中去,为了查询到完整的信息,必须查询多张表,例如:

    select*from订单信息表join商品信息表on订单信息表.商品id=商品信息表.商品id;

  • 如果还需要查询出用户的信息,则以上SQL语句还需要继续补充关联查询!

  • 当表的关联越复杂,查询时需要关联的表就越多,但是,如果采取的是“冗余”的设计方案,只需要查询“订单信息表”这1张表就能查询到完整的信息。

  • 可见,即使是“冗余”的设计方案,它也是有优点的,就是“简单!快! ”

  • 在《阿里巴巴Java开发手册》中约定:

    • 【推荐】库名与应用名称尽量一致。
    • 【推荐】如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释。
    • 【推荐】字段允许适当冗余,以提高查询性能,但必须考虑数据一致。冗余字段应遵循:
      • 不是频繁修改的字段
      • 不是varchar超长字段,更不能是text字段。
      • 正例:商品类目名称使用频率高,字段长度短,名称基本一成不变,可在相关联的表中冗余存储类目名称,避免关联查询
  • 所以,冗余不一定是缺点,适当冗余可提高查询性能,所以,数据库范式不是必须完全遵循的,应该根据实际情况来决定!

数据库范式建议:

  • 数据库范式约定了创建数据表的规范((尽管可能不完全遵守),在实际开发中,通常还有以下建议:
    • 如果varchar类型的字段的值的长度相对可控,推荐使用char替代,因为char的效率更高一些
    • 尽管varchar类型的理论长度可达65535,但如果可能超过5000 (部分企业可能约定为其它值),建议将其设计到另—张表中去,并与当前表关联-可能建议将字段类型改为text
    • 可能会在当前表把长字符串值进行截取,便于获取简要信息
    • 如果可行,建议使用更小的单位存储更大的数值,避免使用浮点类型,造成运算时的误差,例如价值为“18.52元”的商品,存储为“1852分”

总结:

  • lNF:在关系模型中,对于添加的一个规范要求,所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项,简单来说就是:列不可再分
  • 2NF:在1NF的基础上,非码属性必须完全依赖于候选码,简单来说就是:非主属性不能只依赖主键的一部分
  • 3NF︰在2NF基础上,任何非主属性不依赖于其它非主属性,简单来说就是:每列数据都与主键直接相关

核心思想:

  • 数据库范式的核心思想包括“消除冗余”,冗余的缺点在于:
    • 不便于管理维护
    • 占用较多的存储空间
  • 但是,适当冗余可提高查询性能
    • 数据库范式不是必须严格遵守的

使用原则:

  • 基本按照数据库范式来设计各数据表,但不完全遵循,并且:
    • 查询频率高且修改频率低的较短长度的数据允许冗余,特别是关联查询
    • 如果varchar类型的字段的值的长度相对可控,推荐使用char替代,因为char的效率更高一些
    • 尽管varchar类型的理论长度可达65535,但如果可能超过5000(部分企业可能约定为其它值),建议将其设计到另一张表中去,并与当前表关联 -一可能建议将字段类型改为text
    • 可能会在当前表把长字符串值进行截取,便于获取简要信息
    • 如果可行,建议使用更小的单位存储更大的数值,避免使用浮点类型,造成运算时的误差,例如价值为“18.52元”的商品,存储为“1852分”