数据库表的软硬关联_Jimmy的关系型数据库设计心得 第一版

0fdad0316a3e601bedf13b3686ffece5.png

欢迎关注Jimmy的公众号:Jimmy嘚啵嘚,每周都有很多干货文章分享(最近比较懒,先保证每周写几篇,等忙完了再每日更新)

最近在梳理以前设计关系型数据库的心得体会,或者斗胆说是方法论,梳理出一些感觉比较干的东西,跟大家分享,以后我继续成长进步了,还会逐步更新,希望能对从事这个行业的同学有所帮助。

数据库类型的选用就不用我多说了,就是根据业务流程和数据特点,确定是用关系型还是非关系型数据库,对于非关系型数据库还要根据数据特点确定数据库存储类型,比如文档存储的mongodb,key-value存储的redis,或者图存储、列存储、对象存储、xml数据库等,都有对应的产品,不过最常用的还是mongodb和redis。

今天不谈非关系型,只看关系型数据库怎么用,怎么设计他的表结构。

一、什么时候适合用关系型数据库

关系型数据库的特点是:

  • 数据高度组织化、结构化
  • 可以使用结构化查询语言(SQL)进行多表关联查询
  • 满足ACID要求:原子性、一致性、隔离性、持久性

非关系型数据库的特点是:

  • 数据不需要高度结构化、模式化,可以灵活扩展,存储形式也比较多样(文档存储、列存储、key-value存储、图存储、对象存储、xml存储等等)
  • 没有声明性查询语言,通过内部算法调优可以满足超大数据的快速查询
  • 依据CAP定理,分为满足CA原则、CP原则、AP原则的三大类NoSQL数据库,不满足ACID要求,满足BASE要求(基本可用、柔性事务、最终一致性)
  • 也正是因为CAP定理,非关系数据库在集群支持上更灵活,也适合超大数据量的存储。

因此,我们在做一些结构比较固定、数据之间的关联性比较强的数据时,可以用关系型数据库,比如用户信息管理、商品价格管理、交易流水管理等。

那这个时候心细的同学肯定会问:这些数据用MongoDB的JSON型文档不也一样搞得定吗?

是的,所有用关系型数据库表格存储的数据,用JSON格式都可以完美存储,那MySQL这种关系型数据库和MongoDB这种JSON文档非关系型数据库之间的使用场景到底有什么区别呢?

注:这里MySQL是最常用的,阿里云上主推的关系型数据库之一,所以我们用这个来示范。

我们首先来看MySQL和MongoDB中数据都是怎样存储的:

e72eb16139457762ea30287f46c1cea7.png

MySQL用表存储数据,如下图中的左边示意,MongoDB用文档集合来存储数据,即写成JSON的格式,如下图的右边示意:

864ce0a7ce06bbc8b896568cf6d48f1f.png

在查询时,由于关系型数据库的结构型查询机制,无论你用查询表中的哪一个column作为条件筛选(SQL where语句),速度都很快,还可以通过针对某些column建立索引,进一步增加速度。

而对于MongoDB来说,collection中的document是按照 _id field来建立的索引,所以在按_id检索时,速度会非常快,但是如果按其他 field 检索或筛选,在document非常大时,可能就会很慢;并且MongoDB是允许不同的document拥有不同的field的,这样检索还要判断这个document是否具有这个field,效率就不如MySQL了。

总结:

  • 如果你的数据需要结构化查询,就用关系型数据库;
  • 如果需要记录大量结构不固定的信息,而且不需要结构化查询,就用非关系型数据;

二者结合起来可以满足更多复杂系统的数据库设计。

二、基本准则

这里推荐一本书:《MySQL管理之道:性能调优、高可用与监控》

结合我自己的经验,给出2点我认为比较重要的:

1、不用外键,多用索引

不要使用外键,因为如果系统过于复杂,表的数量过多,外键关系过多,会让增删改查变得非常缓慢。因为每一步操作都要去验证外键的依赖关系,如果表中的数据记录特别多的话,是很浪费时间的。

