1、命名规范
- 所有表名库名字段索引名均小写字母,用下划线分割
MySQL
所有均忽略大小写设置lower_case_table_names
为1.- 库名、表名、字段名最大支持64个字符,为了统一规范、易于辨识以及减少传输量,禁止超过32个字符
- 库名、表名、字段名禁止使用
MySQL
保留字 - 库名、表名、字段名必须见名知意。命名与业务、产品线等相关联
- 临时库、表名必须以
tmp
为前缀,并以日期为后缀。例如tmp_test01_20130704
- 线上账号采用见名知意,以
RW
、RO
开头,例如:RW_XX
,访问XX应用的可读写的账号
2、基础规范
- 线上必须使用
innodb
存储引擎。 - 表字符集必须使用UTF8。
- 所有表必须要有注释,所有字段必须有用途注释。
- 禁止数据库存放图片以及文件等大数据。
- 每张表建议控制在100w以内。
- 禁止在线上做数据库压力测试。
- 禁止本地以及开发测试环境直连线上环境。
- 禁止个人账号直连线上主库
3、库表设计
- 禁止使用分区表
- 大字段字段单独存放,不允许使用
text
字段, 大文本字段建议存储至mongodb
或者hbase
之类的KV数据库 - 采用合适的分表分库策略,尽量让数据均匀分布, 建议使用用户id、订单id取模进行分表
- 禁止表中存放业务逻辑
- 所有表必须有主键,且主键采用INT自增模式.
- 所有表中字段避免过多导致数据量以及索引过多
4、字段设计
- 建议使用
UNSIGNED
存储非负数值 - 建议使用
INT
UNSIGNED
存储IP - 用
DECIMAL
代替FLOAT
和DOUBLE
存储精确浮点数,例如支付相关数据 - INT类型固定占4字节存储,例如
INT(10)
仅代表显示字符宽度为10位,不代表存储长度 - 区分使用
TINYINT
、SMALLINT
、MEDIUMINT
、INT
、BIGINT
数据类型。例如取值范围为0-80时,使用TINYINT
UNSIGNED
- 建议使用
TINYINT
来代替ENUM
类型 - 尽可能不使用
TEXT
、BLOB
类型 - 使用
VARBINARY
存储大小写敏感的变长字符串或二进制内容 - 使用尽可能小的
VARCHAR
字段。VARCHAR(N)
中的N表示字符数而非字节数 - 区分使用
DATETIME
和TIMESTAMP
。存储年使用YEAR
类型。存储日期使用DATE
类型。 存储时间(精确到秒)建议使用TIMESTAMP
类型 - 所有字段均定义为
NOT NULL
并且有DEFAULT
值
索引规范
- 使用
prepared statement
,可以提升性能并避免SQL注入 - 用
IN
代替OR
。SQL语句中IN包含的值不应过多,200以内 - 禁止隐式转换。数值类型禁止加引号、字符串类型必须加引号
- 避免使用
JOIN
和子查询。必要时推荐用JOIN
代替子查询 - 避免在
MySQL
中进行数学运算和函数运算 - 减少与数据库交互次数,尽量采用批量SQL语句
- 拆分复杂SQL为多个小SQL,避免大事务
- 获取大量数据时,建议分批次获取数据,每次获取数据少于2000条,结果集应小于1M
- 用
UNION ALL
代替UNION
- 统计行数用
COUNT(*)
- SELECT只获取必要的字段,禁止使用SELECT *
- SQL中避免出现
now()
、rand()
、sysdate()
、current_user()
等不确定结果的函数 - INSERT语句必须指定字段列表,禁止使用
INSERT INTO TABLE()
- 禁止单条SQL语句同时更新多个表
- 避免使用存储过程、触发器、视图、自定义函数等
- 建议使用合理的分页方式以提高分页效率
- 禁止在主库上执行后台管理和统计类功能的QUERY,必要时申请统计类从库
- 程序应有捕获SQL异常的处理机制,必要时通过
rollback
显式回滚 - 重要SQL必须被索引:
update
、delete
的where
条件列、order by
、group by
、distinct
字段、多表join
字段 - 禁止使用%前导查询,例如:
like “%abc”
,无法利用到索引 - 禁止使用负向查询,例如
not in、!=
、not like
- 使用EXPLAIN判断SQL语句是否合理使用索引,尽量避免extra列出现:
Using File Sort
、Using Temporary
行为规范
- 表结构变更必须通知DBA进行审核
- 禁止有super权限的应用程序账号存在
- 禁止有DDL、DCL权限的应用程序账号存在。
- 重要项目的数据库方案选型和设计必须提前通知DBA参与
- 批量导入、导出数据必须通过DBA审核,并在执行过程中观察服务
- 批量更新数据,如
UPDATE
、DELETE
操作,必须DBA进行审核,并在执行过程中观察服务 - 产品出现因数据库导致的故障时,如被攻击,必须及时通DBA,便于维护服务稳定
- 业务部门程序出现BUG等影响数据库服务的问题,必须及时通知DBA,便于维护服务稳定
- 业务部门推广活动或上线新功能,必须提前通知DBA进行服务和访问量评估,并留出必要时间以便DBA完成扩容
- 出现业务部门人为误操作导致数据丢失,需要恢复数据的,必须第一时间通DBA,并提供准确时间地点、误操作语句等重要线索
- 提交线上建表改表需求,必须详细注明涉及到的所有SQL语句(包括
INSERT
、DELETE
、UPDATE
),便于DBA进审核和优化 - 不要在MySQL数据库中存放业务逻辑
SQL建表示例
1 | CREATE TABLE `risk_rule_item` ( |
索引优化
- 字段类型转换导致不用索引,如字符串类型的不用引号,数字类型的用引号等,这有可能会用不到索引导致全表扫描;
- mysql 不支持函数转换,所以字段前面不能加函数,否则这将用不到索引;
- 不要在字段前面加减运算;
- 字符串比较长的可以考虑索引一部份减少索引文件大小,提高写入效率;
like %
在前面用不到索引;- 根据联合索引的第二个及以后的字段单独查询用不到索引;
- 不要使用
select *
; - 排序请尽量使用升序 ;
- or 的查询尽量用
union
代替 (Innodb
); - 复合索引高选择性的字段排在前面;
order by
/group by
字段包括在索引当中减少排序,效率会更高。
如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !