MySQL 进阶02

-----转自 【王者-YCZ】的笔记

三、SQL开发的规范和建议

1.SQL语句分类
DDL : 数据定义语言
DCL : 数据控制语言
DML : 数据操纵语言
DQL:数据操纵语言(查询)
2.DDL规范

操作:
  CREATE 
  DROP 
  ALTER 

规范: 
  1. 库名不要使用大写字母,数字开头 
  2. 库名要和业务有关
  3. 不要使用内置关键字
  4. 创建数据库要加字符集(UTF8MB4)
  5. 生产中禁用DROP操作
  6. 字符集修改:从小到大,比如: utf8 ---> utf8mb4

表:

操作:
  CREATE 
  DROP 
  ALTER
  TRUNCATE

规范: 
  1. 表名不要使用大写字母,数字开头
  2. 表名要和业务有关
  3. 选择合适的数据类型(完整的,简短的,符合数据特点)
  4. 建表要有主键。
  5. 每个列要加非空约束,并设定默认值0。
  6. 每个列要有注释,comment,每个表要有注释。
  7. 每个表要设置存储引擎(innoDB)和字符集(utf8mb4).
  8. 生产禁用DROP操作
  9. alter做表结构变更时,大表不能在业务繁忙期间变更;
  如果一定需要,交给DBA来做,通过PT-OSC,在线做DDL,对业务影响小。
  在线DDL:在8.0版本以前需要的操作,8.0版本以后就不需要了,因为源数据库只有一份,而不是多份。
  10.TRUNCATE,历史归档数据应用,使用truncate配合分区表进行实现,避免使用Delete。
3.DCL规范
操作:
  grant 
  revoke 
规范:
  1.遵循权限最小化。
4.DML规范
操作:
  insert
  update
  delete

规范: 
	1.insert,尽量批量,尽量精准录入<将字段名写全>
		insert into t1(id,name) values(...,...),(...,...),(...,...);
	2.大的事务,进行拆分,避开业务繁忙期。
	3.update/delete,必须加where条件。
	4.delete操作尽量替换为update。(使用状态列,逻辑删除)
	5.整表删除,不用delete,用truncate.
5.DQL规范
操作:
	select:MySQL Select与其他数据库的不同
1.查询设定的参数
mysql> select @@port;
mysql> select @@datadir;
mysql> select @@socket;
mysql> select @@innodb_flush_log_at_trx_commit;
mysql> show variables;
mysql> show variables like '%trx%';

select @@sql_mode; 					查看SQL_MODE规范
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 

2.计算 
mysql> select 1+1;

3.调用函数
mysql> select now();
6.关键字逻辑执行顺序
    from
    where
    group by
    having
    select
    distinct 
    order by
    limit
解析:
1.找到表:from
2.拿着where指定的约束条件,去表中取出一条条记录
3.将取出的一条条记录进行分组group by,如果没有group by,则整体作为一组
4.将分组的结果进行having过滤
5.执行select
6.distinct去重
7.将结果按条件排序:order by
8.限制结果的显示条数

了解:
	其中,group by中做了三件事:排序,去重,分组。
7.关于删表的面试题
drop table t1    : 表结构 + 表段全部物理删除
trucate table t1 : 保留表结构,清空表段的数据页,属于物理删除
delete from t1   : 保留表结构,逐行删除表的每行数据,属于逻辑删除,会产生大量日志和碎片.
8.group by
1.原因:在5.7的版本中,group by加入了 ONLY_FULL_GROUP_BY 的SQL_MODE限制。
2.示例:
select a , b ,count(c) 
from t1 
group by a;

报ONLY_FULL_GROUP_BY错:
	在select后的列表,例如b,没有在函数里包裹,也没再group by后出现就报错。

不报错的情况:
	如果分组列,即a列,可以唯一确认一个唯一对象时(比如,主键),就不会违反SQL_MODE。

四、索引原理和优化

索引作用:提供了类似于书中目录的作用,目的是为了优化查询。
1.MySQL的索引类型
B树索引
Hash索引
R树
Full text
GIS 
2.B树查找算法
BTREE 
B+TREE:叶子节点之间有双向指针。
B*TREE:叶子节点之间和枝节点之间都有双向指针。

1.B树对等值查询有一定的优势,而对范围的查询则需要采用B+树与B*树。
2.mysql中innodb引擎用的是B*树;myisam引擎用的是普通B树。

B*树图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vh7zZsuf-1572831560858)(assets/6.png)]

