数据库范式

简介: 最近在开发新系统,理解业务,开始设计数据表结构;寻找实体,确定实体间的关系及关系属性梳理业务功能接口逻辑,其实也就是这个功能操作了哪张表的哪个字段没有传说中的面向对象分析,DDD实践,流行的微服务玩法也许,好久没有从零开发系统,很久没有亲手新建数据库表沉默十秒钟,感觉像回到了学校,做个类似留言板,BBS类的学生系统;不是鄙视学生时代,而是有些恍惚多年的工作经验,恍如做了个梦,现在设计的表结构与一名实习生有什么区别呢?

最近在开发新系统,理解业务,开始设计数据表结构;

寻找实体,确定实体间的关系及关系属性

梳理业务功能接口逻辑,其实也就是这个功能操作了哪张表的哪个字段

没有传说中的面向对象分析,DDD实践,流行的微服务玩法

也许,好久没有从零开发系统,很久没有亲手新建数据库表

沉默十秒钟,感觉像回到了学校,做个类似留言板,BBS类的学生系统;不是鄙视学生时代,而是有些恍惚

多年的工作经验,恍如做了个梦,现在设计的表结构与一名实习生有什么区别呢?


创建数据库表,想起了数据库范式理论,脑中一片空白呢。不得不来温习一下

范式

范式来自英文Normal form,简称NF。要想设计—个好的关系,必须使关系满足一定的约束条件,此约束已经形成了规范,分成几个等级,一级比一级要求得严格。满足这些规范的数据库是简洁的、结构明晰的,同时,不会发生插入(insert)、删除(delete)和更新(update)操作异常。反之则是乱七八糟,不仅给数据库的编程人员制造麻烦,而且面目可憎,可能存储了大量不需要的冗余信息

范式其实就是规范,这个规范还分了等级,等级越高越规范

从上面的定义可以看出规范,规范标准是要让数据库简洁,结构明晰,不要出现冗余

三大范式

第一范式

当关系模式R的所有属性都不能再分解为更基本的数据单位时,称R满足第一范式

第一范式讲究的是原子性,但这也跟需求相关,比如常使用的示例:

(username,address) values ("张三","江苏省南京市码农大道100号")

这儿的地址不具有原子性,需要拆分成(username,省,市,详细地址)

但如果需求不可能出现对省,市查询、分类,那其实没有必要拆分,也没有不合第一范式之说


这儿引申出一个逆向思维:两列的属性相近或相似或一样,那就得合并

(箱子编号,物品1,物品1数量,物品2,物品2数量)

这种结构满足第一范式吗?从设计上有两个弊端,物品少时会冗余;物品多时会存储不了

这只能行转列,再建新表

第二范式

如果关系模式R满足第一范式,并且所有非主属性都完全依赖每一个候选关键属性,称R满足第二范式

第二范式主要是部分依赖问题

如一个电商卖家对接到个各电商平台,存储订单信息,如果所有订单都来自一个平台,可以使用“平台订单号”作为主键;如果来自多个平台,各平台的订单号可能重复,所以可以使用“平台+平台订单号”作为主键

平台 订单号 金额 对接人邮箱
京东 123 618 dongge@jingkong.com
VIP 145 419 yage@vip.com
VIP 231 345 yage@vip.com

主键“平台+订单号”可以决定金额,但对接人邮箱只依赖于“平台”

不满足第二范式:

  1. 数据冗余:每条记录都含有相同数据
  2. 删除异常:比如删除所有VIP平台信息,那平台的对接人邮箱也被删除了
  3. 插入异常:没有订单,无法插入一个平台的对接人
  4. 更新异常:调整平台对接人,需要更新平台全部记录

经常在建表时,会有一个毫无业务意义的自增字段作为主键,这样就保证了第二范式,因为主键只有一个属性,不存在真子集。同时,应当把非主属性和原来它依赖的“主键的子集”单独建表,如上表,需要加一张(平台,对接人邮箱)表

第三范式

设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式

第三范式主要是传递依赖

Student(学号,姓名,年龄,所在院校,院校地址,院校电话)

学号可以确定一个学生及所在院校,但所在院校确定院校地址与院校电话

这儿需要把传递依赖项独立建表(所在院校,院校地址,院校电话)

不满足第三范式:

  1. 数据冗余:院校信息重复
  2. 更新异常:有重复值,修改时需要修改多条记录,否则数据不一致

为什么范式

范式还有很多,但一般达到第三范式基本就合格了;

为什么需要范式呢?

从范式定义来讲,范式就是为了结构明晰,不出现冗余

从上面的范式递进来看,背后逻辑都体现在消除冗余,一旦出现重复数据,就想办法把这些数据抽离出独立表

在程序中,也是类似的,抽取公共部分,确定不变的,封装好变化的,保持代码简洁

那是不是必须要完全满足范式规定呢?

