Mysql高性能数据库设计(一)

时间:2021-07-02 19:46:32

数据库设计是获得良好性能的基石,特别是新手,或者说入行一两年的工作来说,其实大多数面试所提到的就是数据库,最基本的就是数据库的设计了。一个表如果设计得不合理,它的后期扩展将会让你一筹莫展,香菇无泪啊!所以个人的建议是必须要多借鉴一些项目中的数据库设计,多想想别人为何会这么设计的,比方说看看ecshop的商品,订单表的设计,dedecms或者wordprss等的一些内容表设计,数据类型,拆分表,临时表,范式与反范式。其实提到三范式,应该还有很多PHP的开发者不是很熟悉,作为后端编程,如何处理数据和如何做到高性能架构都是你的亮点,也是做为后端开发可说必备或者进阶必备的知识实践出来的经验。

一.不合理的设计
先举两个例子(可跳过,举例是为了加深印象)

1.第一个例子:相信大部分人都会碰到需求变更需要改表,但且愁眉苦脸地感觉前期设计的表有多坑。

Mysql高性能数据库设计(一)

Mysql高性能数据库设计(一)

这是一张已存储了19339条记录的规格表,主要的用途是服装类的规格表,如果是放在后期的需求变更里要修改[将颜色尺码分出去,如淘宝的先选择尺码再选择服装颜色],为了兼容原来已有的19339多记录,你会用什么办法做向后兼容,既符合需求变更,也能更快地实现呢?

2.第二个例子:自己有时候是对数据类型,数据库性能设计架构,更符合索引和读的优化是一知半解的,然后在设计数据库过,总会感觉自己设计得不够合理。特别是随着数据量不断增大,或者变更需求很频繁的时候,前期越不合理的设计都会后期自己给自己挖的坑。

Mysql高性能数据库设计(一)

如这种电商活动所使用的枚举类型,且活动还一直在增加,如果依据数据库版本来说的话,而这表面上是整数类型,如果不是很理解数据类型的来说,很多人会把enum类型当作是整数来看,但它却是字符串。还有scan是浏览数,有关于统计的字段在访问这张表很频繁时,可以考虑独立设计一张统计表做数据统计。

3.再补充一种就是新手设计的数据库
Mysql高性能数据库设计(一)

这么说吧,一共3025条记录,我用10分钟还没打开。

select * from news order by id desc limit 0,1000

order by id查询1000条需要3分钟,不加order by直接崩溃查不出来。

二.选择合适的存储引擎
Msyql的亮点在于它的组件式存储引擎设计,而合理和不合理地使用存储引擎对性能的影响会差别很大,这些我们简单地介绍和建议怎么选择存储引擎。日常我们频繁用的有两种存储引擎,分别是InnoDB和MyISAM。

一般情况下,InnoDB都是正确的选择,除非说需要用到些InnoDB不具备的特性,优先选择InNoDD。对于一个数据库来说,一般都是选择性地使用InnoDB和MyISAM。

在需要用到事务处理和崩溃恢复方面,那必定是选择InnoDB,那什么时候考虑使用MyISAM呢,在可以不考虑事务处理,对于崩溃恢复的代价可以承受的,需要更好的读操作,那么应该选择MyISAM,总做周知的是MyISAM在读的性能比InnoDB更快,如一些配置文件,就可以考虑使用MyISAM。

三.选择合理的数据类型
Mysql所支持的数据类型有很多,当然在实际业务中大部分也是你最熟悉的那几个,但还是有很多人在自己所熟悉的几个数据类型选择上使用得非常不合理。选择正确的数据类型是高性能架构的基石,引入《高性能Mysql》书中所说的有几个简单的原则能帮你更好地选择使用字段类型。

1.更小的通常更好
例如只需要存储0~200个字节的,应该尽量使用最小的数据类型。更小的通常会更快,因为它们占用更少的磁盘,内存和CPU,并且处理时需要的CPU更少。

2.简单就好
简单的数据类型的操作通常需要更少的CPU处理时间,比如整形比字符串操作代价更低,再结合更小的通常更好来设计,就是一个不错的选择啦。

3.尽量避免NULL
我每次看到这个都会想到我曾经的主管跟java的同事争辩的使用留空和使用0或者”替代方案哪个更好。后面的经历中验证了我曾经的主管在数据库方面也是满腹经纶的。新浪五六年出来的人物确实有很多地方值得我学习和敬仰。如果查询中包含有为NULL的列,对Mysql来说更难优化,因为可为NULL的列会让索引,索引统计和值比较都更复杂。可为NULL的列会占据更多的磁盘空间,在Mysql中也需要更多复杂的处理程序。通常把Null改为0或者更定一个非Null的合理默认值更符合设计,当然这个性能的提升并不是很明显的。

建议分2步去选择合理的数据类型:
1).确定数据是属于哪种类型:如数字,字符串,时间等

2).选择具体的类型:如主键自增的是数字,数字分为整型和实数类型,我们应该选择的是整型,而在整型里还分为TINTINT,SMALLINT,MEDIUINT,INT,BIGINT,分别以8,16,,24,32,64位存储空间。主键自增,那么通常来说都是选择11位(看情况,如配置表可能里面再怎么自增,ID最大也不是超过1000等的就不适应用INT或者固定用11位了)

总结:良好的数据库设计原则是普遍适用的,概括起来说是尽可能保持任何东西小而简单总是好的。Mysql喜欢简单,需要使用数据库的人应该也同样喜欢简单的原则:

1.尽量避免过度设计
2.小而简单的合适数据类型
3.避免使用NULL值
4.尽量使用相同的数据类型存储相似或者相关的值(如goods表的id,在订单表中对应的goods_id的值应该都是int(n))
5.注意可变长度字符串,其在临时表和排序时可能导致悲观的按最大长度分配内存。
6.尽量使用整型定义的标识列(id)
7.避免使用Mysql已经遗弃的特性
8.小心使用ENUM和SET
9.范式是好的,但是反范式有时候也是必须的。
10.根据表不同的功能选择性地使用InnoDB和MyISAM。

后续将更新整理出高性能数据库设计的具体建议和实现,本篇文章希望能让大家知道数据库的表设计至关重要,可能学习起来也花不了你多长的时候,但在求职面试中,可能别人很少问你PHP的问题,更多的是Mysql,Linux,分布式,事务处理,高并发,性能调优等等。。。