命名规范

【强制】对象名称必须用小写或者小写、下划线、数字组成。

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。

不同字符集转化可能会产生乱码。

不同字符集比较前会进行字符转换,索引失效。

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 进行判断会全表扫描。

【强制】时间类型不要使用 varchar 或 int 等。

使用 timestamp,占用4字节与int相同,查询计算比int快。

timestamp 取值范围,1970-01-01 00:00:01 ~ 2038-01-19-03:14:07。

使用 datatime,占用8字节,明确日期时间,超出timestamp用datatime。

索引设计规范

【强制】不要使用外键和级联,应放在应用层去做。

外键与级联更适合单机及低并发,不适合分布式和高并发集群。

外键即外键约束,会影响写操作(插入速度),降低性能。

级联更新是强阻塞,存在更新风暴的风险。

【强制】一张表不要超过5个索引。

索引过多会降低性能。

合理分配索引会提高性能。

【强制】联合索引的左侧原则可以减少每个字段单独建立索引。

避免每个字段都建立索引。

联合索引区分度高的放在最左边。

联合索引如果存在非等号和等号混合时,把等号的索引放在最左边。

联合索引左侧原则,一定要注意顺序。

【强制】InnoDB 必须有主键。

结合建表四个必要字段,id作为主键。

InnoDB 属于索引组织表,逻辑顺序和索引的顺序相同。

单表时主键自增1。

预计三年内达到500万条,需要使用 snowflake 等分布式id生成主键。

不要使用 uuid、hash、md5 等作为主键,要有顺序概念。

【建议】查询想走特定索引时可以用force index。

MySQL的 optimizer 会执行它认为最优索引,但是往往不是我们需要或者最优的。

使用 force index 可以强制使用索引,结合 explain 使用,确认为最优。

【强制】有唯一索引需求,该字段就应设置唯一索引。

即使该字段是在联合索引内,也要单独设置唯一索引。

唯一索引对insert速度影响可以忽略,但是提高查询速度和唯一性是明显的。

应用层也建议做校验控制,但是根据墨菲定律,只要有可能就会出现脏数据。

【强制】varchar型设置索引要设置索引长度。

不设置默认是全部长度。

建议索引长度为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)时为覆盖索引,查询效率高。

【强制】避免隐式类型转换。

定义和使用不同数据会造成隐式转换。

隐式转换会不走索引,降低查询效率。

如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)

【强制】尽量避免子查询。

子查询一般在IN中。

子查询会创建临时表,不会存在索引。

结果集大的子查询,性能越差。

可以使用join替代。

【强制】查询一条或者是否有数据时,要使用limit 1。

索引效率最高。

explain的type为const。

【建议】order by字段没有索引就不要排序。

order by字段有索引会按索引排序。没有索引影响效率。

可以设置索引,或者覆盖索引。

【建议】尽量不使用or。

同一字段用IN、between等替代or,因为很多情况不会走索引。

多字段下or两边都需要是索引且其他条件也是索引,才会走索引。

最好使用union、union all来替换。

【建议】尽量用union all替代union。

union会集合后进行唯一性去重,涉及到排序,加大资源开销。

在没有重复数据情况强制使用union all。

【建议】拆分大且复杂的SQL。

一条SQL只会使用一个CPU。

拆成多个小SQL可以通过并行提高查询效率。

【强制】禁止使用ORDER BY RAND()

随机排序性能差。

可以用其他SQL替换。

原:select id from 'dynamic' order by rand() limit 1;,

新:select id from 'dynamic' t1 join (select rand() * (select max(id) from 'dynamic') as nid) t2 on t1.id > t2.nid limit 1;注意,此查询只能随机一条id,并连续查询该id的顺序条数,具体情况具体分析,适用随机取一条,不应用随机取多条。

随机取多条解决方案:先查询所有id->在后端业务层做随机id->IN该id组。

rand()取值范围:[ 0 , 1 )。

【强制】禁止对where条件字段进行函数转换。

不走索引。

正例:select user_age from user where create_time>'20190320'

反例:select user_age from user where date(create_time)>'20190320'

【建议】in、exists、not in、not exists。

in是子查询,优先查询驱动表为内表,所以适合内表数据小的情况。

exists优先查询驱动表为外表,适合外表数据小的情况。

不建议使用not in和not exists,不走索引且容易混淆。

建议用其他SQL替代。

反例:select a.user_age from user a where a.user_no not in (select b.user_no from user_info b)。

正例:select a.user_age from user a left user_info b on a.user_no = b.user_no where b.user_no is null。

【建议】offset偏移量、分页。

分页数据量大的情况会影响查询效率,因为不是跳过offset行,而是查询offset+N行,然后抛弃offset行。

优化举例1:select user_age from user where user_no > 13333 limit 20。

优化举例2:select a.user_age from user a,(select user_no from user limit 13333,20)b where a.user_no = b.user_no。

【强制】范围查询注意。

between、>、

【强制】count()相关。

统计行数要使用count(*),不要使用count(列名)。

count(*)会统计NULL数据,count(列名)不会统计NULL数据。

当某一列的值全为NULL时,count(列名)返回的结果为0,但sum(列名)结果为NULL,因此使用sum(列名)需要使用IFNULL判断。

例如:select if(ifnull(sum(user_name)),0,sum(user_name))user_age from user

