关系型数据库设计要领(值得收藏)
ccwgpt 2025-01-02 14:57 80 浏览 0 评论
摘要
本文讨论关系数据库设计相关的一些内容,涉及关系模型,表结构设计等内容,以学生选修课程讲述设计过程,在尽量讲清楚设计要领的前提下,简化设计内容。
本文基于MySQL数据库为基础,适合有一定关系型数据库基础的人阅读。
实体-关系模型(E-R)
首先搞清楚什么是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的默认存储引擎。
何如选择?
选择标准: 根据应用特点选择合适的存储引擎,对于复杂的应用系统可以根据实际情况选择多种存储引擎进行组合。但是要知道组合使用的缺点:
- 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压力。
- 把text和blob分离到单独的表中。这会把原来表中的数据列转变为更短的固定长度的数据行格式,这个十分有用。
浮点数和定点数
在MySQL中float、double是浮点数,decimal是定点数。
浮点数优势:在长度一定的情况下,浮点数能表示更大的数据范围。
浮点数缺点:精度问题。
友情提醒:在有关金钱交易方面浮点数慎用!!!
整数
MySQL支持SQL标准整数类型INTEGER(或INT)和SMALLINT。作为标准的扩展,MySQL还支持整数类型TINYINT、MEDIUMINT和BIGINT。下表显示了每个整数类型所需的存储空间和范围。
索引设计
设计原则
- 搜索的索引列,不一定是所要选择的列。最适合索引的列是出现在 WHERE 子 句中的列,或连接子句中指定的列,而不是出现在 SELECT 关键字后的选择列表中的列。
- 使用惟一索引。对于惟一值的列,索引的效果最好,而具有多个 重复值的列,其索引效果最差。
- 使用短索引。如果对字符串列进行索引,应该指定一个前缀长度 。例如,如果有一个 CHAR(200) 列,如果在前 10 个或 20 个字符内,多数值是惟一的, 那么就不要对整个列进行索引。
- 利用最左前缀。每个额外的索 引都要占用额外的磁盘空间,并降低写操作的性能。
- 不要过度索引。
- 考虑在列上进行的比较类型。如果是在列上做函数运算,对其进行索引将毫无意义。
示例
针对上面提到的学生选课E-R图,给出设计结果和说明:
表1-1 学生信息表(Student)
表1-2 课程信息表(Course)
表1-3 选课成绩表(SC)
- Student中姓名的长度是40,这里把外国人也考虑进来了;
- Student中性别定义成枚举,主要是枚举意义简明;
- Student中没有存年龄,而存储的出生日期,是因为年龄并不是一成不变的,并且能够通过出生日期正确计算。
- SC中成绩使用的是double而不采用decimal,主要是因为成绩并不需要那么高的精确度。
- SC中(sno,cno)作为联合主键而不是独立主键,由于现阶段markdown无法合并行,所以无法编辑。
参考
- (美)Abraham Silberschatz等.数据库系统概念.北京:机械工业出版社,2012
- MySQL 5.7 Reference Manual
- [eimhe.com]网易技术部的MySQL中文资料.
(感谢阅读,希望对你所有帮助)
来源:blog.csdn.net/qq_36011946/article/details/105305063
相关推荐
- 一个基于.Net Core遵循Clean Architecture原则开源架构
-
今天给大家推荐一个遵循CleanArchitecture原则开源架构。项目简介这是基于Asp.netCore6开发的,遵循CleanArchitecture原则,可以高效、快速地构建基于Ra...
- AI写代码翻车无数次,我发现只要提前做好这3步,bug立减80%
-
写十万行全是bug之后终于找到方法了开发"提示词管理助手"新版本那会儿,我差点被bug整崩溃。刚开始两周,全靠AI改代码架构,结果十万行程序漏洞百出。本来以为AI说没问题就稳了,结果...
- OneCode低代码平台的事件驱动设计:架构解析与实践
-
引言:低代码平台的事件驱动范式在现代软件开发中,事件驱动架构(EDA)已成为构建灵活、松耦合系统的核心范式。OneCode低代码平台通过创新性的注解驱动设计,将事件驱动理念深度融入平台架构,实现了业务...
- 国内大厂AI插件评测:根据UI图生成Vue前端代码
-
在IDEA中安装大厂的AI插件,打开ruoyi增强项目:yudao-ui-admin-vue31.CodeBuddy插件登录腾讯的CodeBuddy后,大模型选择deepseek-v3,输入提示语:...
- AI+低代码技术揭秘(二):核心架构
-
本文档介绍了为VTJ低代码平台提供支持的基本架构组件,包括Engine编排层、Provider服务系统、数据模型和代码生成管道。有关UI组件库和widget系统的信息,请参阅UI...
- GitDiagram用AI把代码库变成可视化架构图
-
这是一个名为gitdiagram的开源工具,可将GitHub仓库实时转换为交互式架构图,帮助开发者快速理解代码结构。核心功能一键可视化:替换GitHubURL中的"hub...
- 30天自制操作系统:第六天:代码架构整理与中断处理
-
1.拆开bootpack.c文件。根据设计模式将对应的功能封装成独立的文件。2.初始化pic:pic(可编程中断控制器):在设计上,cpu单独只能处理一个中断。而pic是将8个中断信号集合成一个中断...
- AI写代码越帮越忙?2025年研究揭露惊人真相
-
近年来,AI工具如雨后春笋般涌现,许多人开始幻想程序员的未来就是“对着AI说几句话”,就能轻松写出完美的代码。然而,2025年的一项最新研究却颠覆了这一期待,揭示了一个令人意外的结果。研究邀请了16位...
- 一键理解开源项目:两个自动生成GitHub代码架构图与说明书工具
-
一、GitDiagram可以一键生成github代码仓库的架构图如果想要可视化github开源项目:https://github.com/luler/reflex_ai_fast,也可以直接把域名替换...
- 5分钟掌握 c# 网络通讯架构及代码示例
-
以下是C#网络通讯架构的核心要点及代码示例,按协议类型分类整理:一、TCP协议(可靠连接)1.同步通信//服务器端usingSystem.Net.Sockets;usingTcpListene...
- 从复杂到优雅:用建造者和责任链重塑代码架构
-
引用设计模式是软件开发中的重要工具,它为解决常见问题提供了标准化的解决方案,提高了代码的可维护性和可扩展性,提升了开发效率,促进了团队协作,提高了软件质量,并帮助开发者更好地适应需求变化。通过学习和应...
- 低代码开发当道,我还需要学习LangChain这些框架吗?| IT杂谈
-
专注LLM深度应用,关注我不迷路前两天有位兄弟问了个问题:当然我很能理解这位朋友的担忧:期望效率最大化,时间用在刀刃上,“不要重新发明轮子”嘛。铺天盖地的AI信息轰炸与概念炒作,很容易让人浮躁与迷茫。...
- 框架设计并不是简单粗暴地写代码,而是要先弄清逻辑
-
3.框架设计3.框架设计本节我们要开发一个UI框架,底层以白鹭引擎为例。框架设计的第一步并不是直接撸代码,而是先想清楚设计思想,抽象。一个一个的UI窗口是独立的吗?不是的,...
- 大佬用 Avalonia 框架开发的 C# 代码 IDE
-
AvalonStudioAvalonStudio是一个开源的跨平台的开发编辑器(IDE),AvalonStudio的目标是成为一个功能齐全,并且可以让开发者快速使用的IDE,提高开发的生产力。A...
- 轻量级框架Lagent 仅需20行代码即可构建自己的智能代理
-
站长之家(ChinaZ.com)8月30日消息:Lagent是一个专注于基于LLM模型的代理开发的轻量级框架。它的设计旨在简化和提高这种模型下代理的开发效率。LLM模型是一种强大的工具,可以...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- mfc框架 (52)
- abb框架断路器 (48)
- beego框架 (52)
- java框架spring (58)
- grpc框架 (65)
- tornado框架 (48)
- 前端框架bootstrap (54)
- orm框架有哪些 (51)
- 知识框架图 (52)
- ppt框架 (55)
- 框架图模板 (59)
- 内联框架 (52)
- cad怎么画框架 (58)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)