MySQL数据库设计篇
概述
做服务端开发离不开数据库设计,虽然说服务端技术一直在革新,但是MySQL一直都是我们首选使用的关系型数据库。服务端开发一直以来都是采用数据驱动研发的思想,可见数据库设计是非常重要的,数据库设计的好坏对软件设计影响非常大。后来由埃里克·埃文斯(Eric Evans)在他的著作《领域驱动设计:软件核心复杂性应对之策》(Domain-Driven Design: Tackling Complexity in the Heart of Software,2003)中首次提出领域驱动设计思想,我们开始接触和转变软件设计思想,但是数据库设计依然是非常的重要。如下图所示展示的是两种软件设计思想:
图1 数据驱动研发,领域驱动研发
工作了很多年依然很多人一直在crud,自我感觉工作中也都没问题,产品给出来的需求也都能得心应手,但是猛然回头却发现自己积累的只是经验,多年工作积累经验成为了一名有经验的码农,这里还有很多人会抱怨这家公司学不到东西,实则却是自己没有去思考软件设计。正如数据库设计是软件设计工作中重要的一环,如果不去思考如何提高自己的数据库设计能力,那也是自己没有理解软件研发是一项设计工作导致的。
聊到数据库设计,大家基本都想到的是三范式,三范式是数据库设计的基本原则,我们在设计过程中都是要考虑的,那么还有其他方面要考虑吗,当然是有的,如下图所示:
图2 mysql数据库设计
如上图展示,是我根据阅读资料和以往经验总结的数据库设计要考虑的各方面,本文将介绍一下各模块的内容。
一、三范式
1 .第一范式(确保每列保持原子性)
第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。
2 .第二范式(确保表中的每列都和主键相关)
第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。
3.第三范式(确保每列都和主键列直接相关,而不是间接相关)
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
二、表类型(存储引擎)选择
首先我们要了解存储引擎的作用,如下图所示是MySQL的逻辑架构图:
从图中可以看出存储引擎的作用,MySQL是一款支持多存储引擎的数据库,用户可以根据针对不同的存储需求可以选择最优的存储引擎,那么MySQL支持哪些存储引擎呢?
据了解MySQL 5.0支持的存储引擎包括MyISAM、InnoDB、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED等,其中 InnoDB和BDB提供事务安全表,其他存储引擎都是非事务安全表。创建新表时如果不指定存储引擎,那么系统就会使用默认存储引擎,MySQL 5.5之前的默认存储引擎是MyISAM,5.5之后改为了InnoDB。
在做数据库设计的时候我们需要了解如何选择合适的存储引擎,下面罗列两个常用的存储引擎的特性:
MyISAM:适用于应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高。
InnoDB:用于事务处理应用程序,支持外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询以外,还包括很多的更新、删除操作。
三、选择合适的数据类型
做数据库设计很多的工作都是在思考选用哪种数据类型最合适,我总结主要就是一下几种常见情况:
1、字符串存储数据类型选用
字符串存储主要就是CHAR和VARCHAR,特性对比如下:
2、大文本存储数据类型选用
遇到需要保存较大文本时,我们就会考虑到TEXT或者BLOB。二者之间的主要差别是BLOB能用来保存二进制数据,比如照片;而TEXT只能保存字符数据,比如一篇文章或者日记。TEXT和BLOB中又分别包括TEXT、MEDIUMTEXT、LONGTEXT和BLOB、MEDIUMBLOB、LONGBLOB三种不同的类型,它们之间的主要区别是存储文本长度不同和存储字节不同,用户应该根据实际情况选择能够满足需求的最小存储类型。
3、数值型存储数据类型选用
如下图所示是MySQL数值类型的特性对比:
根据以往设计经验总结,在存储数值型场景中我们主要考虑如下:
(1)、存储的是整数还是浮点数
(2)、存储的数据最大、最小值范围
(3)、存储的数据精度
根据以上考虑因素我们来确定数据类型。
4、日期型存储数据类型选用
MySQL提供的常用日期类型有DATE、TIME 、DATETIME、TIMESTAMP,如下图展示的是日期和时间类型的特性,我们根据存储格式要求选用就可以了:
四、字符集
字符集这块实际上是计算机层面考虑的,计算机最初由美国科学家发明出来的,他们制定了一套编码,称为ASCII编码,但是这套编码并没有考虑到全球各个国家的需求,这样肯定是行不通的,于是各地区根据需要在其基础上进行了编码扩展,这样的话就会导致一个问题乱码,所以我们在日常数据库设计中需要考虑系统的编码,避免出现编码选取不当导致系统乱码的困境。
五、索引的设计
索引可以极大的提高数据库的查询性能,索引设计的好坏直接影响系统的性能。
MySQL索引类型主要有以下几种:
-
普通索引:最基本的索引类型,没有唯一性的限制。
-
唯一索引:与普通索引类似,但区别在于唯一索引列的每个值都必须是唯一的。
-
主键索引:特殊的唯一索引,不允许有空值,多用于主表的主键。
-
组合索引:多列值组合成一个索引。
-
全文索引:主要用来搜索文本类型的数据,如字符串类型的数据。
-
空间索引:使用空间数据类型的列上,例如GEOMETRY,可以加快空间数据的查询速度。
六、sql mode
MySQL可以运行在不同的SQL Mode(SQL模式)下,SQL Mode定义了MySQL应支持的SQL语法、数据校验等,我们可以根据应用场景选用不同的SQL Mode,MySQL中的SQL Mode如下所示:
七、安全
数据安全我认为是系统设计最重要一方面,保证数据安全实际就是要先保证数据库安全,这块也是很多方面需要考虑,比如SQL注入、敏感数据脱敏、数据库高可用、数据异地多中心等
总结
紧赶慢赶文章总算是结束了,因为明天要加班,根据自己制定的每周一篇的计划,今晚必须要完成文章的书写工作,一直没有审稿的习惯,本次编写也没来得及审稿先发出了,后续阅读到有不清楚的地方再做细节调整。
本文意在总结数据库设计各方面的思考路线,一直依赖也都是按积累的经验和数据库知识来做数据库设计的工作,并没有一套成体系的方案,近期因为有一部分工作是审核团队的系统设计,突然想到了数据库设计这一环节是非常重要的,所以考虑把审核的思路整理成体系。希望本文给读者也能带来启发,在此先感谢每一位读者阅读!