首先搞清楚什么是E-R数据模型?它有什么用?
E-R模型在将现实世界中事实的含义和相互关联映射到概念模式方面非常有用,因此,许多数据库设计工具都利用了E-R模型的概念。E-R模型所采用的三个主要概念是:实体集、关系集和属性。
-
实体
:实体是世界中可以区别于其他对象的“事件”或者“物体”,例如,学校里的每个学生、学生选修的每门课程等都是一个实体。 -
属性
:属性是实体集中每个成员具有的描述性性质。例如,学生的姓名,学号等。 -
实体集
:实体集就是就有相同类型及属性的实体集合,比如,学校里的所有学生,学生选修的所有课程等。 -
关系
:关系是多个实体间的相互关联。例如,小明选修语文课程。 -
关系集
:关系集是同类关系的集合。例如,所用学生选修课程的集合。
既然知道了E-R数据模型的作用,下面就让我们来画出学生选修课程的E-R图吧。
其中,(学号,姓名,年龄,性别)为学生的属性,(成绩)为选修关系的属性,(课程号,课程名,学分)为课程的属性。学生和课程之间的关系是多对多,即一个学生可以选择多门课程,一门课程可以被多个学生选修。
关系表设计
从上面的E-R图,我们一眼就能看出他们之间的联系,那该如何设计关系模式呢?
我们要知道,关系数据库设计的目的是为了生成一组关系模式,使我们能够既不必存储不必要的冗余信息,又能方便地获取信息。为了是我们方便的达到这个目的,范式设计应运而生。
Boyce-Codd范式
我们所知道的令人满意的范式之一是Boyce-Codd范式(BCNF)。如果对F+中所有形如 α→β 的函数依赖,其中 α⊆R 且 β⊆R,下面的定义至少有一个成立:
-
α→β 是平凡函数依赖(即 β ⊂ α)。(一般来说,平凡函数依赖并没有讨论意义,讨论的都是非平凡函数依赖,即 β ∉⊂ α 的情况)
-
α 是模式R的超码。
考虑如下关系模式及其相应的函数依赖:
- 学生 = (学号,姓名,年龄,性别)
学号 → 姓名 年龄 性别
- 课程 = (课程号,课程名,学分)
课程号 → 课程名 学分
- 选修 = (学号,课程号,成绩)
学号 课程号 → 成绩
以上模式均属于BCNF。就拿第一组关系模式来说,学生上仅有的非平凡函数依赖,箭头左侧是学号,学号是该模式的一个候选码(候选码属于超码的子集),没有破坏BCNF的定义。
其实并不是每个BCNF都能保持函数依赖的,例如:
Banker-schema = (branch-name,customer-name,banker-name)
它表示的是一个客户在某一分支机构有一个银行账户负责人。它要求满足的函数依赖集F为
-
banker-name → branch-name
-
branch-name customer-name → banker-name
显然,Banker-schema不属于BCNF,因为 banker-name 不是超码。
我们可以将它分解得到如下的BCNF:
Banker-branch-schema = (banker-name,branch-name)
Customer-banker-schema = (customer-name,banker-name)
分解后的模式只保持了banker-name → branch-name,而branch-name customer-name → banker-name的依赖没有保持。
第三范式
当我们不能同时满足以下三个设计目标:
-
BCNF。
-
无损连接。
-
保持函数依赖。
我们可以放弃BCNF而接受相对较弱的第三范式(3NF)。因为3NF总能找到无损连接并保持依赖的分解。
具有函数依赖即F的关系模式R属于3NF,只要F+中所有形如 α→β 的函数依赖,其中 α⊆R 且 β⊆R,下面的定义至少有一个成立:
-
α→β 是平凡函数依赖(即 β ⊂ α)。
-
α 是模式R的超码。
-
β - α 中的每个属性 A 都包含在R的候选码中。
回到Banker-schema的例子中,我们已经看到了没能将该关系模式转化成BCNF而又保持依赖和无损连接的分解,但改模式属于3NF。在Banker-schema中,候选码是{branch-name,customer-name},所以Banker-schema上不包含候选码的就只有banker-name。
而形如 α → banker-name 的非平凡函数依赖都是以{branch-name,customer-name}作为 α 的一部分。由于{branch-name,customer-name}是候选码,所以符合3NF的定义。
每个BCNF都属于3NF,因为BCNF的约束比3NF更严格。
存储引擎的选择
关系模式一但确定,基本的数据库表结构就确定了,接下来就是表结构的详细设计了,这里先从存储引擎开始,MySQL提供的各种存储引擎都是根据不同的用例设计的。
下表概述了MySQL提供的一些存储引擎。
最常用的两种存储引擎:MyISAM和InnoDB。
-
MyISAM:MySQL 5.5.5以前,MyISAM作为MySQL的默认存储引擎。
-
InnoDB:MySQL 5.5.5以后,InnoDB作为MySQL的默认存储引擎。
另外,关注公众号Java技术栈,在后台回复:面试,可以获取我整理的 MySQL 系列面试题和答案,非常齐全。
何如选择?
选择标准: 根据应用特点选择合适的存储引擎,对于复杂的应用系统可以根据实际情况选择多种存储引擎进行组合。但是要知道组合使用的缺点:
- InnoDB和非InnoDB存储引擎的组合对比,仅使用InnoDB存储引擎可以简化备份和恢复操作。MySQL Enterprise Backup对使用InnoDB存储引擎的所有表进行热备份。对于使用MyISAM或其他非InnoDB存储引擎的表,它会执行“热”备份,数据库会继续运行,但这些表在备份时不能修改。
下面是常用存储引擎的适用环境:
-
InnoDB:事务型业务场景首选。
-
MyISAM:非事务型的大多数业务场景。
-
Memory:数据保存到内存中,能提供极速的访问速度。(个人觉得可以使用Redis等NoSQL数据库代替)
字符集选择
存储引擎之后就是确定字符集,字符集的选择十分重要,不管是MySQL还是Oracle,如果在数据库创建阶段没有正确选择字符集,那么在后期需要更换字符集的时候将要付出高昂的代价。
如何选择?
建议在能够完全满足应用当下和未来几年发展的前提下,尽量使用小的字符集。应为更小的字符集意味着能够节省空间、减少网络传输字节数,同时由于存储空间小间接的提升了系统的性能。
不同的数据库有不同的字符集应用级别,分别为服务器级别、库级别、表级别、字段级别,通常推荐使用库级别或者表级别。因为库级别或者表级别在保有灵活性的同时,兼顾数据间字符集的统一,这可以给开发省去很多处理字符集的麻烦。
数据类型的选择
选择原则
前提:使用合适的存储引擎。
选择原则:为了获得最佳的存储,您应该在所有情况下尝试使用最精确的类型。
固定长度和可变长度
char 与 varchar
下面这个例子说明二者的区别:
请注意上表中最后一行的值只适用不使用严格模式时;如果 MySQL 运行在严格模式,超过列 长度的值不保存,并且会出现错误。
从 CHAR(4)和 VARCHAR(4)列检索的值并不总是相同,因为检索时从 CHAR 列删除了尾部的空 格。通过下面的例子说明该差别:
mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO vc VALUES ('ab ', 'ab ');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT CONCAT(‘(’, v, ‘)’), CONCAT(‘(’, c, ‘)’) FROM vc;
±--------------------±--------------------+
| CONCAT(‘(’, v, ‘)’) | CONCAT(‘(’, c, ‘)’) |
±--------------------±--------------------+
| (ab ) | (ab) |
±--------------------±--------------------+
1 row in set (0.06 sec)
对于InnoDB数据表,内部的行格式没有区分固定长度和可变长度列,所有数据化行都使用指向数据列值的头指针,因此在本质上,使用固定长度的CHAR列不一定比使用可变长度的VARCHAR列要好。
因为,主要的性能因数是数据行使用的存储总量。对于占用空间来说,CHAR总是大于等于VARCHAR,所以,使用VARCHAR来最小化行数据的存储总量,进而减少磁盘I/O频率。
text 和 blob
在使用text或者blob类型的字段是需要注意一下几点,以便获得更好的性能:
-
执行大量的删除和更新操作后,会留下很”空洞“,需要定期optimize table进行碎片整理;
-
避免查询大型的text和blob。查询大型的text和blob会使一页能装下的数据量减少,增加磁盘I/O压力。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

最后
作为过来人,小编是整理了很多进阶架构视频资料、面试文档以及PDF的学习资料,针对上面一套系统大纲小编也有对应的相关进阶架构视频资料
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
csdnimg.cn/images/e5c14a7895254671a72faed303032d36.jpg" alt=“img” style=“zoom: 33%;” />
最后
作为过来人,小编是整理了很多进阶架构视频资料、面试文档以及PDF的学习资料,针对上面一套系统大纲小编也有对应的相关进阶架构视频资料
[外链图片转存中…(img-QiZaQA0u-1713434360289)]
[外链图片转存中…(img-QDFIDRSe-1713434360290)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!