我们一般使用代码来保障逻辑上的外键约束关系,而不是用外键。(后面的例子中会详细讲解如何使用代码保障逻辑上的外键约束关系)

我们在使用代码约束外键关系时,为了提高查询速度,还要使用索引功能,即以某个column建立索引,这样在用这个column作为筛选条件查询数据时,就会提高查询速度。

注:外键和索引的区别大家可以自行百度,本来想画个图,后来觉得我好懒,就算了。

2、表不要太大,要满足第三范式

啥叫第三范式?这事得从第一范式说起。

第一范式:数据库表中的字段都是单一属性,不可再分。

第二范式:在满足第一范式的基础上,实体的属性完全依赖于主关键字。

第三范式:在满足第二范式的基础上,不存在非关键字段对任意候选关键字段的传递函数依赖。

干不干,硬不硬,这概念多清晰。。。。貌似还是不好理解,这次我不偷懒了,上栗子:

例如我们要对如下信息建表:

病人编号,病人姓名,性别,出生日期,挂号单流水号,就诊记录,联系方式,医生编号,医生姓名,医生性别,职称,科室编号,负责人,诊室号

按照满足第三范式的要求,建表如下:

9c5cbafe60be07f632afb8a9dc2ee720.png

其实我在列举这些信息时,已经满足第一范式了,每一个信息都是单一属性的,不可再分。

然后按照第二范式,提取出4个主关键字(分类):病人、医生、科室、挂号就诊,其他所有信息都和这四个主关键字有关(完全依赖其中的某一个),因此我们建立4个表:病人信息表、医生信息表、科室信息表、挂号就诊信息表。

备注:在实际操作中,既可以先把所有要记录的信息列出来,再分类,也可以先分类,然后按类列举所有要记录的信息,但是在列出所有的信息后,还是要重新按照第一范式的要求去拆分去重所有的信息,然后按照第二范式去提取主关键字(分类)。

下一步,审视这四张表之间的关系(聚合、关联等),通过我们前面提到的“逻辑外键约束”的方法,将这四个表建立联系:即医生和科室之间构成聚合关系;病人和医生构成关联关系,它们通过挂号就诊信息表进行关联。

建立完成后,检查下每个表中的字段是否和其他字段构成函数依赖关系,所谓的函数依赖关系,就是 y = f(x),y字段可以由x字段推导出。

检查没问题,就完成了一个满足第三范式的建表。

备注:对于数据库建表,我们一般使用UML图来描述,一方面直观清晰。上图中我们用到了一些UML中的关系图示,下面我会详细说明最常用的2个关系及其图示,读完下面一章,再回过头看这个数据库UML图,就很清晰了。

三、两种主要的建表方法

在建表实践中,有2中方法非常重要,基本上灵活交叉使用这2种方法,就可以解决大部分复杂问题。

1、聚合关系反向建表

在上面的例子中,医生和科室有这样的聚合关系:一个科室包含多个医生,一个医生只属于一个科室:

630d0e632e66f7bb3a963b2092e8e020.png

对于这样的情况,可以用聚合关系反向建表,如下面的UML图示,这里用的是菱形实线表示聚合关系:

ffd4f2f79acc5d1c48d60f84a5058538.png

这里医生信息表中的“科室编号”,由代码保证它在逻辑上是以科室信息表中的主键“科室编号”作为外键的。

所谓的代码保证,即在为医生信息表写入或修改数据时,需要查询写入或修改记录的科室编号是否在科室信息表中,如果在,才能执行写入或修改操作,否则不执行并报错。

2、关联关系建表

对于上面的例子中,医生和病人有如下的关联关系:一个医生可以给多个病人看病,一个病人也可以找多个医生看病:

75348989fcd5e1970aa543c0efdeba31.png

对于这种情况,可以用第三个表——挂号就诊表,将医生和病人关联起来,UML图示如下所示,这里用的是箭头虚线表示关联关系:

