配置规范
-
MySQL
数据库默认使用InnoDB
储存引擎 - 保证字符集设置统一,
MySQL
数据库相关系统,数据库,表的字符集都使用UTF8
,应用程序连接,展示等可以设置字符集的地方也都要统一设置为UTF8
字符集 -
MySQL
数据库的事务隔离级别默认是RR(Repeatable-Read)
,建议初始化时统一设置为RC(Read-Committed)
,对于OLTP
业务更加合适。 - 数据库中的表要合理的规划,控制单表数据量,对于
MySQL
数据库来说,建议单表记录数控制在2000w以内。 -
MySQL
实例下,数据库,表数量尽可能少。数据库一般不超过50
个,每个数据库下,数据表数量一般不超过500
个。
建表规范
-
InnoDB
禁止使用外键约束,可以通过程序层面保证。 - 存储精确浮点数必须使用
decimal
替代fload
和double
。decimal 适用于货币数据
- 整型定义中无需定义显示宽度,比如:使用
int
,而不是int(4)
。 - 不建议使用
enum
类型,可以使用tinyint
来替代。 - 尽可能不要使用
text
,blob
类型,如果必须使用,建议将过大字段或是不常用的描述类型较大字段拆分到其他表中,另外,禁止用数据库存储图片或文件。 - 存储年时使用
YEAR(4)
,不使用YEAR(2)
- 建议字段定义为
not null
。 - 建议DBA提供SQL审核工具,建表规范性需要通过审核工具审核。
命名规范
- 库,表,字段全部采用小写。
- 库名,表名,字段名,索引名称均使用小写字母,并以'_'分隔。
- 库名,表名,字段名建议不超过12个字符。(库名,表名,字段名最多支持64个字符,但是为了统一规范,易于识别以及减少传输量,统一不超过12个字符)
-
库名,表名,字段名见名知意,不需要添加注释。
命名列表.png
索引规范
- 索引建议密码规则:
idx_col1_col2[_colN], uniq_col1_col2[_colN]
(如果字段过长建议采用缩写) - 索引中的字段数建议不超过5个。
- 单张表的索引个数控制在5个以内。
-
InnoDB
表一般都建议有主键列,尤其在高可用集群方案中作为必须项。 - 建立复合索引时,优先将选择性高的字段放在前面。
-
update,delete
语句需要根据where
条件添加索引。 - 不建议使用
%
前缀模糊查询,例如like '%weibo'
,无法用到索引,会导致全表扫描。 - 合理利用和覆盖索引,例如:
SELECT email, uid FROM user_email WHERE uid = xx
,如果uid
不是主键,可以创建覆盖索引idx_uid_email(uid, email)
来提高查询效率。 - 避免在索引字段使用函数,否则会导致查询时索引失效。
- 确认索引是否需要变更是要联系DBA。
应用规范
- 避免使用储存过程,触发器,自定义函数等,容易将业务逻辑和DB耦合在一起,后期做分布式方案时会成为瓶颈。
- 考虑使用
union all
,减少使用union
不去重,而少了排序操作,速度相对比union
要快,如果没有去重,优先使用union all
。 - 考虑使用
limit N
,少用limit M, N
,特别是大表,或者M比较大的时候。 - 减少或避免排序,如:
group by
语句中如果不需要排序,可以增加order by null
。 - 统计表中记录数时使用
count(*)
,而不是count(primary_key)
和count(1)
。InnoDB
表避免使用count(*)
操作,计数统计实时要求较强可以使用Memcache
或者Redis
,非实时统计可以使用单独统计表,定时更新。 - 做字段变更操作(
modify column / change column
)的时候必须加上原有的注释属性,否则修改后哦,注销会丢失。 - 使用
prepared statement
可以提高性能并且避免SQL
注入。 -
SQL
语句中IN
包含的值不应过多。 -
update
,delete
语句一定要有明确的where
条件。 -
where
条件中的字段值必须符合该字段的数据类型,避免MySQL
进行隐式类型转化。 -
select
,insert
语句必须显式的指明字段名称,禁止使用SELECT *
或者INSERT INTO table_name VALUES()
。 -
insert
语句使用batch提交(INSERT INTO table_nameVALUES(), (), ()
),VALUES
的个数不应过多。
相关知识补充
-
UTF8格式是存储不了表情类的数据,需要使用UTF8MB4,可在MySQL字符集里面设置。在8.0中已经默认为UTF8MB4,可以根据公司的业务情况进行统一或者定制化设置
-
数据库事务隔离级别由低到高Read uncommitted、Read committed、Repeatable read和Serializable等四种。
ANSI/ISO SQL标准定义了4中事务隔离级别:未提交读(read uncommitted),提交读(read committed),重复读(repeatable read),串行读(serializable)。
- 数据库不同,其支持的事务隔离级别亦不相同。
- MySQL数据库支持上面四种事务隔离级别,默认为Repeatable read。
- Oracle 数据库支持Read committed和Serializable两种事务隔离级别,默认为Read committed。
- Read committed(读提交):可以避免脏读,但可能出现不可重复读和幻读。
- 大多数数据库默认级别就是Read committed,比如Sql Server数据库和Oracle数据库。
注意:该隔离级别在写数据时只会锁住相应的行。
-
对于不同的事务,采用不同的隔离级别分别有不同的结果。不同的隔离级别有不同的现象。主要有下面3种现在:
- 脏读(dirty read):一个事务可以读取另一个尚未提交事务的修改数据。
- 非重复读(nonrepeatable read):在同一个事务中,同一个查询在T1时间读取某一行,在T2时间重新读取这一行时候,这一行的数据已经发生修改,可能被更新了(update),也可能被删除了(delete)。
- 幻像读(phantom read):在同一事务中,同一查询多次进行时候,由于其他插入操作(insert)的事务提交,导致每次返回不同的结果集。
-
不同的隔离级别有不同的现象,并有不同的锁定/并发机制,隔离级别越高,数据库的并发性就越差,4种事务隔离级别分别表现的现象如下表:
隔离级别 脏读 非重复读 幻像读
---
read uncommitted 允许 允许 允许
---
read committed 允许 允许 X
---
repeatable read 允许 X X
---
serializable X
网友评论