数据库设计-规范化规则

SQL反模式一书在附录章节给出了设计关系数据库的规范化规则,一个简明的规范化规则清单。

关系是什么

在规范化之前,我们先要理解下关系。

数学中关系定义:两个不同数据域上的值的集合,通过一个条件得到的一个所有可能组合的子集。

怎么理解呢?书中以棒球队和城市举例,比如有一个包含所有棒球队的集合,还有一个包含所有城市的集合,

如果把每个城市和每个球队随意组合进行列表,列表会很长,但其实我们只需要关注“球队和其所属城市的集合”。

所以“关系”:

  1. 作为一种规则,比如城市是指某一支队伍所属城市“
  2. 过滤子集的规则

然后将这个子集存储在数据库一张表中,关系即表示的是表中列与列之间的关系。

数据库表需要满足以下条件:

  1. 行之间没有上下顺序
  2. 列之间没有左右顺序
  3. 重复记录不允许
  4. 每一列只有一个类型,每一行只有一个值
  5. 列中都是数据值,而不是物理存储标识,如Oracle的ROWNUM伪列等

规范化的神话

以下一些对规范化的理解是错误的

  1. 规范化让数据库更慢,不规范让数据库更快
  2. 规范化就是把数据移到子表之中
  3. 规范化就是将属性尽可能的拆分开
  4. 没人需要超过第三范式的规范化标准

很久以前我也是这么认为的,现在经过项目实践以及阅读SQL反模式这本书后,这些观念都是不正确的,比如不规范只能让某一种查询变快,其他业务的查询可能呢个就很困难和很慢,再比如不符合范式使得程序含有了隐藏的Bug。

规范化是保证我们正确的存储数据,保证数据的完整性,如果没有这个基础,就不用谈其他的了。

什么是规范化

书中简明给出了规范化的目标如下:

  1. 以一种我们能理解的方式表示事物
  2. 减少数据的冗余存储,防止异常或者不一致的数据
  3. 支持完整性约束

提供数据的性能并不在以上列表中,但规范化本身保证数据的正确存储,很多时候项目因为错误、不一致、重复的数据出现很多问题,但如果一开始就进行规范化设计,就会避免这些问题,所以在某种程度是提升了效率。

范式

以前只了解一到四范式以及BCNF范式,从本书了解到第六范式和DKNF范式,一般的讲述都是以主键、候选键,主属性、非主属性以及依赖关系来解释范式的,这里了解到不同的解释。

 

第一范式

  1. 该表必须是一个关系,满足前面关系中数据库表的条件
  2. 表中没有重复组合,并不是记录重复,是指一行中可能有多个来自于同一个集合的值,

比如书中以产品缺陷管理举例,如缺陷标签,下面两个图都不满足第一范式。

 

第一个表,tag1、tag2、tag3都是来自同一个集合tag

第二个表,tags字段的值为多个值也是来自同一个集合tag

始终记住:关系中的每一行,都是从多个集合的每个集合中选一个值形成的组合

满足第一范式的如下图:

 

第二范式

  1. 表中存在字段其取值与部分主键字段无关
  2. 表中数据有冗余,更新不当会造成数据异常。

还是刚刚的缺陷标签表,现在要往BugsTags表中增加打标签者以及标签创建者,下图就不符合第二范式

 

tagger字段是打标签者,coiner是标签创建者,BugsTags表是bug_id和tag复合主键,coiner只与tag有关,与Bug是无关的,即只依赖部分主键,并且coiner取值是重复的,所以不符合第二范式。

如果需要修改某个标签的创建者,如果没有修改掉该表中所有tag为该标签的coiner,就会出现数据不一致,这种情况尤其可能出现在多个人同时修改该值的时候。

但是我这里有一个疑问,这张表符合第一范式吗?tagger和coiner字段都应该来账户集合(如Account表),有两列来自相同的集合应该不符合第一范式呢。除非理解标签创建者和打标签者属于不同集合。

而满足第二范式的设计,是增加一个标签表tags,如下图:

 

 

第三范式

第二范式是存在字段只依赖于组合主键中的部分,而第三范式是存在字段不依赖于任何主键,而是依赖其他字段。

如果需要记录处理Bug的工程师的email,下图的设计不符合第三范式:

 

assigned_email与主键bug_id无关,只由assigned_to这个非主键字段决定,所以不符合第三范式,assigned_email取值也是冗余的,也会有更新问题。

符合第三范式的设计是应该把email放到Accounts表中,email直接与主键关联没有冗余。如下图

 

BCNF(博伊斯-科德范式)

BCNF范式与第三范式的差异很细微,在第三范式中,所有非主键字段都必须直接依赖于这张表中的所有主键列,而BCNF范式要求主键字段也必须遵循这个规则,一般在一张表有复合主键时有效。

比如,我们有三种Tag类型,描述Bug所造成影响的tag,描述Bug影响子系统的tag,以及Bug修复状态的tag,且要求每一个Bug对于每一种tag类型只能有一个tag,所以这里可能的复合主键有bug_id加上tag,或者复合主键为bug_id加上tag_type,这两种组合都可以定位到一行。