阿里开发手册mysql_MySQL 开发准则(总结自阿里巴巴开发手册)相关推荐

  1. 阿里巴巴开发手册“泰山”版它来了,1.4.0+终极版+阿里内部PPT

    阿里的<Java开发手册>距离上次发布已经过去了 10 个月了,而这次发布也增加了很多干货内容,比如:新增 34 条规约,修改描述 90 处,其中错误码规则更是第一次提出完整的解决方案,发 ...

  2. 阿里巴巴开发手册之应用分层

    阿里巴巴开发手册自己所感 应用分层 总结:其实,对于*****的开放接口设计来说,manager层实在 业务逻辑层之上的,区别并不是很大,但是service 和 manager 可以互相转化 ,就数据 ...

  3. 阿里巴巴开发手册——集合

    阿里开发手册笔记:集合 1.ArrayList的sublist(form,to) 返回父list的一个视图,包含from不包含to,它是ArrayList的内部类,无法强制转换成ArrayList. ...

  4. 全套阿里巴巴开发手册和大神解读一起给你【2022年整理】

    前些日子查些资料想要看一下阿里巴巴开发手册,网上一搜出来了一大推,也搞不清楚哪个,更让人讨厌的是有很多介绍开发手册文章的是某些培训机构来吸引流量的,都能看得来的写文章的人根本不懂这些东西,最后放个二维 ...

  5. 阿里巴巴开发手册笔记-----数据库篇

    阿里巴巴开发手册笔记 阿里开发团队发表的java开发规范,下面我在学习了之后做一个简单的总结.此篇为数据库篇. 数据库 (一)建表约定 1.表达是与否的概念的字段,必须使用is_xxx的方式来命名.数 ...

  6. 魔法值是什么?(为什么在阿里巴巴开发手册中提到不允许任何魔法值直接出现在代码中)

    在阿里巴巴开发手册中,提到魔法值,是在最开始的常量定义中提到的.即如下图: 那么,魔法值究竟是什么? 在al手册中说是未经预先定义的常量. 其实这样说就已经很明了了,但毕竟是一个不常见的概念,所以我在 ...

  7. 包机制、阿里巴巴开发手册

    公司域名倒置作为包名 com.baidu.www 阿里巴巴开发手册可百度搜索看看

  8. 关于阿里巴巴开发手册不得使用外键与级联,一切外键概念必须在应用层解决的疑惑

    原文地址:http://www.codes51.com/itwd/4517194.html 问题: 关于阿里巴巴开发手册"不得使用外键与级联,一切外键概念必须在应用层解决"的疑惑 ...

  9. 阿里云大数据ACP(一)大数据开发平台 DataWorks

    文章目录 一.DataWorks 简介 1.1 DataWorks 的功能概述 1.2 DataWorks 产品特点 1.3 DataWorks 产品优势 1.4 应用场景 (助力企业搭建大数据信息平 ...

  10. (阿里巴巴开发手册)为什么阿里巴巴推荐内部员工使用StringBuilder?

    今日我在阅读阿里巴巴开发手册泰山版,发现开发手册上有这么一条:[推荐] 循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展. 字符串的三种表示类型 Strin ...

最新文章

  1. 1016. 部分A+B (15)
  2. 马士兵java视频学习顺序
  3. 什么意思_手机HD是什么意思 手机信号区显示hd是什么意思
  4. IOS学习之蓝牙4.0
  5. apmserv 5.2.6 升级php,APMServ5.2.6 升级PHP版本 到高版本 5.3,5.4
  6. vue 判断两对象是否一致_vue - 比较两个Json对象是否相等
  7. 采用Locust对grpc协议进行压测
  8. 亚信安全中标南方电网网络架构优化调整项目 智能联动抑制未知威胁
  9. python string_Python String center()
  10. 为什么世界上没有安全的工作
  11. docker基础1--下载制定docker镜像的两种方法:
  12. ArcMap基本操作
  13. java 10阶乘_java编程求1到10的阶乘
  14. filecmp.dircmp实现递归比对两个目录
  15. wifi共享大师,去除弹窗广告。
  16. SDHC或SD2.0卡的驱动程序的注意事项
  17. vue父子传值,slot插槽的使用
  18. 记录一次上网正常但是【登录客户端应用网络异常问题】
  19. Java中 9 种常见的 CMS GC 问题分析与解决
  20. Struts2介绍(一个大的工具库)

热门文章

  1. 山寨手机软件测试工程师,安卓手机跑分作弊方法公布,仅供学习交流 Chainfire3D...
  2. c语言万能编程模板_51、STC单片机C语言通用万能编程模板
  3. 我的世界1.14刷雪机java版_我的世界全自动刷雪机图文攻略
  4. 虚拟化之——内存虚拟化
  5. 众安实业持续看好萤石矿产资源,新能源产业发展前景
  6. 机器学习深度学习高阶内容系列-kaggle广告点击欺诈识别实战
  7. p2p终结者ver207 注册码
  8. linux系统能连接wifi密码,Linux下通过命令连接wifi
  9. 云曦网络空间安全实验室第一次考试WP
  10. 发那科机器人示教盒复位键是哪个_发那科示教器维修 大连发那科机器人伺服放大器维修 伺服电机维修...