e8975cf37a064f44bdffb09f165dd7b3.png

同样,用代码保证,挂号就诊信息表中的“病人编号”以病人信息表中的主键作为外键,“医生编号”以医生信息表中的主键作为外键。

四、总结

本文主要讲了一些我个人在设计关系型数据库时的心得体会和设计原则,比较简单,足以应付大多数业务。

当然,这个内容我也会持续更新,以后如果我的水平有提高了,有了新的心得体会,也会更新这篇文章,出新版本。

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

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

相关文章

83998 连接服务器出错_来申请一个阿里云服务器玩玩?

对开发有兴趣的小伙伴们可以去阿里云官网申请一个免费入门级的服务器小试身手。那么如何申请免费服务器呢?(这里吐槽不能超链接外部网页)进入官网这里我选择了左边的(体验时间长一点)选择Ubuntu 14.04 32位的系统(上面的地域选择可以百度一下自己的地理位置适合选择…

安卓项目打开有时候manifests不见了_手机通话音量太小?教你打开这个开关,再也不怕听不清了...

分享最实在的玩机技巧,洞察最前沿的科技资讯!大家好,这里是手机科技园!我们在生活中,经常用手机与家人朋友通话,可是有时候即使将音量开到最大,通话声音还是非常小,这到底是为什么呢…

为什么自己编写的页面总是在那里抖动_「内存抖动」?别再吓唬面试者们了行吗...

视频版本 本文在 B 站有对应的视频,如果你喜欢看视频版本,可以点 这里 去哔哩哔哩观看,或者点 这里 去 YouTube 观看。从「内存抖动」说起 面试官:你做过性能优化是吧。面试者:嗯是的,在卡顿和耗电问题上做…

vba 循环读取单元格_利用VBA打开顺序文件,并读取

大家好,疫情施虐,国外各地更有爆发的迹象,但无论怎样,我们一定要坚信,疫情终将会过去,曙光一定会到来。后疫情时代将会是一个全新的世界,很多理念都将被打破,大多数人不会再享受体制…

opcua客户端实现断线重连_虹科教您|实现OPC UA C/S快速部署及数据采集

想获取更多IIOT干货请点击蓝字,关注我们虹科HMI解决方案高性能高防护宽温★★★★★简介边缘HMI需要实现的主要功能包括连接到该边缘HMI的边缘设备的数据采集,实现边缘计算、提供人机接口、数据的本地存储与上传。在工业4.0的进程中,越来越多…

特征级融合_遥感影像融合的方法有哪些

遥感影像融合的方法有哪些 多种名称,常见的有 图像复合(Image Fusion) 影像融合(Image Merging)、 数据复合(Data Fusion)、 数据综合(Data Integration)、 影像综合(Image Integration)、 信息复合(Information Combination) 目的:把那些在空间和时间上…

最大值减最小值等于区间长度_呆哥数学每日一题 ——三角函数求余弦最小值...

如果想要获取往期每日一题电子版,可以加我微信:daigemath166,备注:知乎 每日一题呆哥解析:今天我们来看一道三角函数求余弦最小值的题目这里条件只有一个,那么我们第一步就是应该把两个角联系起来&#xff…

go channel 缓冲区最大限制_Go语言11周年,泛型问题有望明年得到解决

作者 | 田晓旭、万佳 近日,Go 团队发布长篇博文庆祝 Go 语言开源 11 周年。 Go 团队在博文写道,“回想 Go 语言十周年庆典恍如隔世。虽然 2020 年有诸多艰难,但我们一直在推动 Go 语言的发展,其中有不少值得回忆的美好瞬间。”1 G…

深度linux 转中文,Linux Deepin 中文Linux系统的新希望?

Linux Deepin 中文Linux系统的新希望?出处:快科技 2010-08-02 22:51:18 作者:Plum 编辑:Plum[爆料] 收藏文章前言说到国产系统,我们想到的东西可能并不多,在这个Windows垄断的领域,国产的空…

耳机不分主从是什么意思_无延时音质好的蓝牙耳机能代替有线耳机吗—DOSS T60上手体验...

伴随着手机的更新迭代,大概是从iPhone 7的时候大家开始对手机是否有3.5mm耳机孔这个问题开始纠结起来,好像是从真无线耳机出来时大家又对3,5mm耳机孔又不是那么的纠结。此一时彼一时,大家为何对耳机接口为何有这么大的转变,就拿今…

switch安装linux教程,Freeswitch Linux安装教程 | 【韩涛博客】

大家都有一个经历,经过漫长的编译后,各种报错,经过整理后,我总结出了以下无错步骤:(一)安装编译所需要的环境包yum install -y autoconf automake libtool gcc-c ncurses-devel make zlib-devel libjpeg-devel(二)安装…

python软件如何安装方法_【新手必看】Python软件下载及安装教程

原标题:【新手必看】Python软件下载及安装教程 Python下载:免费开源 官网地址:https://www.python.org/downloads/ 下载对应版本Python:python-3.6.1-amd64.exe(我的电脑是window 7-64位),所以我…

如何下载linux历史版本下载,CentOS历史版本下载方法

实验室要求统一Linux版本,原来我用的是Ubuntu,现在我在的实验室是centos,我也就只能改了。实验室和个人不同,个人的Linux版本可能经常换,只要有新的版本出来,我就会去下载下来,在虚拟机里面试一…

table超出边框出现滚动条_精美横轴智能滚动条设计

如何设计一款精美的横轴智能滚动条?本文对设计过程进行了详细地介绍。页面布局页面设定新建一个页面文件,命名为【精美横轴智能滚动条设计】。在【精美横轴智能滚动条设计】页面内新建一个命名为【table】的动态面板。【底层背景】:从元件库内…

如何在python中安装matplotlib模块_Windows下为Python安装Matplotlib模块

这玩意反反复复弄了一晚上,这里详细叙述下如何安装,肯定会对大家有所帮助。首先默认大家都装了Python,这个从官网下基本不会有任何难度。 (1)Setuptools的安装 为啥先说这个,后面所有whl文件都要用这个安装…

马冬晗学习计划表_一年时间提升学习和工作能力,我做对了这3点

文 / 小椰子 昨晚和朋友去大排档吃宵夜,酒足饭饱之后,发现他两眼无神地盯着桌上的空啤酒瓶:“讲真,毕业后出来工作这一年多,我好几次想重新回去读书。”我诧异地看着他,静静地听他继续说下去。“现在的自己…

python编写递归函数、求斐波那契数列第n项_python使用递归求斐波那契数列中第n个数的值...

原博文 2019-11-29 16:33 − def byh(n): if n 1 or n 2: return 1 return byh(n-1) byh(n-2)print(byh(8)) #1,1,2,3,5,8,13,21,输出结果:21... 相关推荐 2019-12-12 14:08 − 使用range函数生成数值列表 使用range函数打印1~5的数字 for i in range(1,6): prin…

sqlsugar 批量删除guid类型主键_SAP使用MASS批量修改主数据

由于公司业务部门需要,向我提出的这个要求,我就在网上查了下,看到了一位知乎的前辈大神写了,自己测试了下把过程更详细的记录了一下,也挺好用,就在这里记录和分享一下,便于以后查看。业务场景&a…

kali linux 搜狗输入法,kali_Linux下安装搜狗输入法

1. 由于我的虚拟机里kali是32位,如果64位系统就找对应的安装包。依赖软件下载地址:http://http.kali.org/pool/main/f/fcitx/1 ) dpkg -i fcitx-libs_4.2.8.4-3~bpo701_amd64.deb2 ) dpkg -i fcitx-libs_4.2.8.4-3~bpo701_i386.deb3 ) dpkg -i fcitx-l…

python数据库操作sqlite_使用Python对SQLite数据库操作

原博文 2017-04-05 15:25 − SQLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在IOS和Android的APP中都可以集成。 Python内置了SQLite3&…