阿⾥开发⼿册mysql_MySQL开发准则(总结⾃阿⾥巴巴开发
⼿册)
命名规范
【强制】对象名称必须⽤⼩写或者⼩写、下划线、数字组成。
name;user_name;
【强制】对象名称禁⽌使⽤ MySQL 保留关键字。
如 ORDER 等
【强制】对象名称要见名知其意,不要超过 32 个字符。
nick_name,student_age,create_time
【强制】临时表要以 tmp 为前缀,⽇期为后缀。
tmp_export_user_20200721
【强制】备份表要以 bak 为前缀,⽇期为后缀。
bak_user_20200721
【强制】表名不使⽤负数名词。
【强制】表字段表⽰是否概念,⽤ is_xxx 表⽰。
is_default
【强制】索引名称,⽤特定_字段表⽰。
普通索引:idx_xxx
联合索引:un_xxx_xxx
唯⼀索引:uk_xxx
表设计规范
【强制】如⽆特殊需求,存储引擎使⽤ InnoDB。⽀持事务
⾏级锁
并发性能好
【强制】数据库和表的字符集统⼀使⽤ utf8 或者 utf8mb4。
不同字符集转化可能会产⽣乱码。怎么通过jquery实现跳转
不同字符集⽐较前会进⾏字符转换,索引失效。
UTF8 每个字符占⽤3字节,占⽤空间⼩,但是不能存储 emoj,emoj 占⽤4字节。
UTF8MB4 每个字符占⽤4字节,是真正的 UTF8,推荐使⽤。
【强制】数据库表和字段都需要添加备注,更好理解建表思路。
【建议】数据库表考虑分库分表细节,推荐使⽤snowflake作为ID主键。
单表设计存储数据少于 500 万条或单表容量超过 2G。
不建议使⽤分区表,容易造成全表死锁,跨分区查询效率低。
【强制】表每⼀⾏中的每列数据⼤⼩相加不能⼤于 65535 byte。
【强制】不要设置预留字段,更改会锁表。
【强制】不要保存⽂件等⼤的⼆进制数据。应放到⽂件服务器中。
【建议】InnoDB 字符集默认排序使⽤ _general_ci 和 _unicode_ci,推荐使⽤ _general_ci。ci不区分⼤⼩写
cs区分⼤⼩写
general速度更快,准确性稍低
【建议】表必备三个字段,id、create_time、modify_time。
id:unsigned bigint。单表时主键单表时⾃增1,需要分表使⽤snowflake。
create_time:datatime。创建时间。
modify_time:datatime。修改数据更新时间。
【强制】存储过程设计要合理,尽量少⽤。
过度复制逻辑容易死锁。
可以替换为在后端业务层或者脚本实现。
【强制】不要使⽤触发器。
⾼并发情况下不理想。
可以⽤事务替代。
【强制】数据量⼤的表要使⽤pt⼯具修改表结构。
pt-online-schema-change。
原理是新建⼀张表并复制原表结构与数据,最终删除原表,可以有效避免⾏锁及表锁。
字段设计规范
【强制】表字段表⽰是否概念,即is_xxx。
1表⽰是,0表⽰否
使⽤ unsigned tinyint
【强制】⼩数类型都使⽤decimal型。
decimal精确。
如果超出decimal范围建议分两个字段存储。
【强制】ip及⼿机号类固定长度字段,要⽤char。
【强制】选择合适的存储长度。
可以减少表存储空间。
可以减少索引长度,增加索引效率。
【建议】避免使⽤TEXT、BLOB数据类型。
内存临时表不⽀持TEXT和BLOB。会使⽤磁盘临时表,降低查询速度。
TEXT和BLOB需要单独成表,提⾼查询效率。
【建议】避免使⽤ENUM数据类型。
枚举类型order by效率低。
禁⽌使⽤数字作为枚举值。
在与php使⽤上1和’1’差别⼤,PHP是弱引⽤很容易把’1’写为1,1为key,’1’为内容。【建议】尽可能把列定义设置为 NOT NULL。
索引NULL列,会额外增加开销,占⽤更多表空间。
要做计算或者⽐较时,会对 NULL 做特别处理。
在 SQL 中对 NULL 进⾏判断会全表扫描。
opengl要不要开
【强制】时间类型不要使⽤ varchar 或 int 等。
使⽤ timestamp,占⽤4字节与int相同,查询计算⽐int快。
timestamp 取值范围,1970-01-01 00:00:01 ~ 2038-01-19-03:14:07。
使⽤ datatime,占⽤8字节,明确⽇期时间,超出timestamp⽤datatime。
驽马十驾 功在不舍 锲而不舍朽木不折
索引设计规范
textarea是单标签吗【强制】不要使⽤外键和级联,应放在应⽤层去做。
外键与级联更适合单机及低并发,不适合分布式和⾼并发集。
外键即外键约束,会影响写操作(插⼊速度),降低性能。
级联更新是强阻塞,存在更新风暴的风险。
【强制】⼀张表不要超过5个索引。
索引过多会降低性能。
合理分配索引会提⾼性能。
【强制】联合索引的左侧原则可以减少每个字段单独建⽴索引。
避免每个字段都建⽴索引。
联合索引区分度⾼的放在最左边。
联合索引如果存在⾮等号和等号混合时,把等号的索引放在最左边。
联合索引左侧原则,⼀定要注意顺序。
【强制】InnoDB 必须有主键。
结合建表四个必要字段,id作为主键。
InnoDB 属于索引组织表,逻辑顺序和索引的顺序相同。
单表时主键⾃增1。
预计三年内达到500万条,需要使⽤ snowflake 等分布式id⽣成主键。
不要使⽤ uuid、hash、md5 等作为主键,要有顺序概念。
【建议】查询想⾛特定索引时可以⽤force index。
MySQL的 optimizer 会执⾏它认为最优索引,但是往往不是我们需要或者最优的。
使⽤ force index 可以强制使⽤索引,结合 explain 使⽤,确认为最优。
【强制】有唯⼀索引需求,该字段就应设置唯⼀索引。
即使该字段是在联合索引内,也要单独设置唯⼀索引。
唯⼀索引对insert速度影响可以忽略,但是提⾼查询速度和唯⼀性是明显的。
应⽤层也建议做校验控制,但是根据墨菲定律,只要有可能就会出现脏数据。
【强制】varchar型设置索引要设置索引长度。jewish
不设置默认是全部长度。
建议索引长度为20,区分度可以达到90%。
区分度计算公式:select count(distinct left(列名, 索引长度))/count(*) FROM 表名。可以查出区分度百分⽐。
【强制】模糊查询最好⽤搜索引擎。
禁⽌使⽤like %str和like %str%。因为不⾛索引。
可以使⽤like str%。⾛索引。
也可以⾛全⽂索引,但是需要看配置,还是推荐搜索引擎。
【强制】order by 需要注意索引的有序性。
order by后接索引应该索引的⼀部分,如果是联合索引,应该是联合索引的最后,避免出现file_sort,影响查询性能。where a=? and
b=? order by c那么索引是(a,b,c)。
file_sort出现是没有⾛索引或者联合索引。出现情况:where a=? order by b索引是a。改进优化:where a=? order by b索引是(a,b)。
【强制】避免冗余索引。
重复索引:primary key(id)、index(id)、unique index(id)。
冗余索引:key(a,b,c)、key(a,b)、key(a)。
【强制】查询频率较⾼的sql语句,应该使⽤覆盖索引。
覆盖索引不是真正的索引,是⼀种使⽤索引⽅式。
原理是从索引中查询出想要内容,⽽不⽤回表查询,提⾼查询效率。
表现是explain的extra为Using index。
例如select user_no from user order user_age = 28索引为user_no时效率低,索引为(user_no,user_age)时为覆盖索引,查询效率⾼。
手机mysql安装配置教程
【强制】避免隐式类型转换。
定义和使⽤不同数据会造成隐式转换。
隐式转换会不⾛索引,降低查询效率。
如select user_age from user where user_no='111'
【强制】避免在字段位置写表达式,不⾛索引。
反例:select user_no from user where user_age*2 = 36。
正例:select user_no from user where user_age = 36/2。
查询优化
【强制】SQL性能优化⽬标,由⾼到低。
const。基本是只有⼀⾏匹配。
ref。基本是⾛普通索引。
range。基本是⾛范围索引。
index。⾛索引最差,和全表查询相似。
NULL。不⾛索引,全表查询。
【强制】不适⽤索引的⼏种情况。
不等式:!=、<>。
null判断:is null、is not null。
like模糊查询:like %a、like %a%
not in。
【建议】避免使⽤IN操作,如果避免不了,需⼩于1000条。
多表查询IN会影响查询效率。
可以⽤between替代。
IN(select * from)索引会失效,可以使⽤join(left、right、inner、full)来实现。
【建议】join优化。
最好在三张表之内,最多不要超过5个,理论可以61个。
on关联字段类型要相同。
每关联⼀个表就会多分配⼀个关联缓存,和join_buffer_size设置相关。占⽤内存过⼤会形成溢出,影响性能和稳定性。
left join的驱动表是左侧表。
inner join的驱动表是数据少的表。
right join的驱动表是右侧表。
MySQL没有full join,可以⽤SQL实现。例如:select * from A left join B on B.name = A.name where B.name is null union all select * from B。
尽量利⽤⼩表驱动⼤表,可以减少循环嵌套次数。
straight join的使⽤。前提是inner join内连接。inner join优先查询⼩表,但有group by、order by等file_sort,Using temporary时会想改变优先查询表顺序,这时可以使⽤straight join。straight join强制优先查询表为左侧表。
⼀定要是内连接才能使⽤straight join,否则数据可能不准确。
【强制】禁⽌select * 出现。
select * 增加额外解析成本。
增减字段对前端映射不⼀致。
⽆⽤字段增加⽹络消耗。
⽆法使⽤覆盖索引。
【强制】禁⽌使⽤不带字段的insert出现。
正例:insert into user(user_no,user_age) values (123,18)
反例:insert into user values (123,18)
【强制】尽量避免⼦查询。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。