总结MySQL开发规范大全

前言

俗话说的好“无规矩不成方圆”,在我们使用MySQL的过程中同样亦是如此,如果我们能达成一致的共识,那么开发过程中会减少一些不必要的争论,同时能让我们的整个开发更加规范。参考业界的一些共识和阿里数据库相关规范等,个人总结了一些库表设计、索引、SQL相关的规范,希望能对大家有所帮助,欢迎收藏~

一、命名规范

l 库名、表名、字段名必须使用小写字母,并采用下划线分割,不能超过32个字符

l 库名、表名、字段名必须?名知意。命名与业务、产品线等相关联

举例:遵循:{project名称} + "_" + 业务数据类型,比如“user_order”、“user_address”,如果数据表为全局系统表,可以不包含{project}前缀,比如“user”。

l 禁止使用中文字符、系统保留字、特殊符号命名

l 临时库、表名必须以tmp为前缀,并以日期为后缀。例 tmp_test01_20210310

l 备份库、表必须以bak为前缀,并以日期为后缀。例 bak_test01_20210310

二、基础规范

l 使用INNODB存储引擎(支持事务、支持更大并发量)

l 表字符集默认使用UTF8,需要存储表情请使用utf8 mb4

l 所有表都需要添加注释;除主键外的其他字段都需要增加注释。推荐采用英文标点,避免出现乱码

l 禁止在数据库中存储图片、大文件等大数据

l 禁止使用存储过程、触发器、函数

l 每张表数据量建议控制在1000W以内

l 禁止在线上做数据库压力测试

l 禁止从测试、开发环境直连数据库

l 单个实例数据库数量不超过50个

l 单个数据库容量不能超过300G

三、库表设计

l 禁止使用分区表

l 将大字段、访问频率低的字段拆分到单独的表中存储,分离冷热数据

l 推荐使用HASH进行散表,表名后缀使用十进制数,数字必须从0开始

l 按日期时间分表需符合YYYY[MM][DD][HH]格式,例如2021031001。年份必须使用4位数字表示。例如按日散表user_20210310、 按月散表user_202103。

l 采用合适的分库分表策略。例如千库十表、十库百表

l 创建表时必须显式指定表存储引擎类型和字符集,存储引擎统一使用innodb

l 表必须使用有序递增的整型字段做主键,字段类型用int或bigint,并且是无符号(unsigned)

l 不能使用外键

l 单表字段不能超过30个

l 单表记录数不能超过5000W,否则分表

l 建议表中添加三个字段:

create_time:记录创建时间,时间类型

update_time:记录修改时间,时间类型

version:“乐观锁”的版本标记,long型,默认为0

四、字段设计

l 建议使用UNSIGNED存储非负数值

l 建议使用INT UNSIGNED存储IPV4

l 用DECIMAL代替FLOAT和DOUBLE存储精确浮点数。例如货币、金融相关的数据

l INT类型固定占用4字节存储,例如INT(4)仅代表显示字符宽度为4位,不代表存储长度

l 强烈建议使用TINYINT来代替ENUM类型

l 不使用TEXT、BLOB类型

l 禁止在数据库中存储明文密码

l 使用VARBINARY存储大小写敏感的变长字符串或二进制内容

l 使用尽可能小的VARCHAR字段。VARCHAR(N)中的N表示字符数而非字节数,最大1024

l 区分使用DATETIME和TIMESTAMP。存储年使用YEAR类型。存储日期使用DATE类型。 存储时间(精确 到秒)建议使用TIMESTAMP类型(不过需要注意:TIMESTAMMP最大时间到2037年)

l 所有字段均定义为NOT NULL,定义其默认值,建议数字字段default 0,字符串字段尽量default "",最好不要default null

五、索引设计

l 单张表中索引数量不超过5个

l 单个索引中的字段数不超过5个

l 索引名必须全部使用小写

l 非唯一索引按照“idx_字段名称[_字段名称]”进行命名。例如idx_age_name

l 唯一索引按照“uniq_字段名称[_字段名称]”进行命名。例如uniq_age_name

l 组合索引建议包含所有字段名,过长的字段名可以采用缩写形式。例如idx_age_name_add

l 表必须有主键,推荐使用UNSIGNED自增列作为主键

l 不使用更新频繁地列作为主键

l 尽量不选择字符串列作为主键

l 唯一键由3个以下字段组成,并且字段都是整形时,可使用唯一键作为主键。其他情况下,建议使用自增列 或发号器作主键

l 禁止冗余索引

l 禁止重复索引

l 禁止使用外键

l 联表查询时,JOIN列的数据类型必须相同,并且要建立索引

l 不在低基数列上建立索引,例如“性别”等

l 选择区分度大的列建立索引。组合索引中,区分度大的字段放在前

l 对字符串使用前缀索引,前缀索引长度不超过10个字符;如果有一个CHAR(200)列,如果在前10个字符内,多数值是惟一的,那么就不要对整个列进行索引。对前10个字符进行索引能够节省大量索引空间,也可能会使查询更快。