3.MySQL中innodb引擎的索引
可分为聚集索引、辅助索引(也称为二级索引或者普通索引)两大类。

聚集索引:
	1.如果建表时有主键,自动选择主键列作为聚集索引列
	2.如果没有主键,则选择唯一键作为聚集索引列
	3.如果都没有,则自动生成隐藏聚集索引	
	4.聚集索引只能有一个,非空唯一,一般是主键
	5.聚集索引叶子节点,就是磁盘的数据行存储的数据页
	6.MySQL是根据聚集索引,组织存储数据的,数据存储时就是按照聚集索引的顺序进行存储数据

辅助索引:
  1.辅助索引,可以有多个,是配合聚集索引使用的
  2.辅助索引,只会提取索引键值,进行自动排序生成B树结构

辅助索引细分:
  1.普通的单列辅助索引
	2.联合索引:多个列作为索引条件,生成索引树,理论上设计的好的,可以减少大量的回表查询
	3.唯一索引:索引列的值都是唯一的

索引相关命令:
  创建单列索引:alter table 表名 add index 索引名称(索引字段);
  创建联合索引:alter table 表名 add index 索引名称(索引字段1,索引字段2);
  创建前缀索引:alter table 表名 add index 索引名称(district(前缀字符数));
  删除索引:alter table 表名 drop index 索引名称;
同一个表中,索引名不能同名。
4.聚集索引构建B树结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VTnvbYS2-1572831560860)(assets/4.png)]

解析:

聚集索引的树如同上图构成,此时,只能加速条件为id字段的查询。
5.辅助索引构建B树结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-md5yrSHk-1572831560861)(assets/5.png)]

解析:

1.先将索引列name字段进行排序;
2.排完序后,生成叶子节点,枝节点,根节点;
3.由于是要查找整行数据,因此在构建树时,还会存储pk的值;
4.首先根据name字段条件查询到pk的值,然后通过pk值,回到聚集索引的表,获取整行数据;
5.辅助索引列的值中,如果重复值过多,会造成回表的次数增多,回表的次数多,IO的次数就多,而且还是随机IO,因为辅助索引中的列重新排序后,回表后,所在行就不是顺序的了;
6.因此,设计辅助索引除了为增强当前索引列查询的速度,还需要尽肯能地减少回表的次数
(可以通过选择重复值较少的列以及使用联合索引来减少回表的次数)。
6.聚集索引和辅助索引最大的区别(重要)
在叶子节点处,
	聚集索引存储的是整行数据;
	辅助索引存储的是索引列键的值,以及对应的pk值。
	在查询时,辅助索引是配合聚集索引进行查询的,而不是单独使用。
7.索引树高度的影响因素
影响因素:
	1.表的数据行
	2.索引列值过长
	3.数据类型
对应的解决策略:
	1.分表,分库,数据库缓存
	2.使用前缀索引
	3.选择合理,简短的数据类型
8.索引执行计划获取
1.命令:
	explain SQL查询语句;		或者		desc SQL查询语句;
	
2.通过命令获取到的是优化器选择完成的,它认为代价最小的执行计划。

3.作用: 语句执行前,先看执行计划信息,可以有效的防止性能较差的语句带来的性能问题,
如果业务中出现了慢语句,我们也需要借助此命令进行语句的评估,分析优化方案。
9.索引执行计划分析(重要)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5ZB5v1Mu-1572831560861)(assets/7.png)]

1.type:查询类型

共分为:ALl,index,range,ref,eq_ref,const(system)六种查询类型。

各种查询类型出现的情况:
1.ALl:全表扫描,不走索引。
	a.查询条件列,没有索引 
	b.查询条件出现以下语句(辅助索引列):
		<>、not in()、like"%aa%"、隐式转换、where中条件进行计算、索引失效(统计信息过旧)
  c.注意:对于聚集索引列,使用以上语句,依然会走索引

2.index:全索引扫描

3.range:索引范围扫描
	a.查询条件出现以下语句(辅助索引列):
		<、>、>=、<=、between and、like "a%"、or、in
	b.查询语句中出现or、in,是不能享受到B+树算法优势的;
		因为or,in里面的值有可能不是顺序的,不能利用到双向指针,只能重新全索引查询;
		此时,可以使用 union all 来替代or或者in。
		示例:
			 select * from t1 where num in ("110","119");
			 可以替换为:
			 select * from t1 where num="110"
			 union all
			 select * from t1 where num="119";
		注意,用 union all 替换后,查询类型将不再显示range,而是显示两条ref的查询类型。

4.ref:非唯一性索引,等值查询。

