最近给新员工做了一次数据库基础的培训,其中涉及个主题,就是数据库范式,从理论层面讲,数据库会包含第一范式、第二范式、第三范式、BC范式、第四范式、第五范式等,但是一般情况下,满足第三范式就足够了。
什么是第三范式?我们要从第一范式开始看。
第一范式,理论概念是数据库表中的字段都是单一属性的,不可再分。举个例子,学生信息表,“地址”字段存储了学生的地址,可以看到,当前不是单一属性的,我们检索的时候,可能会根据“省”、“市”作为条件,该字段是可以继续进行分解的,
将“地址”字段拆成“省份”、“城市”、“详址”三个字段,此时每个字段就是单一属性的了,当前的设计就是符合第一范式,
第二范式,理论概念是数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖,不能部分依赖。听着抽象,翻译一下,应该包括了三层含义,
1. 首先就是符合第一范式。
2. 表必须存在主键。
3. 非主键列不能只依赖于主键的一部分。
如下这张表,主键是“快递单号”和“商品编号”,但是像“价格”依赖于“商品编号”,“数量”依赖于“快递单号”,都是依赖于主键的一部分,这种情况,就是不符合第二范式的,
因此,拆分为这三张表,快递信息表中都是和快递相关的字段,商品信息表中都是和商品相关的字段,快递项目表则是快递和商品的关联表,每张表中非主键列都依赖于主键的全部,此时,就是符合第三范式的,
第三范式,理论概念是在第二范式的基础上,数据表中不存在非关键字段对任一候选关键字段的传递函数依赖,即除了主键外,其他字段必须依赖主键。如下例子,“爸爸”是主键,但是“儿子的玩具车”和“儿子的玩具枪”依赖的是“儿子”,并不依赖于主键,存在传递函数依赖的关系,因此不符合第三范式,
可以拆成这两张,每张表中的非主键字段,都只依赖于主键,不存在传递函数依赖的关系,因此这是符合第三范式的,
符合第三范式的表设计,可以说是从理论层面比较纯粹的设计了,但在实操层面,这种设计,未必一定可行。其实无论是数据库设计,还是系统架构的设计,都是为了业务需求服务的,都需要考虑实际的业务场景,仅从理论上考量,有时候未必能够满足业务的需求。
例如在第一范式中的例子,如果你的需求,会根据“区”、“路”进行检索,“详址”字段,当前的设计还可以继续拆,究竟什么是“单一属性”的粒度,还是取决于业务场景。例如在第二范式的例子,拆成了三张表,确实结构清晰,但是可能每次检索快递和商品信息的时候,都需要三表关联,如果数据量很大,表的字段属性再复杂些,对性能造成的影响就会更明显,此时,根据业务场景,向表中冗余一些字段,虽然违反了范式,但是能在满足业务需求和性能需求中得到平衡,可能就是一种更合适的方案。
因此,无论何种范式,都是理论基础,在实操过程中,还是要考虑实际业务场景的需求,有时候就需要“反范式”,套用一句广告词“没有最好的设计,只有最合适的设计”。