如何更好的设计MySQL数据库(MySQL 数据库设计原则)

简述

        在我们项目开发中,数据库的设计可以说是非常重要,我遇到过很多数据库设计比较杂乱的项目,像表名、字段名命名混乱、字段类型设计混乱等待。写本篇博文的目的就是总结一下设计MySQL 数据库原则,有一个小小的规范会使得我们的项目更加强壮。

设计原则

1. 命名规则

        数据库的的名字一般都是很随意,最好和我们的项目业务一致,这样比较好进行区分;数据表的命名应尽可能和所服务的业务模块名一致,也就是我们所存储实体的名称,表名应尽量包含与所存放数据对应的单词,一眼可以看出此表所保存的是什么;表字段的命名也应尽量保持和实际数据相对应,联合索引名称应尽量包含所有索引键字段名或缩写,且各字段名在索引名中的顺序应与索引键在索引中的索引顺序一致。

2. 字段类型

        经常需要计算和排序等消耗CPU的字段,应该尽量选择更为迅速的字段,如用TIMESTAMP(4个字节,最小值1970-01-0100:00:00)代替Datetime(8个字节,最小值1001-01-01 00:00:00),通过整型替代浮点型和字符型;变长字段使用varchar,不要使用char,注意设计合适的长度;对于二进制多媒体数据,流水队列数据(如日志),超大文本数据不要放在数据库字段中;业务逻辑执行过程必须读到的表中字段必须要有初始的值,避免业务读出为负或无穷大的值导致程序失败。

3. 存储引擎选择

        一般情况可以选择MyISAM存储引擎,如果需要事务支持必须使用InnoDB存储引擎。关于各类数据库存储引擎的区别,在这里就不在赘述,想了解的可以Google。

4. 表设计

        业务逻辑执行过程必须读到的表中字段必须要有初始的值,避免业务读出为负或无穷大的值导致程序失败。并不需要一定遵守范式理论,字段适度的冗余,可以让Query尽量减少Join,提高查询速度。访问频率较低的大字段拆分出数据表。有些大字段占用空间多,访问频率较其他字段明显要少很多,这种情况进行拆分,频繁的查询中就不需要读取大字段,造成IO资源的浪费。大表可以考虑水平拆分。大表影响查询效率,根据业务特性有很多拆分方式,像根据时间递增的数据,可以根据时间来分。以id划分的数据,可根据id%数据库个数的方式来拆分。

5. 索引设计

a) 业务需要的相关索引是根据实际的设计所构造sql语句的where条件来确定的,业务不需要的不要建索引,不允许在联合索引(或主键)中存在多于的字段。特别是该字段根本不会在条件语句中出现。唯一确定一条记录的一个字段或多个字段要建立主键或者唯一索引,不能唯一确定一条记录,为了提高查询效率建普通索引。业务使用的表,有些记录数很少,甚至只有一条记录,为了约束的需要,也要建立索引或者设置主键。
b) 对于取值不能重复,经常作为查询条件的字段,应该建唯一索引(主键默认唯一索引),并且将查询条件中该字段的条件置于第一个位置。没有必要再建立与该字段有关的联合索引。对于经常查询的字段,其值不唯一,也应该考虑建立普通索引,查询语句中该字段条件置于第一个位置,对联合索引处理的方法同样。

c) 业务通过不唯一索引访问数据时,需要考虑通过该索引值返回的记录稠密度,原则上可能的稠密度最大不能高于0.2,如果稠密度太大,则不合适建立索引了。需要联合索引(或联合主键)的数据库要注意索引的顺序。SQL语句中的匹配条件也要跟索引的顺序保持一致。

6. 查询语句设计

        Insert语句中,根据测试,批量一次插入1000条时效率最高,多于1000条时,要拆分,多次进行同样的插入,应该合并批量进行。注意query语句的长度要小于mysqld的参数max_allowed_packet。查询条件中各种逻辑操作符性能顺序是and,or,in,因此在查询条件中应该尽量避免使用在大集合中使用in。永远用小结果集驱动大记录集,因为在mysql中,只有NestedJoin一种Join方式,就是说mysql的join是通过嵌套循环来实现的。通过小结果集驱动大记录集这个原则来减少嵌套循环的循环次数,以减少IO总量及CPU运算次数。尽量优化Nested Join内层循环。只取需要的columns,尽量不要使用select *。仅仅使用最有效的过滤字段,where 字句中的过滤条件少为好。尽量避免复杂的Join和子查询。

猜你喜欢

转载自blog.csdn.net/Zhihua_W/article/details/80907525
今日推荐