范式化优缺点

优点:

  1. 可以尽量减小冗余
  2. 数据表更新体积小
  3. 范式化的更新操作比反范式更快
  4. 范式化的表通常比反范式化更小

缺点:

  1. 对于查询需要对多个表进行关联,导致性能降低
  2. 更难进行索引优化

反范式化优缺点

优点:

  1. 可以减小表的关联
  2. 可以更好地进行索引优化

缺点:

  1. 存在数据冗余及数据维护异常
  2. 对数据修改需要更多成本

选择

从范式优缺点看,范式也不是个银弹

比如

student(id, name),

class(id, description),

studentclass(studentid, class_id)

三张表,这样是符合数据库范式的(第一范式,第二范式,第三范式,BC范式等),没有任何冗余

如果需要列出学生的class信息,一次需要三张表的join

join性能差,那也得分三次查询

那我们可以用一张大表代替它

studentclassfull(studentid, classid, name, description)

这样name和description可能要被存储多份,但是由于不需要join了,查询的性能就可以提高很多了。

减少join除了直观地降低了高并发状态下的资源消耗外,更大的好处是降低了业务之间的耦合,增加了扩展性。

拿前面的例子来说,如果我们避免了join操作,就可以拆分成多个库,便于在一方负担过重时进行增配;或者直接改为异构、使用缓存;甚至编写独立服务成为其他业务调用的公共接口,尤其现在流行微服务架构


范式,不仅结构清晰,避免冗余,更重要的保持了一致性

如果表中存在数据冗余,同一份数据存在多个副本,是很难从逻辑上保证一致性,从应用上保证一致性,就增加了系统复杂性,所以在性能前,也不能肆意地“去规范化”

至少“去规范化”是建立在对“规划化”和应用场景的熟悉理解,对数据模型的深入思考的基础之上做出的权衡

尤其很多网页数据以表格形式显示,直接以看得见的样子建数据库的表,将会导致应用系统内部一塌糊涂,开发时举步维艰

从工程落地角度看:需求>性能>范式;但从分析角度看:需求>范式>性能


最近也是天天思考着数据模型和它们之间的关系,实体也就6个左右,各实体都有关系;系统看着也不是很复杂,花了两天才确定结构,有点能力触顶呢

抓住核心,确定主次

宽表以CQRS来实现,减少操作数据时,处理更多的表数据,增加系统复杂性,貌似CQRS就带来了复杂性


其实这篇想写更多,如NOSQL,冗余方式;篇幅太长了,再写一篇!


目录
相关文章
|
存储 关系型数据库 MySQL
轻松入门MySQL:数据库设计之范式规范,优化企业管理系统效率(21)
轻松入门MySQL:数据库设计之范式规范,优化企业管理系统效率(21)
526 0
|
存储 数据库
数据库设计三范式
三范式设计的最终目的都是为了减少我们的工作量,所以说,尽管三范式是一种很好的指导规范,但在实际应用中,我们也不需要太局限在三范式中,更多的是应该从项目中出发,设计出合理的表结构。
|
数据库
数据库三范式
数据库设计中的三范式(1NF、2NF、3NF)用于规范数据结构,减少冗余。1NF 要求字段不可再分,保证原子性;2NF 消除部分依赖,确保非主键列完全依赖主键;3NF 消除传递依赖,非主键列只能依赖主键。遵循三范式可提升数据库的完整性与效率。
524 1
|
SQL 安全 关系型数据库
数据库安全管理新范式:DBKEEPER一体化数据库权限管控堡垒机解决方案
在数字化时代,数据库安全至关重要。DBKEEPER提供一站式数据库安全访问与权限管控解决方案,支持多种数据库,具备精细化权限管理、数据脱敏、高危操作拦截、全面审计等功能,助力企业实现智能、安全的数据治理,满足金融、医疗、互联网等行业合规需求。选择DBKEEPER,让数据库安全管理更高效!
数据库安全管理新范式:DBKEEPER一体化数据库权限管控堡垒机解决方案
|
存储 数据库
数据库设计三范式
数据库设计三范式
241 0
|
存储 关系型数据库 数据库
关系型数据库设计范式:深入理解与实践
【7月更文挑战第20天】关系型数据库设计范式是数据库设计中的重要指导原则,它通过一系列规范来减少数据冗余、提高数据一致性和优化查询性能。在实际应用中,我们应该根据具体需求和数据特点,灵活选择和应用不同的范式级别,以构建高效、可靠和可扩展的数据库系统。同时,也需要注意范式设计带来的挑战和限制,根据实际情况进行权衡和调整。
|
存储 Java 数据库连接
数据库三范式详解及应用
数据库三范式详解及应用
|
存储 Java 数据管理
数据库三范式设计与规范化过程详解
数据库三范式设计与规范化过程详解

热门文章

最新文章