一个三线城市的国企码农,酷爱技术,在这里和大家分享在国企搞技术的点点滴滴。欢送大家关注我的微信公众号:果冻想
前言
每天开各种会议,这不刚刚完结的组织生活会的批评环节,我又收到了一条批评,说我技术分享不多,不够,没有无效起到传帮带的作用。好吧,当前就把这些日常的传帮带都总结起来,发到这里,作为一个记录,也以备组内小兄弟们后续翻阅查看。
这几天在整顿数据库表的时候,看到之前的撑持方建的那些表,几乎不忍直视,齐全没有逻辑可言,反正就是一堆货色都放到一个表里,不晓得大学数据库实践是怎么学习的。明天在和组内小兄弟们沟通时,就说起这个货色,正好波及到数据库的三范式,就顺带总结下来。
数据库三范式
这个货色是一种关系型数据库设计实践实践准则,也不是说必须去恪守,只是说咱们在进行数据库建模时,按着这个实践来执行,会更迷信一点,会更正当一点,后续扩展性会更强一点;并且能在很大水平上打消数据冗余和数据依赖性,进步数据库的性能和数据一致性。
所以,这套实践有这种那种的长处,咱们在进行关系型数据库建模时,也根本都是依照这个实践来执行的,至多依照这个来,做进去的货色不会太差。
三范式的定义:
第一范式(1NF):确保数据库中的每个列都是原子性的,即每个列都不可再分。
第二范式(2NF):在满足第一范式的根底上,确保数据库中的每个非主键列齐全依赖于主键。
第三范式(3NF):在满足第二范式的根底上,确保数据库中的每个非主键列都不传递依赖于主键。
以上是三范式的定义,可能不是很好了解,上面通过具体的数据库建模实例来进行阐明。
第一范式(1NF)
第一范式(1NF)要求的是列的原子性。这样讲可能不太好了解,当初有上面这样的一个地址表:
地址 ID | 地址详情 |
---|---|
202311212056485430000081 | 内蒙古呼和浩特市新城区团结小区 7 号楼 |
202311231036360980000279 | 内蒙古呼和浩特市赛罕区万达一区底商 101 |
联合第一范式(1NF)的定义,很显然,地址详情
这列蕴含的信息量很大,显然是能够拆分的。依照第一范式(1NF),咱们进行以下拆分:
地址 ID | 省 / 自治区 | 地市 | 地区 | 小区名称 | 楼栋 | 门牌号 |
---|---|---|---|---|---|---|
202311212056485430000081 | 内蒙古 | 呼和浩特市 | 新城区 | 团结小区 | 7 号楼 | |
202311231036360980000279 | 内蒙古 | 呼和浩特市 | 赛罕区 | 万达一区 | 底商 | 101 |
这样拆分完,每个列都无奈进行再次拆分了,同时使得数据库构造更加清晰和易于保护,也有利于前期的经营剖析。
第二范式(2NF)
第二范式(2NF)要求每个非主键列只依赖于主键而不依赖于其余非主键列,具体的利用场景是联结主键(多个字段独特充当表的主键),这里通过以下例子来进行阐明(订单编号和产品编码组成联结主键):
订单编号 | 产品编号 | 购买价格 | 购买数量 | 订单总金额 | 购买工夫 |
---|---|---|---|---|---|
202311212056485430000001 | 202311212056485430000003 | 100.00 | 2 | 230 | 2023/11/21 20:56:48 |
202311212056485430000001 | 202311212056485430000004 | 30.00 | 1 | 230 | 2023/11/21 20:56:48 |
202311231036360980000202 | 202311212056485430000005 | 9.99 | 1 | 34.99 | 2023/11/23 10:36:36 |
202311231036360980000202 | 202311212056485430000006 | 10.00 | 1 | 34.99 | 2023/11/23 10:36:36 |
202311231036360980000202 | 202311212056485430000007 | 15.00 | 1 | 34.99 | 2023/11/23 10:36:36 |
间接看感觉没有什么故障,然而咱们来对上表的字段进行剖析:
- 购买价格:购买价格齐全依赖订单编号 + 产品编号,订单编号 + 产品编号同时确定能力确定购买价格(同一产品在不同的订单会有不同的价格);
- 购买数量:购买数量齐全依赖订单编号 + 产品编号;订单编号 + 产品编号同时确定能力确定购买数量;
- 订单总金额:订单总金额只依赖于订单编号,和理论的产品没有关系,咱们通过订单编号就能够明确订单总金额;所以该字段违反了第二范式(2NF);
- 购买工夫:购买工夫只依赖于订单编号,一个订单的所有商品必定是同一时间购买的,该字段很显著和产品编号是无任何依赖关系的;所以该字段也违反了第二范式(2NF)。
当初咱们进行优化,进行表拆分,拆分后失去两个表:
订单编号 | 产品编号 | 购买价格 | 购买数量 |
---|---|---|---|
202311212056485430000001 | 202311212056485430000003 | 100.00 | 2 |
202311212056485430000001 | 202311212056485430000004 | 30.00 | 1 |
202311231036360980000202 | 202311212056485430000005 | 9.99 | 1 |
202311231036360980000202 | 202311212056485430000006 | 10.00 | 1 |
202311231036360980000202 | 202311212056485430000007 | 15.00 | 1 |
订单编号 | 订单总金额 | 购买工夫 |
---|---|---|
202311212056485430000001 | 230 | 2023/11/21 20:56:48 |
202311231036360980000202 | 34.99 | 2023/11/23 10:36:36 |
这样拆分完后,就合乎了第二范式(2NF),同时数据结构更加清晰,也缩小了数据冗余。
第三范式(3NF)
第三范式(3NF)说直白点就是表中的非主键字段和主键字段间接相干,不容许间接相干。上面通过一个表来进行阐明(主键:部门 ID)。
部门 ID | 部门名称 | 负责人 | 负责人性别 | 负责人年龄 |
---|---|---|---|---|
202311212056485430000001 | 综合撑持部 | 张三 | 男 | 35 |
202311212056485430000002 | 人力资源部 | 李四 | 男 | 41 |
很显著,部门名称和负责人和部门 ID 是间接关联了,而负责人性别和负责人年龄和部门 ID 并没有间接关系,而是和负责人间接关联的,所以就存在这种传递依赖关系了。
部门 ID-> 负责人 -> 负责人性别
部门 ID-> 负责人 -> 负责人年龄
这就违反了第三范式(3NF),这个时候就须要把上表拆分成两张表,以外键模式关联。如下所示:
部门 ID | 部门名称 | 负责人 ID |
---|---|---|
202311212056485430000001 | 综合撑持部 | 202311212056485430000003 |
202311212056485430000002 | 人力资源部 | 202311212056485430000004 |
负责人 ID | 姓名 | 性别 | 年龄 |
---|---|---|---|
202311212056485430000003 | 张三 | 男 | 35 |
202311212056485430000004 | 李四 | 男 | 41 |
这样拆分后,构造立马清晰了,每个表存储的数据也都是繁多的。
总结
在日常开发中,咱们少不了进行功能模块的数据库建模,而数据库三范式是设计数据库表构造的规定束缚,通过遵循三范式,能够缩小数据冗余、进步数据的一致性和准确性,并且简化数据库的设计和保护。
然而通过下面的剖析,咱们遵循了三范式,就会多了好几张表,导致在一些业务简单的场景,就会呈现多表关联查问效率低的问题。所以,有的时候进行零碎性能优化时,也会突破三范式规定,进行部分变通,做到依据具体业务场景活学活用。
但凡事都有一个然而,然而在理论开发中容许部分变通。
一个三线城市的国企码农,酷爱技术,在这里和大家分享在国企搞技术的点点滴滴。欢送大家关注我的微信公众号:果冻想