云数据库MySQL使用规范
本文将介绍云数据库 MySQL 的使用规范,帮助您规范化的对云数据库 MySQL 的管理和维护,避免操作不当对云数据库 MySQL 造成不可用等影响。为发挥云数据库 MySQL 的最大性能,请数据库开发人员根据指导编写合理的 SQL。
# 权限管理
为了云数据库 MySQL 的稳定性和安全性,云数据库 MySQL 限制了 super、shutdown、file 权限,当在云数据库 MySQL 上执行 set 语句时,有时会出现如下报错:
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation
1解决方法:如果需要 set 修改相关参数,可以使用控制台中实例管理页的 参数配置 进行修改,如果您要修改的参数不在其中,可以通过控制台上方入口提交工单,经评估后将会协助您进行修改,以保证实例稳定。
按需授权,一般应用程序只授权 DML(SELECT、UPDATE、INSERT、DELETE)权限即可。
授权用户访问时只允许特定 IP 或 IP 段访问,白名单具体操作,详情参见 连接实例。
请将管理账号与开发账号分离使用。
# 日常操作
# 注意事项
- 禁止设置弱密码用于 MySQL 用户账号。
- 内网连接登录须确保客户端的云服务器与云数据库 MySQL 是同一账号同一虚拟数据中心(VDC)下的机器。
# 使用建议
- 尽量避免业务高峰期做 online DDL 操作,可以使用的工具请参考:在线DDL操作。
- 尽量避免在业务高峰期批量操作数据,建议在业务低峰期分批操作。
- 尽量避免一个 MySQL 实例跑多个业务,高耦合可能会导致业务间互相影响。
- 业务有推广活动时,请提前预估资源并对实例进行优化,当需求量比较大时请及时与对应的客户经理联系。
# 库表设计
# 注意事项
- 云数据库 MySQL 8.0 版本不支持 MyISAM 引擎和 Memory 引擎,若有 Memory 引擎的需求建议使用云数据库 Redis;自建数据库迁移到云数据库 MySQL 时,需要先将 MyISAM 引擎转换成 InnoDB 引擎。
- 存在自增列的数据表,在自增列上应该创建至少一个单独的索引,或以自增列为开头的复合索引。
row_format
必须为非 fixed。- 每张表必须要有主键(可以创建一个无意义的列做主键),MySQL 第一范式标准 InnoDB 辅助索引叶子节点会保存一份主键值,建议用自增短列作为主键,降低索引所占磁盘空间提升效率。
- 字段尽量定义为 NOT NULL 并加上默认值。
# 使用建议
根据实际业务分析和数据预估,合理规划数据库的使用资源,建议在控制台 监控功能 页面,配置云数据库 MySQL 实例的监控与报警策略。
同一类业务的表放一个库,不同业务的表尽量避免公用同一个库。尽量减少执行跨库关联操作。
字符集统一使用 utf8mb4 可以降低乱码风险,部分复杂汉字和 emoji 表情必须使用 utf8mb4 方可正常显示。
注意:修改字符集只对修改后创建的表生效,若无特殊需要请勿修改默认字符集。
小数字段建议使用 decimal 类型,float 和 double 精度不够,特别是涉及金钱的业务,必须使用 decimal。
尽量避免数据库中存储大段文本、二进制数据、图片、文件等内容,建议将这些此类数据保存在本地磁盘,在数据库中保存文件索引。
尽量避免使用外键,外键与级联更新不适合高并发场景,会降低插入性能,在大并发情况下容易产生死锁。
降低业务逻辑和数据存储的耦合度,数据库存储数据为主,业务逻辑尽量通过应用层实现,尽可能减少对存储过程、触发器、函数、event、视图等高级功能的使用,这些功能移植性、可扩展性较差。
除非业务中 80% 以上的查询走分区字段或短期间内业务量大幅提升,建议禁止使用分区表。分区表主要用作归档管理,没有提升性能的作用。
# 索引设计
# 注意事项
- 禁止在更新频繁且区分度不高的列上创建索引,记录更新会变更 B+ 树,更新频繁的字段上创建索引会极大影响数据库性能。
- 建复合索引时,区分度最高的列放索引的最左边。存在非等号和等号混合判断条件时,必须把等号条件的列前置。
# 使用建议
- 单表的索引不超过 5 个,单个索引中的字段数不超过 5 个,索引会占用空间并耗资源。
- 选择业务中 SQL 过滤走的最多的并且 cardinality 值比较高的列建索引,字段的唯一性越高即代表 cardinality 值越高,索引过滤效果也越好。
- 在 varchar 类型的字段上创建索引时,建议指定索引长度,指定长度的索引区分度已经很高,无需整列创建索引,整列索引增大了索引维护的成本。
- 避免冗余索引,在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引。
# SQL编写
# 注意事项
- UPDATE、DELETE 操作不使用 LIMIT,必须使用 WHERE 精准匹配,LIMIT 是随机的,此操作会导致数据出错。
- 禁止使用
INSERT INTO table_name VALUES(value1,value2,value3,...)
,必须显式指定插入的列属性,避免表结构变动导致数据出错。 - SQL 语句中易导致索引失效的情况:
- 隐式类型转换。
- 对索引列进行数学计算和函数等操作,如使用函数对日期列进行格式化处理。
- join 列字符集不统一。
- 多列排序顺序不一致问题,如索引是 (a,b),SQL 语句是 order by a b desclike。
- 使用负方向查询(not,!=,not in 等)。
# 使用建议
- 按需索取,拒绝使用 select *,规避以下问题:
- 无法索引覆盖,回表操作,增加 I/O。
- 额外的内存负担,大量冷数据灌入
innodb_buffer_pool_size
,降低查询命中率。 - 额外的网络传输开销。
- 尽量避免使用大事务,建议大事务拆小事务,规避主从延迟。
- 及时提交业务代码中的事务,避免产生锁等待。
- 尽量减少多表 join,大表禁止 join,两张表 join 必须让小表做驱动表,join 列必须字符集一致并且都建有索引。
- LIMIT 分页优化,建议先确认首记录的位置再分页,减少数据库压力。
- 避免多层子查询嵌套的 SQL 语句。
- 业务上线之前做有必要的 SQL 审核,日常运维需定期下载慢查询日志做针对性优化。