本文讨论了关系数据库设计相关的一些内容,包括关系模型、表结构设计等,利用选修课的方式为学生描述设计过程,在力求把设计要领讲清楚的同时,简化了设计内容。
本文基于MySQL数据库,适合有一定关系数据库基础的人。
实体关系模型(ER)
首先我们先了解一下什么是ER数据模型? 这是为了什么?
ER 模型在将现实世界事实的含义和相互关系映射到概念模式方面非常有用,因此,许多数据库设计工具都利用 ER 模型的概念。 ER模型中使用的三个主要概念是:实体集、关系集和属性。
现在我们知道了ER数据模型的作用,下面我们来画一下学生选修课的ER图。
其中,(学号、姓名、年龄、性别)为学生的属性,(年级)为选课关系的属性,(课程号、课程名称、学分)为课程的属性。 学生与课程之间是多对多的关系,即一名学生可以选择多门课程,一门课程可以由多名学生选修。
关系表设计
从上面的ER图中,我们一眼就能看出它们之间的联系。 那么如何设计关系模型呢?
我们要知道,关系数据库设计的目的是生成一组关系模式,以便我们可以轻松地获取信息,而不必存储不必要的冗余信息。 为了方便我们实现这一目标,范式设计应运而生。
博伊斯-科德范式
我们所知道的令人满意的范式之一是 Boyce-Codd 范式 (BCNF)。 如果对于 F+ 中 α→β 形式的所有函数依赖性,其中 α⊆R 和 β⊆R,至少有以下定义之一成立:
考虑以下关系模式及其相应的函数依赖关系:
学生证 → 姓名 年龄 性别
课程编号 → 课程名称 学分
学号 课程号 → 成绩
以上模式均属于BCNF。 以第一组关系模式为例。 对学生唯一重要的函数依赖是箭头左侧的学生编号。 学号是该模式的候选代码(候选代码属于超码的子集),不会破坏BCNF。 定义。
事实上,并不是每个BCNF都能保持函数依赖,例如:
-=(-名称,-名称,-名称)
表示客户在某分行拥有银行账户持有人。其需要满足的函数依赖集F为
显然,-不属于BCNF,因为-name不是超码。
我们可以将其分解得到BCNF,如下所示:
-- = (-名称,-名称)
-- = (-名称,-名称)
分解后的模式仅维护-name → -name,但不维护-name -name → -name 的依赖关系。
第三范式
当我们无法同时满足以下三个设计目标时:
我们可以放弃BCNF,接受相对较弱的第三范式(3NF)。 因为3NF总能找到无损连接并保持依赖分解。
具有函数依赖性的关系模式R,即F,属于3NF。 只要 F+ 中的所有函数依赖均呈 α→β 形式,其中 α⊆R 和 β⊆R,则至少以下定义之一成立:
回到-的例子,我们看到没有分解可以将关系模式转换为BCNF,同时保持依赖关系和无损连接,但改变后的模式属于3NF。 - 中,候选代码为{-name, -name},因此- 上唯一不包含候选代码的候选代码为-name。
α → -name 形式的非平凡函数依赖都具有 {-name, -name} 作为 α 的一部分。 由于{-name,-name}是候选代码,因此符合3NF的定义。
每个BCNF都属于3NF,因为BCNF比3NF有更严格的约束。
存储引擎选择
一旦确定了关系模型,基本的数据库表结构就确定了。 接下来就是表结构的详细设计。 这里我们从存储引擎开始。 MySQL提供的各种存储引擎是根据不同的用例而设计的。
下表概述了 MySQL 提供的一些存储引擎。
两个最常用的存储引擎: 和 。
如何选择?
选择标准:根据应用特点选择合适的存储引擎。 对于复杂的应用系统,可以根据实际情况选择并组合多种存储引擎。 但要注意组合使用它的缺点:
以下是常用存储引擎的适用环境:
字符集选择
存储引擎确定之后,字符集就非常重要了。 无论是MySQL还是MySQL,如果在数据库创建阶段没有正确选择字符集,那么当后期需要更改字符集时,你将付出高昂的代价。
如何选择?
建议在能够完全满足现在和未来几年应用程序发展的前提下,尽可能使用小字符集。 因为较小的字符集意味着可以节省空间,减少网络传输字节数。 同时,较小的存储空间也间接提高了系统的性能。
不同的数据库有不同的字符集应用级别,分别是服务器级、库级、表级、字段级。 通常建议使用库级别或表级别。 因为库级或者表级在保持灵活性的同时,考虑到了数据间字符集的统一,这样可以省去开发很多处理字符集的麻烦。
数据类型选择选择原则
先决条件:使用适当的存储引擎。
选择原则:为了获得最佳存储效果,您应该在所有情况下尝试使用最精确的类型。
固定长度和可变长度
炭和
下面的例子说明了两者之间的区别:
请注意,上表最后一行的值仅在不使用严格模式时适用; 如果MySQL运行在严格模式下,超过列长度的值不会被保存并且会发生错误。
从 CHAR(4) 和 (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)
对于数据表,内部行格式不区分定长列和变长列。 所有启用数据的行都使用指向数据列值的标头指针,因此本质上,使用固定长度的 CHAR 列并不一定比使用可变长度的列更好。
因为,主要的性能因素是数据行使用的总存储空间。 从占用空间来看,CHAR总是大于等于,因此它用来尽量减少存储的行数据总量,从而降低磁盘I/O频率。
文本和斑点
使用文本或blob类型字段时,需要注意以下几点才能获得更好的性能:
浮点数和定点数
在MySQL中,float是浮点数和定点数。
浮点数的优点:当长度一定时,浮点数可以表示更大的数据范围。
浮点数的缺点:精度问题。
友情提醒:处理金钱时要谨慎使用浮点数! ! !
整数
MySQL 支持 SQL 标准整数类型(或 INT)和 . 作为标准的扩展,MySQL 还支持整数类型和 . 下表显示了每种整数类型所需的存储空间和范围。
索引设计 设计原理 示例
对于上述学生选课的ER图,给出设计结果和说明:
表1-1 学生信息表()
表1-2 课程信息表()
表1-3 选课成绩表(SC)
参考
(感谢您的阅读,希望对您有帮助)
来源:////