Mysql数据库设计规范
1 数据库所有对象均以小写字母加下划线(因为mysql是大小写敏感的)
2 禁止使用mysql关键字
3 关联列的列名和数据类型尽量保持一次,比如订单表的用户id user_id和购物车表里面的用户id user_id,(因为如果不同的话,在关联查询时会进行隐式的转换,这样有可能造成列上的索引失效)
4 使用innodb为默认的存储引擎
5 统一使用utf-8 字符集,mysql使用utf-8的一个字符,占用三个字节内存。如varchar(10)最多可占用30个字节
6 所有表和字段均需要添加注释,并且如果有枚举含义的话注释里面需要指出字段值的含义如 1代表进行中,2代表已完成等等
7 单表数据量最好控制在500万行之内
8 UUID作为主键的优势和劣势是什么?
9 常用建立索引的列 where 从句出现 order by,group by distinct 列的出现 join 关联列出现
10 联合索引的建立原则
1 区分度(唯一值的数量与总行数的比值)最高的列放在联合索引的最左侧
2 在第一条相差不大的情况下,应该尽量把字段长度小的列放在坐侧
3 避免冗余索引和重复索引
11 尽量不使用外键约束,外键关系建议在业务代码中实现(因为外键会降低性能)
12 优先选择符合存储需要的最小数据类型 如:
1 将字符串转换为数字类型存储 因为int类型占用空间一般更小,(将ip地址转为整形) INET_ATON('255.255.255.255') = 4294967295 ,同时mysql还提供反 向功能 INET_NTOA(4294967295) = '255.255.255.255'
2 非负数选择unsigned存储,因为这样可以存储的有效数更多
3 VARCHAR(N)中的N代表字符数而不是字节数
13 避免使用TEXT,BLOB等类型,这两种类型会使得sql性能变差,但也不是说不能使用者两种类型
14 避免是mysql的ENUM类型,枚举本身是字符串类型,但内部存储使用整数类型进行存储,因此只能存储65535个值,这是枚举类型的一个优点,化字符串为整形存储
但枚举类型也存在缺陷,修改ENUM值需要使用ALTER语句,ENUM 需要在进行order by操作时 需要先有整形转字符串 再进行排序操作,效率比较低 这也是字符串转整形的劣势之一。另外 禁止使用整形值得枚举类型
15 尽量把列都定义为not null, 第一 如果在这样的列增加索引的话,null列需要更多的空间来保存列是否为空的状态值,所以会占用更多的索引空间,索引空间更大则索 引效率更低,其次 在进行比较和计算的时候 需要特别的处理
16 不要使用字符串 存储日期和时间 第一 无法使用时间函数 另外字符串需要更多的空间来存储
17 金额计算 使用decimal 类型 因为这种类型在计算的时候不会丢失精度
18 尽量使用预编译语句 ,第一 可以避免sql注入 ,第二 可多次使用执行计划
19 避免隐式转换 , sql隐式转换一般出现在where 语句中 当列类型和参数类型不一致时就是容易出现饮食转换 如主键id的 where id= '11' 隐式转换可能导致索引 无效
20 避免 前置模糊查询和全模糊查询 这样不会使用索引,后置模糊查询则会使用索引
21 使用 left join 和not exists 来优化not in操作 not in 操作会使索引失效
22 禁止select *
23 避免使用子查询 ,可以使用关联查询来进行优化,因为子查询效率更低 首先子查询返回的临时表 无论是内存临时表还是磁盘临时表 都是无法使用索引的,如果 子查询返回的数据量大这毫无疑问会降低sql性能 ,最后子查询产生的大量的临时表会消耗io和cpu资源 产生大量的慢查询,
24 避免连表太多,mysql 本身最多能关联61张表查询,建议不超过5张表 ,关联表太多会出现更多的关联缓存,一些关联操作也会产生临时表 临时表是无索引的,会降低性能
25 合并多个alter操作 alter操作会阻塞表
26 使用in代替or,in操作 会有效的使用索引
27 禁止使用 order by rand() 推荐 程序来获取随机值
28 避免在where 从句中进行函数转换和计算 , 这样无法使用索引
可以使用以下来优化
where date(create_time) = ‘20160601’ 可以优化为
where create_time>= ‘20160601’ and create_time < ‘20160602’
29 当明显不含有重复值得时候,使用union all 而不是union,union会把所有数据放到临时表中再进行去重操作 当数据量很大的时候 这种去重操作会使sql性能急剧下降 union all 则不会去重操作,比如合并多种类型的订单操作 由于一个订单只会属于一个类型 这时候就可以使用union all了
30 尽量做到数据的冷热分离 减小表的宽度,比如用户表,常用的字段 用户名 密码等等 属于热数据,而生日 性别 等等属于冷数据 ,因此我们也把冷数据拆分为用户 扩展表 达到分离的效果