前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据库范式

数据库范式

作者头像
码农戏码
发布2021-03-23 11:22:40
3580
发布2021-03-23 11:22:40
举报
文章被收录于专栏:DDDDDDDDD

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

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

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

没有传说中的面向对象分析,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,冗余方式;篇幅太长了,再写一篇!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农戏码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 范式
  • 三大范式
    • 第一范式
      • 第二范式
        • 第三范式
        • 为什么范式
          • 范式化优缺点
            • 反范式化优缺点
              • 选择
              相关产品与服务
              数据库
              云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档