l 不对过长的VARCHAR字段建立索引。建议优先考虑前缀索引,或添加CRC32或MD5伪列并建立索引。

l 合理创建联合索引,(a,b,c) 相当于 (a) 、(a,b) 、(a,b,c)。

l 合理使用覆盖索引减少IO,避免排序

l 不在索引列做计算,例如:where (id+1) < 200,不在索引列使用函数,比如date_format()

六、SQL规范

l 使用预编译语句prepared statement,只传参数,比传递SQL语句更高效,一次解析多次使用,且能避免SQL注入

l 用IN代替OR。SQL语句中IN包含的值不应过多,应少于1000个

l 禁止隐式转换。数值类型禁止加引号;字符串类型必须加引号

l 避免使用JOIN和子查询。必要时推荐用JOIN代替子查询。

l 避免在MySQL中进行数学运算和函数运算

l 减少与数据库交互次数,尽量采用批量SQL语句

l 拆分复杂SQL为多个小SQL,避免大事务

l 获取大量数据时,建议分批次获取数据,每次获取数据少于2000条,结果集应小于1M

l 用UNION ALL代替UNION

l 统计行数用COUNT(*)

l SELECT只获取必要的字段,禁止使用SELECT *

l SQL中避免出现now()、rand()、sysdate()、current_user()等不确定结果的函数

l INSERT语句必须指定字段列表,禁止使用 INSERT INTO TABLE()

l 禁止单条SQL语句同时更新多个表

l 避免使用存储过程、触发器、视图、自定义函数等

l 建议使用合理的分页方式以提高分页效率

假如有类似下面分页语句: SELECT * FROM table ORDER BY TIME DESC LIMIT 10000,10; 这种分页方式会导致大量的io,因 为MySQL使用的是提前读取策略。 推荐分页方式:

第1种:SELECT * FROM table WHERE TIME

第2种:SELECT * FROM table inner JOIN (SELECT id FROM table ORDER BY TIME LIMIT 10000,10) as t

l 禁止在从库上执行后台管理和统计类功能的QUERY,必要时申请统计类从库

l 程序应有捕获SQL异常的处理机制,必要时通过rollback显式回滚

l 重要SQL必须被索引:update、delete的where条件列、order by、group by、distinct字段、多表join 字段

l 禁止使用%前导查询,例如:like “%abc”,无法利用到索引。

l 禁止使用负向查询,例如 not in、!=、not like

l 使用EXPLAIN判断SQL语句是否合理使用索引,尽量避免extra列出现:Using File Sort、Using Temporary

l 禁止使用order by rand()

l 不能在不同数据类型的字段上进行比较,避免字段类型转换损失性能

l SQL语句在程序中传入的参数值类型必须与字段在数据库中的类型相同

l INSERT语句必须写上具体的字段名称,写成:insert into table(字段1,字段2,...) values(值1,值2,...)。

l 在做批量更新/插入操作时,建议操作的数据行数不要太多,也不要太少,一般100~200行提交一次,避免频繁io操作

l 前端程序不允许使用set sql_mode和set tx_isolation(会话级事务隔离级别)语句

l 不能使用SELECT … FOR UPDATE语法,它会扩大意向锁范围即表锁,影响数据库的并发效率

l 新数据架构业务尽量join表不能超过3个

七、行为规范

l 表结构变更必须通知DBA进行审核

l 禁止有super权限的应用程序账号存在

l 禁止有DDL、DCL权限的应用程序账号存在

l 批量导入、导出数据必须通过DBA审核,并在执行过程中观察服务

l 产品出现非数据库导致的故障时,如被攻击,必须及时通DBA,便于维护服务稳定

l 业务部门程序出现BUG等影响数据库服务的问题,必须及时通知DBA,便于维护服务稳定

l 业务部门推广活动或上线新功能,必须提前通知DBA进行服务和访问量评估,并留出必要时间以便DBA完成扩容

l 出现业务部门人为误操作导致数据丢失,需要恢复数据的,必须第一时间通知DBA,并提供准确时间点、 误操作语句等重要线索。

l 提交线上建表改表需求,必须详细注明涉及到的所有SQL语句(包括INSERT、DELETE、UPDATE),便于DBA进行审核和优化

l 对同一个表的多次alter操作必须合并为一次操作

l 不要在MySQL数据库中存放业务逻辑

l 对特别重要的库表,提前与DBA沟通确定维护和备份优先级

l 不在业务高峰期批量更新、查询数据库

八、安全规范

1.服务器

l 必须分离MySQL的online,beta,dev环境,不在线上环境直接开发和做任何测试

2.账户权限

l 一个账号对应一个数据库,应用账户只能允许访问对应的数据库。

l 应用账号权限默认开启select/insert/update/delete/execute的权限。

l 每个应用建立一个账号,默认是可读写。 如果只读或只写,加_w,_r。

3.数据获取

l 有敏感信息的数据导出需要上级审批,防止数据泄露。

l 有批量导出数据的需求,需要告知DBA,开发人员不能直接到线上数据库批量导出数据。

你可能感兴趣的:(总结MySQL开发规范大全)