MySQL应用技术1 — MySQL架构简介
MySQL应用技术2 — 事务简介
MySQL应用技术3 — MVCC
MySQL应用技术4 — 数据类型选择
MySQL应用技术6 — 数据库中的锁
MySQL应用技术7 — 性能优化简析
概念介绍
约束 :约束是用来限定表中数据准确性、完整性、一致性和联动性的一套规则,在mysql中,约束保存在information_schema数据库中的table_constraints中,可以通过该表查询约束信息。
范式:设计关系数据库时,需要遵从不同的规范要求,设计出合理的关系型数据库,这些不同规范要求被称为不同的范式。
数据库中的五大约束如下:
-
primary key 主键约束:唯一性、非空性
主键可以是任意的类型,一般我们使用整数或字符串类型,并且最好使用与业务无关的列作为主键。 -
unique 唯一约束:唯一性、可以空
每个值只能有一个,但其中Null可以有多个 -
foreign key 外键约束:需要建立两表之间的关系
(1)只有INNODB的数据库引擎支持外键
(2)外键与参照列的数据类型必须相同。(数值型要求长度和无符号都相同,字符串要求类型相同,长度可以不同);
(3)设置外键的字段必须要有索引,如果没有索引,设置外键时会自动生成一个索引。
【 在web开发中,一般要求不能使用外键,因为会严重影响插入及更新等操作的性能。对于需要有外键约束的逻辑,应当在web的应用层完成校验。】 -
check 检查:指定一个表达式,用于检验指定数据
【 MySQL不支持check约束,但可以使用check约束,而没有任何效果】 - not null 非空约束:指定某列不为空
数据库中常见范式
首先我们来构造一个场景来以便于下面理解123范式以及bcnf范式
我们有一份 学生的 学号,姓名,专业,辅导员,科目,成绩 这么6列的基础数据
第一范式
所谓第一范式(1NF)是指在关系模型中,对于添加的一个规范要求,所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。
【如果我们将 专业和辅导员 合为了一列,那么就是我们违反了第一范式。基于第一范式,我们一定是将这6个值分别放在6个不同的列中。】
第二范式
在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)
【如果我们有一张语文课成绩表, 记录着 学生姓名,成绩。这两列,但是学生姓名会重复,那么就会出现 张三,100分 张三,95分 这样的情况。第二范式更多的是对候选码选取的要求,要求候选码应当是不可重复的,比如这里应当使用 学生id列,而非学生姓名列。】
第三范式
在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
【简单来说,就是不要在一张表中去冗余过多信息,比如说学生表里只需要有专业列,而不要有辅导员列(一个专业一个辅导员),应当表现为两张表,专业表和学生表。当然前面的简单来说其实并不严谨,跟bcnf范式进行对比即可的值】
巴斯-科德范式(BCNF)
在3NF基础上,任何非主属性不能对主键子集依赖(在3NF基础上消除对主码子集的依赖)
【传递依赖指的更多的是像第三范式中举得例子,就是一列的值可以由另一列非主属性去唯一确定的。那么除了这种还有啥情况呢。比如说我学生表中除了 学生id,学生姓名,学生性别,生源所在地 还有一列表示学生的 毕设分数 。那么问题来了,有些学生还没毕业,那一列就必需是null了。然而前面的列都必然不是null,这时候我们如果将学生id,毕设分数 专门拆一张表,那么就更能节省数据空间(null都不用存,这一行都不存在)】
反范式
【然而,看了这么多规则之后,我们会发现,我们设计的数据库都不咋合理啊。都没有遵循这么些个范式,那么是我们设计的不对嘛。其实不然,对于应用开发而言,适合的才是最好的,范式只是起到指导作用,当再三考虑之后,如果认为违背某个范式更好,那么就那么做吧(一定要再三考虑)。】
下面来讲2个常见的违背范式的例子
- 某一列中存储集合,比如说订单表中在那个存储了这个订单使用了哪些优惠券id,是存储的用逗号分割的优惠券id,这完全违背了第一范式要求的每一列是一个不可分割的原子,因为我们没有根据优惠券id去查询订单的场景,所以就必要去新建一张订单id,优惠券id的中间表。我们只需要展示订单的时候,知道使用了哪些优惠券,web应用拿到逗号分割的字符串后,自行在内存中做一下处理转换成集合即可。
- 违反第三范式的冗余存储,比如说学生成绩表中,除了学生id,一般也会冗余存储学生姓名。这样方便展示的时候,不用再次进行连表操作,也方便了查询时以学生姓名为条件进行查询。是一种常见的以空间换取时间的策略。
总结
其实对于范式与反范式而言,我们更多的是混合去使用,在时间与空间上达到一个平衡的状态。而对于某些较为复杂的查询或者报表,应当考虑使用NoSQL这种结构化数据库,而非关系型数据库。
而对于数据库技术选型及字段设计的依据,并没有一套绝对行之有效的准则,更多的还是要依据 数据量级,服务面相的人群,数据变动的频率,数据查询的场景,对稳定性的要求 等各种因素去综合考量。这里我也只是是举出简单的场景,然后进行讲解。还希望大家能有所收获
网友评论