一 、高性能MySQL 数据库设计规范
1、数据库设计规范
-
所有数据库对象名称必须使用小写字母并用下划线分割。
-
所有数据库对象名称禁止使用MySQL保留关键字。
- select id , username , from ,age from tb_user
- SQL中关键字查询 SQL中关键字查询
-
数据库对象的命名做到见名知义,最好不要超过32个字符。
-
临时表必须以temp为前缀并以日期为后缀。
-
备份库,备份表必须以bak_为前缀并,以日期为后缀。
-
所有存储相同数据的列名和列类型必须一致。
2、数据库基本设计规范
-
所有表必须使用Innodb存储引擎。
-
5.6以后Innodb存储引擎成为默认引擎。
-
支持事务,行级锁,更好的恢复性,高并发下的性能更好。
-
数据库和表的字符集统一使用UTF8,解决由于字符集转产生的乱码
。 -
MySQL中的UTF8字符汉字占3个字节,ASCII码占用1个字节。
-
所有的表和字段都需要添加注释。使用commnet从句添加表和列的备注
。 -
从一开始就开始数据字典的维护。
-
尽量控制表数量的大小,建议控制在500万以内。MySQL 并不是能够存储500万数据,这种限制取决于存储设置和文件限制
。 -
历史数据的归档,分库分表等手段来控制数据量的大小
。 -
谨慎使用MySQL 分区表。分区表在物理上表现为多个文件,在逻辑上表现为一个表。谨慎选择分区键,跨分区查询效率可能更低。
-
尽量做到冷热数据分离,减少表的宽度。减少磁盘IO,保证热数据的内存缓存命中率
。 -
利用更加有效的缓存,避免读入无用冷数据。
-
把经常使用的列放在一个表中。
-
禁止在表中建立预留字段
。预留字段命名很难做到见名知意。预留字段无法确认存储的数据类型,所以无法选择合适的类型。 -
对预留字段类型的修改,会对表进行锁定。修改一个字段的成本比预留的成本要大。
-
禁止在数据库中存储图片,文件等二进制数据
。 -
禁止在线上做数据库压力测试。
3、索引设计规范
-
限制每张表上的索引数量,建议单张表索引不超过5个。
-
禁止给表中的每一列都建立单独的索引。
-
每个Innodb表必须有一个主键。不使用更新频繁的列为主键,不使用多列主键。
-
不要使用UUID,MD5,HASH,字符串列作为主键。
-
主键建议选择使用自增长键。
-
那系列中建立索引:
- SELECT、 UPDATE 、DELETE语句的where从句中的列。
- 包含ORDER BY 、GROUP BY、DISTINCT中的字段。
- 多个表JOIN的关联列
4、如何选择索引列的顺序
-
明确建立索引的目的。区分度最高的列放在联合索引的最左侧。
-
在区分度不大的情况下,尽量把字段长度小的列放在联合索引的最左侧。
-
使用最频繁的列放在联合索引的最左侧。
-
避免建议冗余索引和重复索引。反例:(primary key(id) / index(id) / unique index(id))
index(a,b,c) / index(a,b) /index(a) -
对于频繁的查询优先考虑使用覆盖索引。避免了Innodb表进行索引的二次查找,可以把随机IO变为顺序IO加速查询效率。
-
尽量避免使用外键,不建议使用外键约束,但是在表与表之间的关联键上建立索引。
-
外键可用于保证数据的参照完整性,但建议在业务端实现。
-
外键会影响父表和子表的写操作从而降低性能。
5、数据库字段设计规范
-
优先选择符合存储需要的最小的数据类型。
-
将字符串转化为数字类型存储。INET_ATON('255.255.255.255') = 4294967295,INET_NTOA(4294967295) = '255.255.255.255' 。
-
对于非负型的数据来说,要优先使用无符号整型来存储。 无符号相对于有符号可以多出一倍的存储空间。 SIGNED INT -2147483648~2147483647 / UNSIGNED INT 0 ~ 4294967295
-
VARCHAR(N) 中的N 表示的是字符数,而不是字节数。N = 255 ,是可以保存255个中文。使用UTF8存储汉子Varchar(255) = 765个字节。
-
过大的长度会消耗更多的内存。
-
避免使用TEXT、BLOB数据类型。 TinyText \ Text \ MidumText \ LongText。text类型可以存储64K的内容。TEXT 或者BLOB列分离到单独的扩展表中。TEXT 或者BLOB类型只能使用前缀索引。
-
-
避免使用ENUM数据类型。
-
修改ENUM值需要使用ALTER语句。存在一定操作风险。
-
ENUM类型的ORDER BY操作效率低,需要额外操作。
-
禁止使用数值作为ENUM的枚举值。
-
-
尽可能将所有列定义为NOT NULL。 索引NULL列需要额外的空间来保存,所以要占用更多的空间。进行比较和计算要对NULL值做特别的处理。
-
字符串存储日期型的数据。缺点是:1:无法用日期函数进行计算和比较。 2: 用字符串存储日期要占用更多的空间。
-
使用TIMESTAMP或者DATETIME类型存储时间。TIMESTAMP存储日期有限。
-
对于金融,财务数据,必须使用decimal类型,精准的数据类型。decimal类型占用空间由定义的宽度决定。可用于存储比bigint更大的整数数据。
微信扫码关注java技术栈,获取Java面试题和架构师相关题目和视频。