存在两种复合主键,所以下图的设计就不符合BCNF,


 

这里一个隐含的假设是不同tag_type下的tag是不同的,且一个tag只属于一种tag_type,如果没有这个假设,bug_id加上tag是定位不到一行的。

按照这个假设,以前面符合第二范式和第三范式的设计很项,微妙的差别在于该字段在表中的作用是一般字段呢还是复合主键,符合第三范式的设计如下图:

 

第四范式

    随着业务应用复杂度的提升,比如需要支持多个用户报告同一个Bug,并可以分配给多个开发工程师,然后由多个质量工程师验证。这属于多对多的关系,   所以我们需要额外的一张表,如下图不符合第四范式:

 

这里不能单独使用bug_id作为主键。每个Bug需要多行数据来实现各个字段都支持多个账号的目的,主键需为bug_id、reported_by、assigned_to、verified_by的复合主键,然而bug报告时,是不需要立即进行分配和验证的,所以assigned_to和verified_by需要可以为null,而标准情况下主键是不能为null的。

另外的一个问题就是当报告问题者大于分派者,或者大于验证者就会出现数据冗余。

所以当只用一个表描述多个多对多关系时,就违背了第四范式,正确的做法如下图:

 

第五范式

任何满足BCNF范式并且没有复合主键的表将同时满足第五范式。

比如业务需要指定有些工程师只能为某些产品进行服务。

业务还需要了解哪些工程师在为哪些产品服务,以及修复了哪些Bug,下面的设计不符合第五范式

 

但这个表只说明了这个工程师当前指派去服务哪些产品,它不能说明哪个工程是可以被指派为哪些产品服务

与第四范式一样,也是在一张表中存储多种独立的多对多关系而产生的,微妙的差别是没有null的情况。

bug_id与assigned_to是多对多的关系,assigned_to与product_id是多对多的关系,而bug_id与product_id应该假定是多对一关系存在Bugs表中,每个Bug只属于一个product。

所以解决方案是把每个多对多关系放在一个表中,如下:

 

DK范式

DK范式涵盖了第三、四、五范式和BCNF范式。并认为表上的每个约束是这张表的数据域约束和主键约束的逻辑结果,如何理解呢?

比如状态为新建的bug应该是没有任何工作时间记录的,也不需要指派验证工程师的,一个做法是在状态这个非主键字段上建立触发器或者check约束,来进行验证如果状态为新建,没有值是允许的,其他情况就不允许。但这种在非主键字段建议此约束的做法不符合DK范式。

第六范式

第六范式目标是消除所有的联结依赖,通常用于支持记录字段取值的变更历史。

如Bug的状态随着时间推移产生变化,任何发生的变更,变更的时间,谁做的变更,以及其他可能的细节,需要另一张表进行记录。

可以想象,如果Bugs这张表需要满足第六范式,则需要变更的列都需要附带一个历史记录表,会导致表的数量过多,多于大多业务来讲,为每列变更都建立一个历史记录表是没有必要的,在一些数据仓库技术中会使用到第六范式。

个人体会:规范是为了减少数据冗余、提高数据的一致性必须的,二、三、四、BCNF、五范式的差异很微妙,随着业务系统的复杂度的提升,需要考虑更高层次的范式。

转载于:https://www.cnblogs.com/bwater/p/8203770.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/487041.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI 如果 “智力爆炸” ,只有普通智力的人类是蝼蚁还是宠物?

编译|吴婷婷编审|王新凯出品|学术头条想象一下,当你推倒多米诺骨牌时,第一张牌倒下,而后每一块牌迅速产生反应,直至最后一块牌。实际上,这种连锁反应不局限于物理界,而是…

Java容器---Set: HashSet TreeSet LinkedHashSet

1.Set接口概述 Set 不保存重复的元素(如何判断元素相同呢?)。如果你试图将相同对象的多个实例添加到Set中,那么它就会阻止这种重复现象。 Set中最常被使用的是测试归属性,你可以很容易地询问某个对象是否在某个Set中。…

马斯克脑机接口遭质疑:不是新技术,没体现神经解码进展

来源:AI前线作者 | 李冬梅马斯克的脑机接口实验,一经发布,就引来了诸多关注,业内专家们对此实验的评价却褒贬不一。北京时间 8 月 29 日,Neuralink 公司发布的神秘技术终于揭开了它的面纱,在视频直播中&am…

坯子库和suapp哪个好用_「双全科技」进销存软件哪个简单好用,管家婆进销存软件教程...

进销存软件哪个简单好用,管家婆进销存软件教程随着国家信息化的发展越来越趋于成熟,越来越多的企业需要进销存软件来提高工作效率,企业家们不再采用传统的库存管理模式,进销存管理系统解决了企业日常经营中一系列库存问题&#xf…

吴恩达推荐笔记:22 张图总结深度学习全部知识

来源|Sophia知乎https://zhuanlan.zhihu.com/p/152362317编辑 | 公众号极市平台本文仅用于学术分享,如有侵权,联系后台作删文处理最近在做笔记查阅内容,觉得这个总结太美观了,真是棒!吴恩达在推特上展示了一…

