MySQL Best Practices

来自公司一名dba的分享,很好的blog:

===============================================================

以下给出一些合理使用MySQL的建议:

核心

  • 尽量不在数据库做运算

让数据库多做她擅长的事:

-尽量不在数据库做运算

-复杂运算移到程序端cpu

-尽可能简单应用mysql

举例:md5()/order by rand()

 

  • 控制单表数据量

-一年内单表数据量预估

--纯int不超过1000w

--纯char不超500w

-建议单库不超过300-400个表

 

  • 保持表身段苗条

-表字段数少而精

--io高效 --全表遍历 --表修复快 --提高并发 --alter table快

-单表1G体积500w行评估

--顺序读1G文件需要N秒

--单行不超过200byte

--单表不超过50个纯int字段

--单表不超过20个char(10)字段

-单表字段数上限控制在20~50个

 

  • 平衡范式与冗余

-严格遵循三大范式?

-效率优先、提升性能

-没有绝对的对与错

-适当牺牲范式、加入冗余

-但会增加代码复杂度

 

  • 拒绝3B

-数据库并发像城市交通

--非线性增长

-拒绝3B

--大sql(Big sql)

--大事务(Big transaction)

--大批量(Big batch)

 

字段类

  • 用好数值字段类型

-tinyint(1byte)

-smallint(2b)

-mediumint(3b)

-int(4b)、bigint(8b)

-float(4b)、double(8b)

-decimal(m,d)

bad case:

-int(1) vs int(11)

-bigint auto_increment

-decimal(18,0)

 

  • 将字符转化为数字

-数字型vs字符串型索引

--更高效

--查询更快

--占用空间更小

举例:用无符号int存储ip,而非char(15)

-int unsigned

-inet_aton()

-inet_ntoa()

 

  • 优先使用enum或set

-优先使用enum或set

--字符串

--可能值已知且有限

-存储

--enum占用1字节,转为数值运算

--set视节点定,最多占用8字节

--比较时需要加'单引号(即使是数值)

-举例

--sex enum('F','M') comment '性别'

--c1 enum('0','1','2','3') comment '职位'

 

  • 避免使用null字段

-避免使用null字段

--很难进行查询优化

--null列加索引,需要额外空间

--含null复合索引无效

-举例

--a char(32) default null

--b int(10) not null

--c int(10) not null default 0

 

  • 少用并拆分text/blob

-text类型处理性能远低于varchar

--强制生成硬盘临时表

--浪费更多空间

--varchar(65535)==>64k(注意utf-8)

-尽量不用text/blob数据类型

-若必须使用则拆分到单独的表

 

  • 不在数据库里存图片

 

索引类

  • 谨慎合理添加索引

-谨慎合理添加索引

--改善查询

--减慢更新

--索引不是越多越好

-能不加的索引尽量不加

--综合评估数据密度和数据分布

--最好不超过字段数的20%

-结合核心sql优先考虑覆盖索引

-举例

--不要给“性别”列创建索引

 

  • 字符字段必须建前缀索引

 

  • 不在索引列做运算

-不在索引列进行数学运算或函数运算

--无法使用索引

--导致全表扫描

 

  • 自增列或全局id做innodb主键

-对主键建立聚簇索引

-二级索引存储主键值

-主键不应更新修改

-按自增顺序插入值

-忌用字符串做主键

-推荐用独立于业务的auto_increment列或全局id生成器做代理主键

-若不指定主键,innodb会用唯一且非空值索引替代

 

  • 尽量不用外键

-外键可节省开发量

-有额外开销

-逐行操作

-可‘达到’其它表,意味着锁

-高并发时容易死锁

-由程序保证约束

 

sql类

  • sql语句尽可能简单

-大sql vs 多个简单sql

--传统设计思想

--but mysql not

--一条sql只能在一个cpu运算

--可能一条大sql就把整个数据库堵死

-拒绝大sql,拆解成多条简单sql

--简单sql缓存命中率更高

--减少锁表时间,特别是myisam

--用上多cpu

 

  • 保持事务(连接)短小

-保持事务/db连接短小精悍

--事务/连接使用原则:即开即用,用完即关

--与事务无关操作放到事务外面,减少锁资源的占用

--不破坏一致性的前提下,使用多个短事务代替长事务

 

  • 尽可能避免使用sp/TRIG/FUNC

你可能感兴趣的:(MySQL Best Practices)