5.eq_ref:多表连接查询,右表的关联列是主键或者唯一键。

6.const(system):主键或者唯一键的等值查询。

2.key_len:应用索引的长度

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3y0y8zSp-1572831560861)(assets/8.png)]

解析:

按预留的最大长度来计算:
	tinyint:最大长度为1个字节,如果没有设置not null,则需要预留1个字节的长度来存储是否为null;
	int:最大长度为4个字节,如果没有设置not null,则需要预留1个字节的长度来存储是否为null;
	char(5):根据字符编码集,由于utf8mb4编码1个字符最大为4个字节,因此为5*4,如果没有设置not null,则需要预留1个字节的长度来存储是否为null;
	varchar(5):varchar数据类型中的"abcde"占据的是6个字节长度,还有一个字节需要用来存储一共为5个字节,且varchar在超过255字节长度时,需要用两个字节来存放长度,因此,根据按预留的最大长度计算,varchar(5)的key_len长度为5*4+2,如果没有设置not null,则需要预留1个字节的长度来存储是否为null。
	

联合索引应用:
idx_a_b_c(a,b,c)  ==>  查询条件为:a, ab, abc时,可以应用到索引。
	1.where a=? and b=? and c=?
		where条件的等值查询,当三个索引列都在时,无关摆放顺序,全都可以走联合索引。
	2.where a=? and c=?
		只会走a的索引,c的索引不会走。
	3.where a=? and b>? and c=?
		只会走a和b的索引,c的索引不会走;如果联合索引建立改成index(a,c,b),则a,b,c的三个索引都会走
	4.建立联合索引时,在多子句的情况下,应按照子句的顺序建立。
	5.建立联合索引时有顺序讲究,查询时则没有;在建立联合索引时,重复值少的列应该放在最左侧。

3.extra:额外信息

filesort:额外的文件排序
出现原因:在创建的索引没有应用到时,才会进行额外的排序。
出现情况:group by、order by、distinct、union
解决:建立联合索引,将group by和where的列一起建立联合索引。
10.面试题
题目意思:我们公司业务慢,请你从数据库的角度分析原因。
mysql出现性能问题,总结有两种情况:
	1.应急性地慢:突然夯住
		处理过程:
			a.show processlist;  	获取到导致数据库hang的语句
			b.explain 						分析SQL的执行计划,有没有走索引,索引的类型情况
			c.建索引,改语句
	2.一段时间慢(持续性的):
			a.记录慢日志slowlog,分析slowlog
			b.explain   分析SQL的执行计划,有没有走索引,索引的类型情况
			c.建索引,改语句
11.建立索引的场景
1.必须要有主键,如果没有,可以创建无关列作为主键条件的列
2.索引列要是经常作为where order by  group by  join on, distinct 的条件的列
3.最好使用唯一值多的列作为索引,如果索引列重复值较多,可以考虑使用联合索引
4.列值长度较长的索引列,建议使用前缀索引
5.降低索引条目,不要创建没用索引,不常使用的索引要清理
6.索引维护要避开业务繁忙期
7.构建索引后,查询类型至少要到range及以上才好。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 实战》是一本探讨MySQL数据库高级应用和实战技巧的书籍。MySQL是一种广泛使用的开源关系型数据库管理系统,在Web开发和数据分析等领域有着重要的应用。 《MySQL 实战》将帮助读者理解MySQL的高级功能和最佳实践,一步优化数据库的性能和稳定性。本书主要内容包括: 1. 高级查询优化:介绍如何使用索引、列存储和分区技术来提高查询性能,避免慢查询和死锁等问题。 2. 数据库设计与架构:详细讲解如何设计合理的数据库模型,包括表关系、数据类型和字段命名规范,以及应对高并发和大数据量的应用场景。 3. 高可用与备份恢复:介绍如何设置主从复制、集群和故障切换,确保数据库的高可用性和数据安全。 4. 性能调优与监控:介绍如何使用工具和技术调优MySQL数据库的性能,包括查询优化、缓存设置和资源管理等方面。 5. 安全与权限管理:详细讲解如何设置数据库的用户权限、访问控制和加密保护,防止非法访问和数据泄露。 6. MySQL新特性与实践:介绍新版本MySQL的特性和改,以及如何应用到实际项目中。 《MySQL 实战》不仅适合已经具有一定MySQL基础知识的读者,也可以作为MySQL数据库开发和运维人员的参考手册。通过读此书,读者将能够更深入地了解和应用MySQL数据库,在实际项目中提高开发和管理效率,提升数据库的性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值