使用nfs映射远程服务器磁盘目录

参考:http://www.centoscn.com/CentosSecurity/SoftSecurity/2015/0408/5118.htmlhttp://www.cnblogs.com/mchina/archive/2013/01/03/2840040.html说明: 本文是在MacOS上做客户端,因为MacOS内核是类Unix,所以本文也适用于Linux客…

ios笔试题算法_微软笔试题-Dijkstra算法

Dijkstra算法是典型的算法。Dijkstra算法是很有代表性的算法。Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表的方式,这里均采用永久和临时标号的方式。注意该算法要求图中不存在负权边。      用Dij…

自动驾驶车通过动作捕捉,学会阅读街上人们的肢体语言

来源:机器学习研究组订阅号 编译:lin想象一下,工人正在修复路面上一个大坑洞,因此拥有四条车道的马路缩小为两车道。一名工人左手松松地举着停车标志,用右手挥手示意汽车通过。如果是人来开车的话,自然不会…

AI解梦成为现实 未来还有无限可能

文章来源:学术头条编译:阳光排版:赵辰霞编审:王新凯古代巴比伦人认为梦境包含了预言,而古埃及人则将梦境视为神灵给予的信息来崇拜。在 19 世纪 90 年代,西格蒙德弗洛伊德(Sigmund Freud&#x…

fiddler工具条、状态栏、请求信息栏各按钮的作用

1.fiddler工具条 2.fiddler状态栏 3.请求信息栏 转载于:https://www.cnblogs.com/kakaln/p/8198299.html

超9成SCI论文发在国外!中文期刊到底差在哪?

来源 | 科学网撰文 | 卜叶编辑 | 宗华学术界不投中文期刊的原因是什么?这一老生常谈的问题,最近再次出现在某知识问答平台热榜。短短两周,便吸引了180个回答,浏览量超过34万。中文期刊到底差在哪?面对逐渐边缘化的态势…

pyqt5 点击开始执行_《快速掌握PyQt5》第一章 PyQt5的起点

1.1 开始安装PyQt5就跟安装其他库的方法一样,非常简单:Windows上安装:pip install pyqt5Linux上安装:sudo apt-get install pyqt5-dev-toolsMacOS上安装:pip3 install pyqt5验证是否安装成功,只需要导入下该…

不用math type解决word公式上浮问题

今天来解决一下文档整理时候令人头痛的公式上浮问题。 问题 就是这种,以前碰见了简直就是无解,今天不管怎样,解决它!! 准备 开始前要检查一下公式是否是office math格式,如果不是,需要先转化成…

前沿研究丨基于驾驶脑的智能驾驶车辆硬件平台架构

本文选自中国工程院院刊《Engineering》2018年第4期作者:李德毅,高洪波来源:A Hardware Platform Framework for an Intelligent Vehicle Based on a Driving Brain[J].Engineering,2018,4(4):464-470.编者按智能驾驶车辆试验平台是人工智能科…

cogs2840. 二叉查找树

二叉查找树 时间限制:1 s 内存限制:512 MB 【题目描述】 二叉查找树是一种特殊的二叉树(每个节点最多只有两个儿子的树)。树的每个节点上存有一个唯一的值,并且满足:这个节点的左子树内所有点的值都比这个…

苹果挂端口方法_调音台变身直播声卡的方法

现在干直播的多了,搞音响的也可以利用自己手头的专业设备,把调音台变身为直播声卡,然后进行多通道的高品质混音直播。需要的条件:数字调音台或带有USB音频功能的模拟调音台苹果手机(本人没有安卓手机,就以苹果手机为例…

word删除所有的回车、空格

一、打开替换窗口 二、①删除回车 在查找内容中输入 ^p 在替换为中输入 ^s 或者空白 全部替换 ②删除空格 在查找内容中输入 ^w 在替换为中输入 空白 全部替换 三、总结 在Word中 ^p表示回车, ^s表示空白, ^w表示空格

xp的viostor驱动无法获取磁盘序列号的分析

深信服的viostor驱动在获取序列号的时候,多了一个IDE处理的代码,位置在1128处。它会在刚开机加载viostor.sys时机被调用,然后去读取注册表HKLM\\SYSTEM\CurrentControlSet\Services\viostor\Parameters的IDESNCompat,若为1则有此功…

十问亿级神经元类脑计算机:AI领域有望突破,哪些还需火候

来源:澎湃新闻近日,浙江大学联合之江实验室共同研制成功了中国首台基于自主知识产权类脑芯片的类脑计算机(Darwin Mouse)。研究团队在9月1日的成果发布会上指出,该类脑计算机在神经元规模上超越了德国海德堡大学的Brai…

网络加载空页面

空页面的显示很常用,所以自己做了一个通用的空页面显示,先看效果图 在有网络的时候正常加载显示,在没有网络的时候自动加载空页面,点击空页面重新加载网络请求的一个功能 1:定义一个xml页面,页面布局是一个…