哈喽大家好,我是阿Q,今天我们来总结一下【MySQL】 入门的必备知识点吧~
文章目录
数据库的基本概念
- 数据库:DataBase 简称 DB,就是信息的集合或者说数据库是由数据库管理系统管理的数据的集合。
- 数据库管理系统:DataBase Management System 简称 DBMS,是一种操纵和管理数据库的大型软件,通常用于建立、使用和维护数据库。
- 数据库管理员:DataBase Administrator, 简称 DBA,负责全面管理和控制数据库系统。
什么是元组, 码, 候选码, 主码, 外码, 主属性, 非主属性?
- 元组:元组(tuple)是关系数据库中的基本概念,关系是一张表,表中的每行(即数据库中的每条记录)就是一个元组,每列就是一个属性。 在二维表里,元组也称为行。
- 码:码就是能唯一标识实体的属性,对应表中的列;
- 候选码: 若关系中的某一属性或属性组的值能唯一的标识一个元组,而其任何、子集都不能再标识,则称该属性组为候选码。我理解的是一个字段或者多个字段组成唯一索引。例如:在学生实体中,“学号”是能唯一的区分学生实体的,同时又假设“姓名”、“班级”的属性组合足以区分学生实体,那么{学号}和{姓名,班级}都是候选码。
- 主码:主码也叫主键。主码是从候选码中选出来的。 一个实体集中只能有一个主码,但可以有多个候选码。
- 外码:外码也叫外键。如果一个关系中的一个属性是另外一个关系中的主码则这个属性为外码。
- 主属性:候选码中出现过的属性称为主属性。比如关系 工人(工号,身份证号,姓名,性别,部门). 显然工号和身份证号都能够唯一标示这个关系,所以都是候选码。工号、身份证号这两个属性就是主属性。如果主码是一个属性组,那么属性组中的属性都是主属性。
- 非主属性:不包含在任何一个候选码中的属性称为非主属性。比如在关系——学生(学号,姓名,年龄,性别,班级)中,主码是“学号”,那么其他的“姓名”、“年龄”、“性别”、“班级”就都可以称为非主属性。
主键和外键有什么区别?
- 主键(主码) :主键用于唯一标识一个元组,不能有重复,不允许为空。一个表只能有一个主键。
- 外键(外码) :外键用来和其他表建立联系用,外键是另一表的主键,外键是可以有重复的,可以是空值。一个表可以有多个外键。
为什么不推荐使用外键与级联?
对于外键和级联,阿里巴巴开发手册这样说到:
【强制】不得使用外键与级联,一切外键概念必须在应用层解决。
说明: 以学生和成绩的关系为例,学生表中的 student_id 是主键,那么成绩表中的 student_id 则为外键。如果更新学生表中的 student_id,同时触发成绩表中的 student_id 更新,即为级联更新。外键与级联更新适用于单机低并发,不适合分布式、高并发集群; 级联更新是强阻塞,存在数据库更新风暴的风 险; 外键影响数据库的插入速度。
外键的缺点
- 增加了复杂性: a. 每次做DELETE 或者UPDATE都必须考虑外键约束,会导致开发的时候很痛苦, 测试数据极为不方便; b. 外键的主从关系是定的,假如哪天需求有变化,数据库中的这个字段根本不需要和其他表有关联的话就会增加很多麻烦。
- 增加了额外工作:数据库需要增加维护外键的工作,比如当我们做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,保证数据的的一致性和正确性,这样会不得不消耗资源;(个人觉得这个不是不用外键的原因,因为即使你不使用外键,你在应用层面也还是要保证的。所以,我觉得这个影响可以忽略不计。)
- 对分库分表不友好 :因为分库分表下外键是无法生效的。
外键的优点
- 保证了数据库数据的一致性和完整性;
- 级联操作方便,减轻了程序代码量;
总结
如果不涉及到分库分表,并发量不是很高的可以考虑外键。
ER 图
E-R 图 也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型。 它是描述现实世界关系概念模型的有效方法,是表示概念关系模型的一种方式。
下图是一个学生选课的 ER 图,每个学生可以选若干门课程,同一门课程也可以被若干人选择,所以它们之间的关系是多对多(M: N)。另外,还有其他两种关系是:1 对 1(1:1)、1 对多(1: N)。
我们试着将上面的 ER 图转换成数据库实际的关系模型(实际设计中,我们通常会将任课教师也作为一个实体来处理)
数据库范式
1NF(第一范式)
属性(对应于表中的字段)不能再被分割,也就是这个字段只能是一个值,不能再分为多个其他的字段了。1NF 是所有关系型数据库的最基本要求 ,也就是说关系型数据库中创建的表一定满足第一范式。
2NF(第二范式)
2NF 在 1NF 的基础之上,消除了非主属性对于码的部分函数依赖。
举例1:比如学生表中有学号、姓名、系名、课名、分数字段,其中(学号、课名)能唯一确定一条数据,所以(学号、课名)就被称为码,则学号、课名分别被称为主属性,其它的字段便为非主属性。此时(学号、课名)能确定唯一的学生姓名,但是学号也可以确定,这就是非主属性(姓名)对于码(学号、课名)的部分函数依赖。
举例2:比如学生表中有学号、姓名、系名、课名、分数字段,我们把它拆成学号、课名、分数表(表一)和学号、姓名、系名表(表二)。
- 表一中(学号、课名)依然是码,此时(学号、课名)能确定唯一的分数,但是学号和课名不能单独确定,所以不存在非主属性分数对于码 (学号、课名)的部分函数依赖,所以此表符合2NF的要求。
- 表二中学号是码,非主属性是姓名、系名,因为码只有一个属性,所以不可能存在非主属性对于码的部分函数依赖,也符合2NF的要求。
如下图所示,展示了第一范式到第二范式的过渡。第二范式在第一范式的基础上增加了一个列,这个列称为主键,非主属性都依赖于主键。
3NF(第三范式)
3NF 在 2NF 的基础之上,消除了非主属性对于码的传递函数依赖。符合 3NF 要求的数据库设计,基本上解决了数据冗余过大,插入异常,修改异常,删除异常的问题。
举例:比如学生表中有学号、姓名、系名、系主任字段,学号是码,非主属性是姓名、系名、系主任。其中系名依赖于学号,系主任依赖于系名,所以存在非主属性(系主任)对于码(学号)的传递依赖,所以该表不符合3NF的要求,可以将表拆为(学号,姓名,系名)和(系名、系主任)。
概念补充
- 函数依赖(functional dependency) :若在一张表中,在属性(或属性组)X 的值确定的情况下,必定能确定属性 Y 的值,那么就可以说 Y 函数依赖于 X,写作 X → Y。
- 部分函数依赖(partial functional dependency) :如果 X→Y,并且存在 X 的一个真子集 X0,使得 X0→Y,则称 Y 对 X 部分函数依赖。见第二范式举例。
- 完全函数依赖(Full functional dependency) :在一个关系中,若某个非主属性数据项依赖于全部关键字称之为完全函数依赖。
- 传递函数依赖 : 在关系模式 R(U)中,设 X,Y,Z 是 U 的不同的属性子集,如果 X 确定 Y、Y 确定 Z,且有 X 不包含 Y,Y 不确定 X,(X∪Y)∩Z=空集合,则称 Z 传递函数依赖(transitive functional dependency) 于 X。见第三范式举例。传递函数依赖会导致数据冗余和异常。传递函数依赖的 Y 和 Z 子集往往同属于某一个事物,因此可将其合并放到一个表中。
存储过程
我们可以把存储过程看成是一些 SQL 语句的集合,中间加了点逻辑控制语句。
存储过程在业务比较复杂的时候是非常实用的,比如很多时候我们完成一个操作可能需要写一大串 SQL 语句,这时候我们就可以写一个存储过程,这样也方便我们下一次的调用。
存储过程一旦调试完成通过后就能稳定运行,另外,使用存储过程比单纯 SQL 语句执行要快,因为存储过程是预编译过的。
存储过程在互联网公司应用不多,因为存储过程难以调试和扩展,而且没有移植性,还会消耗数据库资源。
阿里巴巴 Java 开发手册里要求禁止使用存储过程。
总结
- 了解数据库的基本概念;
- 区分基本的元组、码、候选码、主码、外码、主属性、非主属性的概念;
- 注意外键的优缺点及具体使用场景;
- 数据库范式不一定都需要满足,要具体场景具体处理;
- 存储过程在生产中慎用;
版权归原作者 阿Q说代码 所有, 如有侵权,请联系我们删除。