mysql总结

1 篇文章 0 订阅
本文深入探讨了MySQL的存储引擎,重点介绍了InnoDB和MyISAM的特点,以及选择存储引擎的依据。此外,详细阐述了索引的类型、结构和优化策略,包括B+Tree、唯一索引、主键索引、覆盖索引等。还讨论了SQL性能优化,如插入数据、主键优化、ORDER BY和LIMIT的优化。最后,提到了视图、存储过程和触发器在数据库管理中的作用,以及锁的概念,包括全局锁、表级锁和行级锁。
摘要由CSDN通过智能技术生成


前言

一、存储引擎

1、体系结构图

连接层

是一些客户端和链接服务,主要完成一些类似于链接处理、授权认证、及相关的安全方案。服务器也会为接入的每个客户端验证它所具有的操作权限

服务层

主要完成大多数的核心服务功能。如SQL接口,并完成缓存的查询,SQL的分析和优化。部分内置函数的执行。所有跨存存储引擎的功能也在这一层实现,如过程、函数

引擎层

innoDB  5.6以后版本默认。负责msyql中数据的存储和提取,服务器通过API和存储引擎进行通信。不同的存储引擎具有不同的功能,这样我们可以根据自己的需要,来选取合适的存储引擎

存储层

主要是将数据存储在文件系统之上,并完成与存储引擎的交互。

2、简介

存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎是基于表的,而不是基于库的,所以存储引擎也可被称为表类型。版本5.5之后,存储引擎默认是innoDB

3、特点

innoDB 存储引擎,
	介绍
		是一种兼顾高可靠性和高性能的通用存储引擎
	特点
		1、ML操作遵循ACID模型,支持事务;
		2、级锁,提高并发访问性能;
		3、外键FOREIGN KEYA约束,保证数据的完整性和正确性;
	文件
		xxx.ibd:xxx代表的是表名,innoDB的每张表都会对应这样一个表空间文件,存储该表的表结构(frm、sdi)、数据和索引
		参数:innodb_file_per_table
		可以通过 idb2di xxx.idb 来查看文件内容
	TableSpece:表空间-》Segment:段-》	Extent:区-》Page:页-》Row:行
MyISAM
	介绍
		是mysql早期的默认存储引擎
	特点
		1、支持事务,不支持外键
		2、持表锁,不支持行锁
		3、问速度快
	文件
		xxx.MYD:存放数据
		xxx.MYI:索引
		xxx.sdi:表结构信息

3、选择

在选择存储引擎时,应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合
	innoDB:是mysql5.5默认的存储引擎,支持事务、外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据一致性,数据操作除了插入和查询之外,还包括很多的更新、删除操作,那么innoDB存储引擎是比较适合的选择。
	MYISAM:如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常合适的。
	MEMORY:将所有数据保存在内存中,访问速度快,通常用于临时表及缓存。MEMORY的缺陷就是对表的大小有限制,太大的表无法缓存在内存中,而且无法保障数据的安全性。

二、 索引

介绍
	是帮助mysql高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。
优点
	提高数据检索的效率,降低数据库的IO成本
	通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗
缺点
	索引列也是要占用空间的。
	索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行insert、update、delete时,效率降低

1.索引结构

1. B+Tree
	与b-tree区别
		所有的元素都会出现叶子节点,形成了一个双向链表
2. bTree (多路平衡查找树)
	以一颗最大度数(max-degree)为5(5阶)的b-tree为例(每个节点最多存储4个key,5个指针);
	解释:树的度数指的是一个节点的子节点个数。
3.	Hash
		哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中
		如果两个(或多个)键值,映射到一个相同的槽位上,他们就产生了hash冲突(也称为hash碰撞),可以通过链表来解决
	特点
		hash索引只能用于对等比较(=,in),不支持范围查询(between,>,<,....)
		无法利用索引完成排序操作
		查询效率高,通常只需要一次检索就可以了,效率通常要高于b+tree索引
	存储引擎支持
		在mysql中,支持hash索引的是Memory引擎,而InnoDB中具有自适应hash功能,hash索引是存储引擎根据B+tree索引在指定条件下自动构建的。
思考
	为什么innoDB存储引擎选择使用B+Tree索引结构
		1、相对于二叉树,层级更少,搜索效率高
		2、对于B-tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少要同样保存大量数据,只能增加树的高度,导致性能降低。
		3、相对hash索引,B+tree支持范围匹配及排序操作

2.索引分类

1、主键索引
	含义:针对于表中主键的索引,
	特点:默认自动创建,只能有一个 
	关键字:PRIMARY
2、唯一索引
	含义:避免同一个表中某数据列中的重复值
	特点:可以有多个
	关键字:UNIQUE
3、常规索引
	含义:快速定位特定数据
	特点:可以有多个
	关键字:无
4、全文索引
	含义:全文索引查找的是文本中的关键词,而不是比较索引中的值
	特点:可以有多个
	关键字:FULLTEXT
根据索引的存储形式,可以分为两种
	1、聚集索引
		含义:将数据存储与索引放到了一块,索引结构的叶子节点保存行数据
		特点:必须有,而且只有一个	
		选取规则:
			1、如果存在主键,主键索引就是聚集索引
			2、如果不存在主键,将使用第一个唯一索引作为聚集索引
			3、如果没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引
	2、二级索引
		含义:将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键
		特点:可以存在多个
	区别:聚集索引的叶子节点放的是行数据,二级索引的叶子节点放的是聚集索引的id
	指针占用空间6个字节。key取决于key的类型

3.索引语法

1、创建索引
		CREATE[UNIQUE|FULLTEXT] INDEX index_name ON table_name (index_col_name,....);
2、查看索引
		SHOW INDEX FROM table_name;
3、删除索引
		DROP INDEX index_name ON table_name;

4.索引-性能分析-查看执行频次

1、SQL执行频次
	show[session|global] status 命令可以提供服务状态信息。通过如下指令,可以查看当前数据库的 insert、update、delete、select的访问频次
		show global status like 'Com_______'(七个下滑现)

5.索引-慢查询日志

1、慢查询日志记录了所有执行时间超过指定参数(long_query_time,单:秒,默认十秒)的所有SQL语句的日志。
默认没有开启,配置后,通过指令重启mysql,查看慢日志文件中记录的信息 ,/var/lib/mysql/localhost-show.log

配置如下

	//	开启mysql慢日志查询开关
	show_query_log=1
	//设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志
	long_query_time=2

6.索引-性能分析

1、profile 详情
	show profiles 能够在做sql优化时帮助我们了解时间都耗费那里去了。通过have_profiling参数,能够看到当前MYSQL是否支持profile操作  
	select @@have_profiling 查看当前数据库是不是支持。
	默认profiling是关闭,可以通过set语句在session/global级别开启profiling:
	set profiling=1
	查看指定的query_id的sql语句各个阶段的耗时情况
	show profiling for query 	query_id;
	查看指定query_id的sql语句CPU的使用情况
	show profile cpu for query query_id;
2、explain 执行计划
	介绍:
		explain  或者DESC命令获取MYSQL如何执行select语句信息,包括在select语句执行过程中表如何连接和连接顺序。
	语法:
		explaini select 字段列表 form 表名 where 条件;
	执行计划各个字段含义
		id:
			select 查询的序列号,表示查询中执行select子句或者时操作表的顺序(id相同,执行顺序从上到下;id不同,值越大,越先执行)。
		select_type:
			表示select的类型,常见的取值有SIMPLE(简单表,既不使用表连接或者子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(SELECT/WHERE之后包含了子查询)等
		type:
			表示连接类型,性能由好到差的连接类型为NULL、system、const、eq_ref、ref、rang、index、all
			null 表示 不访问表
			system 表示访问系统表
			const 表示访问主键以及唯一索引
			eq_ref  表示唯一索引
			ref  	表示非唯一性的索引查询
			rang 范围索引查询
			index 用了索引,但是会扫描整个索引树
			all 表示全表查询
		possible_key:
			显示可能应用在这张表上的索引,一个或者多个
		key
			实际使用的索引,如果为null则没有使用索引
		key_len
			表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确的的前提下,长度越短越好
		rows
			msyql认为必须要执行查询的行数,在innodb引擎的表中,是一个估计值,可能并不总是准确的。
		filtered
			表示返回结果的行数占需要读取行数的百分比,filtered的值有越大越好

7.索引-使用原则

1、最左前缀法则
	如果索引了多列(联合索引),要遵循最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。
	如果跳过某一列,索引将部分失效(后面的字段索引失效)  
2、范围查询会失效
	联合索引中,出现范围查询(>,<),范围查询右侧的列索引失效
3、索引列运算
	不要在索引列进行运算操作,索引将失效
4、索引列上的字符串要加上单引号,否则会失效,原因存在了隐式转换
5、模糊查询
	如果仅仅是尾部模糊查询,索引不会失效。如果是头部模糊查询匹配,索引失效。
6、or连接的条件
	用or分割开的条件,如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到
7、查询索引的数据量大于百分之40%
8、sql 提示
	sql提示,是优化数据库的一个重要手段,简单来说,就是在sql语句中加入一些人为的提示来达到优化操作的目的。
		表名之后 use index  (索引名字)  告诉mysql 建议用这个索引
		表名之后 ignore index (索引名字)  告诉mysql 不要用这个索引
		表名之后 force index(索引名字)  告诉mysql 用这个索引
9、覆盖索引
	尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能找到),减少select *。
	using index condition:查找使用了索引,但是需要回表查询数据
	using where,using index : 查找使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询数据 
10、前缀索引
	当字段类型为字符串(varchar,text等)时,有时候需要索引很长的字符串,这会上索引变得很大,查询时浪费大量的磁盘IO,影响查询效率,此时可以只讲字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率
	语法
		create index 索引名 on table_name(column(n));
	前缀长度
		可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表的记录总数的比值,索引选择越高则查询效率越高,唯一所以的选择是1,这是最好的索引选择性,性能也是最好的。
		select count(distinct email) / count(*) from tb_usr;
		select count(distinct substring(email,1,5)) / count(*) from tb_user;
11、单列索引与联合索引
	单列索引:即一个索引只包含单个列。
	联合索引:即一个索引包含了多个列。
	在业务场景中,如果存在多个查询条件,考虑针对查询字段建立索引时,建议联合索引,而非单列索引。

三、 其他SQL优化

1.插入数据

1. 插入多条记录优化,可以批量优化,但是数据量建议在500-1000之内
2. 手动提交事务
3. 主键顺序插入

2. 主键优化

1. 数据组织方式
	在innoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表。
	满足业务需求的情况下,尽量降低主键的长度。
	插入数据时,尽量选择顺序插入,选择使用auto_increment自增主键。
	尽量不要使用uuid做主键或者是其他自然主键,如身份证。
	业务操作时,避免对主键的修改

3. order by 优化

1. using filesort:通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲冲区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫FileSort排序。
2. using index: 通过有序索引顺序扫描直接返回有序数据,这种情况即为using index,不需要额外的排序,操作效率高。
总结:
	1. 根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则。
	2. 尽量使用覆盖索引。
	3. 多字段排序,一个升序一个降序,此时需要注意联合索引在创建时的规则(asc,desc)
	4. 如果不可避免的出现filesort,大数据量排序时,可以适当增大排序缓冲区大小sort_buffer_size(默认256k)

4. group by 优化

1.在分组操作时,可以通过索引来提高效率
2. 分组操作时,索引的使用也是满足最左前缀法则的

5. limit优化

1.当数据量很大的情况下,分页查询越到后面查询时间越久。
	优化思路:一般分页查询时,通过创建 覆盖索引能够比较好的提高性能,可以通过覆盖索引加子查询形式进行优化

6. count优化

优化思路:自己计数(通过redis),

7. update 优化

1. 在更新字段时,没有根据索引进行更新,此时表开启的是表锁,反之,则是行锁。innoDB 的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则会从行锁升级为表锁

四、视图/存储过程/触发器

1. 视图

1、介绍
	 视图是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。
2、创建
	create [ or peplace] view 视图名称(列名列表) as select 语句 [ with[cascaded|local] check option]
3、查询
	查看创建视图语句: show create view 视图名称;
	查看视图数据: select  * from 视图名称;
4、修改
	方式一:create [or peplace] view 视图名称 [(列名列表)] as select 语句  [ with[cascaded|local] check option]
	方式二: alter  view 视图名称 [(列名列表)] as select 语句  [ with[cascaded|local] check option]
5、删除
	drop view [if exists] 视图名称 [,视图名称] ....
6、视图的检查选项
	当使用 with check option 子句创建视图时,mysql会通过视图检查正在更改的每个行,列如 插入 、更新、删除,已使其符合视图的定义。mysql允许基于另一个视图创建视图,他还会检查依赖视图中,它还会检查依赖视图中的规则,以保持一致性。为了确定检查的范围,mysql提供了两个选项:cascaded 和local ,默认值为 cascaded.
7、视图的更新
	要使用视图的可更新,视图中的行与基础表中的行之间必须存在一对一的关系。如果视图包含以下任何一项,则该视图不可更新:
		1、聚合函数或窗口函数(SUM()、MIN()、COUNT()等)
		2、distint
		3、group by
		4、having
		5、union 或者unIon all
8、作用
	简单:
		视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件
	安全:
		数据库可以授权,但不能授权到数据库特定行和特定的列上。通过可以视图用户只能查询和修改他们所能见到的数据	
	数据独立:
		视图可以帮助用户屏蔽真实表结构变化带来的影响。

2. 存储过程

1、介绍:
	存储过程是事先经过编译存储在数据库中的一段SQL语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。
2、特点
	封装,复用
	可以接收参数,也可以返回数据
	减少网络交互,效率提升
3、基本语法
	1、创建
		CREATE PROCEDUE 存储过程名称([in/out/inout 参数名 参数类型])
		BEGIN
			-- sql语句
		END;
	2、调用
		CALL 名称([参数]);
	3、查看 
		查询指定数据库的存储过程及状态信息
			SELECT * FROM  INFORMATION_SCHEMA.ROUTINES WHERE ROUTNE_SCHEMA = 'xxx';
		查询某个存储过程的定义
			SHOW CREATE PROCEDURE 存储过程名称;
	4、删除
		DROP PROCEDURE [IF EXISTS] 存储过程名称;
	5、变量
		1、系统变量
			1、介绍
				是mysql服务器提供,不是用户定义,属于服务器层面。分为全局变量(GLOBAL)、会话变量(session)。
			2、查看系统变量
				show [session|global] variables;  查看所有系统变量
				show  [session|global] variables like '....';  通过like 模糊匹配方式查找变量
				select @@ [session|global]  系统变量名; -- 查看指定变量的值
			3、设置系统变量
				set  [session|global]  系统变量名= 值;
				set @@ [session|global]  系统变量名= 值;
			注意: 如果没有指定session/global,默认是session,会话变量。mysql服务重启之后,所设置的全局参数会失效,要想不失效可以是配置my.cnf中配置 
		2、用户自定义变量
			1、介绍
				用户定义变量是用户根据需要自己定义的变量,用户变量不用提前声明,在用的时候直接用‘@变量名’使用就可以。其作用域为当前连接。
			2、赋值
				set @var_name = expr[,@var_name=expr]...;
				set @var_name := expr[,@var_name=expr]...;
				select @var_name := expr[,@var_name=expr]...;
				select 字段名 into  @var_name form 表名;
			3、使用
				select @var_name;
			注意:
				用户定义的变量无需对其进行声明或初始化,只不过获取到的值为null
		3、局部变量
			1、介绍
				根据需要定义的在局部生效的变量,访问之前,需要declare 声明。可用做存储过程内的局部变量和输入参数,局部变量的范围是在其内声明的begin...end块;
			2、声明
				declare 变量名 变量类型 [default ...];
				变量类型就是数据库的字段类型;
			3、赋值
				set 变量名=值
				set 变量名:= 值;
				select 字段名 into 变量名 from 表名...;
	6、if 
		1、语法
			if 条件1 then
				.....
			elseif 条件2 then   ---- 可选
				....
			else   ---可选
				....
			end if;
	7、参数
		1、in  类型
			含义:该类参数作为输入,也就是需要调用时传入值
			备注:默认
		2、out 类型
			含义:	该类参数作为输出,也就是该参数可以作为返回值
		3、inout 类型
			含义:既可以作为输入参数,可以作为输出参数
	8、case
		1、语法
			语法一:
				case case_value
					when when1 then statement_list1
					[when when2 then statement_list2] ....
					[else statement_list]
				end case;
			语法二:
				case 
					when search_condition1 then statement_list1
					[when search_condition2 then statement_list2] ....
					[else statement_list]
				end case;
		9、while
			循环是有条件的循环控制语句。满足条件之后,在执行循环体中的SQL语句。具体语法为:
				语法:
				先判断条件,如果条件为true,则执行逻辑,否则,不执行逻辑
					while 条件 do
						SQL逻辑
					end while;
		10、repeat
			是有条件的循环控制语句,当满足条件的时候退出循环。
			先执行一次逻辑,然后判断逻辑是否满足,如果满足,则退出。如果不满足,则继续下一次循环
			语法:
				repeat
					SQL逻辑
					unitl 条件
				end repeat;
		11、loop
			实现简单的循环,如果不在SQL逻辑中增加退出循环的条件,可以用其来实现简单的死循环。Loop可以配合一下两个语句使用:
				leave: 配合循环使用,退出循环
				iterate: 必须用在循环中,作用是跳过当前循环剩下的语句,直接进入下一次循环。
			语法:
				【begin_label:Loop
					SQL逻辑...
				END LOOP [end_label];
				leave label; --退出指定标记的循环体
				iterate label ; -- 直接进入下一次循环
		12、游标
			是用来存储查询结果集的数据类型,在存储过程和函数中可以使用游标对结果集进行循环的处理。游标的使用包括游标的声明、OPEN、FETCH和CLOSE,其语法分别为:
				1、声明游标
					declare 游标名称 cursor for 查询语句;
				2、打开游标
					open 游标名称;
				3、获取游标记录
					FETCH 游标名称 into 变量[,变量];
				4、关闭游标
					CLose 游标名称;
				5、条件处理程序
					可以用来定义在流程控制结构执行过程中遇到问题时相应的处理步骤。
					具体语法:
						declare handler_action handler for condition_value [condition_value ].... statement;
						handler_action 
							continue:继续执行当前程序
							exit: 终止行当前程序
						condition_value 
							SQLSTATE sqlstate_value:状态码,如02000
							SQLWARNING: 所有以01开头的SQLSTATE 代码简写
							NOT FOUND :所有以02开头的SQLSTATE 代码简写
							SQLEXCEPTION: 所有没有被SQLWARNING或NOT FOUND 捕捉的SQLSTATE 代码的简写

3. 存储函数

1、介绍:
	存储函数是有返回值的存储过程,存储函数的参数只能是IN类型的,
2、语法:
	create function 存储函数名称([参数列表])
	returns type [characteristic...]
	begin
		--SQL语句
		return...;
	end;
	characteristic说明:
		deterministic:相同的输入参数总是产生相同的结果
		NO SQL:不包含SQL语句。
		reads SQL date:包含读取数据的语句,但不包含写入数据的语句。

4. 触发器

1、介绍:
	触发器是与表有关的数据库对象,指在insert/update/delete 之前或之后,触发并执行触发器中定义的SQL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性,日志记录,数据校验等操作。
	使用别名old 和new 来引用触发器中发生变化的记录内容,这与其他的数据库是相似的,现在触发器还支持行级触发,不支持语句级触发。
	1、insert触发器 new 表示将要或者已经新增的数据
	2、update触发器 old 表示修改之前的数据,new 表示将要或已经修改后的数据
	3、delete 触发器 old表示将要或者已经删除的数据
2、语法
	1、创建
		create trigger trgger_name
		before/after insert/update/delete
		on table_name for each row --- 行级触发器
		begin
			tigger_stmt;
		end;
	2、查看
		show triggers;
	3、删除
		drop trigger [schema_anme.]trigger_name; -- 如果没有指定schema_anme,默认为当前数据库。

五、锁

1.概述

1、分类
	1、全局锁: 锁定数据中的所有表
	2、表级锁:每次操作锁住整张表
	3、行级锁:每次操作锁住对应的行数据

2.全局锁

1、介绍
	全局锁就是对整个数据库实例加锁,加锁后真个实例都处于只读状态,后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将被阻塞。案列:数据库的备份
2、加锁: flush tables with read lock
3、解锁:unlock tables 

3.表级锁

1、介绍
	每次操作锁住整张表。锁定粒度大,发生锁冲突的概率高,并发度最低。
2、分类
	1、表锁
		1、分类
			1、表锁(read lock)
			2、表独占锁(write look)
		2、语法
			1、加锁:lock tables 表名 ... read/wirte
			2、释放锁:unlock tables / 客户端断开连接。
		3、注意:
			读锁不会阻塞其他客户端的读,但是会阻塞写。写锁既会阻塞其他客户端的读,又会阻塞其他客户端的写。
	2、元数据锁(meta data lock,DML)
		1、介绍:
			DML 加锁过程是系统自动控制,无需显示使用,在访问一张表的时候会自动加上。DML锁主要作用是维护表元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入的操作。为了避免DML与DDL冲突,保证读写的正确性。
	3、意向锁
		1、介绍:
			为了避免DML在执行时,加的行锁与表锁的冲突,在innoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查。
		2、分类
			1、意向共享锁(IS): 与表锁共享锁(read)兼容,与表锁排他锁(wirte)互斥
			2、意向排他锁(IX):与表锁共享锁(read)及排它锁(wirte)都互斥。意向锁之间不会互斥。

4. 行级锁

1、介绍:
	行级锁,每次操作锁住对应的行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在innoDB存储引擎中
	innoDB 的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。对于行级锁
2、分类
	1、行锁
		锁定单个行记录的锁,防止其他事务对此进行update和delete.在RC、RR隔离级别下都支持。
	2、间隙锁
		锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读。在RR隔离级别都支持
	3、临键锁
		行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。在RR隔离级别下支持。
3、行级锁的行锁
	1、特点
		共享锁(s):允许一个事务去读一行,阻止其他事务获取得相同数据集的排它锁。
		排他锁(X): 允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。
	2、默认情况下,innoDB 在REpEatable read 事务隔离级别运行,innoDB使用next-key 锁进行搜索和索引扫描,以防止幻读。
		1、针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将会自动优化为行锁
		2、innoDB的行锁是针对与索引加的锁,不通过索引条件检索数据,那么innoDB将对表中的所有记录加锁,此时就会升级为表锁
4、行级锁的间隙锁、临键锁
	1、特点
		默认情况下,innoDB 在REpEatable read 事务隔离级别运行,innoDB使用next-key 锁进行搜索和索引扫描,以防止幻读。
		1、索引上的等值查询(唯一索引),给不存在的记录加锁时,优化间隙锁。
		2、索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock 退化为间隙锁。
		3、索引上的范围查询(唯一索引),--会访问到不满足条件的第一个值为止。
	注意:
		间隙锁唯一目的是防止其他事务插入间隙,间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁

六、InnoDB引擎

1. 逻辑存储结构

1、表空间
	一个mysql实例可以对应多个表空间,用于存储记录、索引等数据。
2、段
	分为数据段、索引段、回滚段,innoDB是索引组织表,数据段就是b+树的叶子节点,索引段即为b+树的非叶子节点。段用来管理多个EXtent(区)
3、区
	表空间的单元结构,每个区的大小为1M。默认情况下,innoDB存储引擎页大小为16k,即一个区中一共有64个连续的页
4、页
	是innoDB存储引擎磁盘管理的最小单元,每个页的大小默认为16kb,为了保证页的连续性,innoDB存储引擎每次磁盘申请4-5个区
5、行
	innoDB存储引擎数据是按行进行存放的

2. 架构

1、内存结构
	1、buffer pool:缓冲池是主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载并缓存),然后再以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度
		缓冲以page页为单位,底层采用链表数据结构管理page。根据状态,将page分为三种类型
			1、free page:空闲page,未被使用
			2、clean page: 被使用page,数据没有被修改过。
			3、dirty page :脏页,被使用page ,数据被修改过,页中数据与磁盘的数据产生了不一致。
	2、change buffer :更改缓冲区(针对于非唯一二级索引页),在执行DML语句时,如果这些数据page没有在buffer pool 中,不会直接操作磁盘,而会将数据变更存在更改缓冲区change buffer 中,在未来数据被读取时,再将数据合并恢复到buffer pool中,再将合并后的数据刷新到磁盘中
	意义:
		与聚集索引不同,二级索引通常是非唯一的,并且一向对随机的顺序插入二级索引。同样,删除和更新可能会影响索引树中不相邻的二级索引页,如果每一次都操作磁盘,会造成大量的磁盘IO.有了change buffer 之后,我们可以在缓冲池中进行合并处理,减少磁盘IO.
	3、adaptive hash index:自适应hash索引,用于优化对buffer pool 数据的查询。innoDB 存储引擎会监控对表上个索引页的查询。如果观察到hash索引可以提升速度,则建立hash索引,称之为自适应hash索引。
		自适应hash索引,无需人工干预,是系统根据情况自动完成。
		参数:adaptive_hash_index 
	4、log buffer:日志缓冲区,用来保存要写入到磁盘中的log日志数据(redo log 、undo log),默认大小为16mB,日志缓冲区的日志会定期刷新到磁盘中,如果需要更新、插入或删除多行的事务,增阿吉日志缓冲区的大小可以节省磁盘I/O
	参数:
		innoDB_log_buffer_size: 缓冲区大小
		innoDB_flush_log_at_trx_commit:日志刷新到磁盘时机。
2、磁盘架构
	1、System Tablespace:系统表空间是更改缓冲区。如果表是在系统表空间,而不是每个表文件或通用表空间中创建的,它也可能包含表和索引数据。(在mysql5.x版本中还包含innoDB数据字典、undolog等)
	参数:innodb_data_file_path
	2、General Tablespaces:通用通过create tablespance 语法创建通用表空间,在创建表时,可以指定该表空间。
	3、Undo Tablespance : 撤销表空间,mysql 实例在初始化时会自动创建两个默认的undo表空间(初始化大小16M),用于存储undo log 日志。
	4、Temporary Tablespaces: innoDB 使用会话临时表空间和全局临时表空间。存储用户创建的临时表等数据
	5、Doublewrite Buffer Files:双写缓冲区,innoDB 引擎将数据页从buffer pool 刷新到磁盘前,先将数据页双写入缓冲区文件中,便于系统异常时恢复数据。
	文件名:ib_xxx.dblwr
	6、redo log :重做日志,用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。当时事务提交之后会把所有修改信息都会存到该日志中,用于再刷新脏页到磁盘时,发生错误时,进行数据恢复使用。
3、后台线程
图片

3. 事务原理

1、概述
	事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起想系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
2、特性
	原子性:事务是不可分割的最小操作单元,要么全部成功,要么全部失败
	一致性:事务完成时,必须使所有的数据都保持一致状态
	隔离性:数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
	持久性:事务一旦提交或回滚,他对数据库中的数据的改变就是永久的
3、undo log 
	回滚日志,用于记录数据被修改前的信息,作用包含两个:提供回滚和mvvc(多版本并发控制)。
	undo log 和redo log 记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log 中会记录一条对应的insert 记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录,当执行rollback时,就可以从undo log 中的逻辑记录读取到相应的内容并进行回滚。
	undo log 销毁:undo log 在事务执行时产生,事务提交时,并不会立即删除undo log ,因为这些日志可能还用于mvcc
	undo log 存储: undo log 采用段的方式进行管理和记录,存放在前面介绍的rollback segment回滚段中,内部包含1024个 undo log segment。

4. MVCC

1、概念
	1、当前读
		读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁,对于我们日常的操作,如:select ... lock in share mode(共享锁),select ... for update、update、delete(排他锁)都是一种当前读。
	2、快照读
		简单的select(不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。
		read committed: 每次select,都生成一个快照读。
		repeatable read :开启事务后第一个select 语句才是快照读的地方
		serializable :快照读会退化为当前读
	3、mvcc
		多版本并发控制,指维护一个数据的多个版本,是的读写操作没有冲突,快照读为mysql实现mvcc提供了一个非阻塞读功能。mvcc的具体实现,还需要依赖于数据库记录中的三根隐式字段、undo log日志、readView.
2、实现原理
	1、隐藏字段
		1、DB_TRX_ID
			含义:最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID.
		2、DB_ROLL_PTR
			含义:回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版本。
		3、DB_ROW_ID 
			含义:隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段
	2、undo log日志Y

七、MySQL管理

八、运维管理

1. 错误日志

1、含义:错误日志是mysql中最重要的日志之一,它记录了当mysqlId启动和停止时,以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时。
2、地址:该日志是默认开启的,默认存放目录/var/log/,默认的日志文件名为mysql.log。查看日志位置:
show variables like '%log_error%'

2. 二进制日志

1、含义:
	二进制日志(binLog)记录所有的DDL(数据定义语言)语句和DML(数操作语言)语句,但不包括数据查询(select、show)语。
2、作用:灾难时的数据恢复;mysql的主从复制。在mysql 8版本中,默认二进制日志是开启着,涉及到的参数如下:
	show variables like '%log_bin%'
3、日志格式
	systement: 基于sql 语句的日志记录,记录的是sql 语句 ,对数据进行修改的sql都会记录在日志文件中。
	row :  基于行的日志记录,记录的是每一行的数据变更(默认)
	mixed : 混合了systement 和row 两种格式,默认采用systement, 在某些特殊情况下会自动切换为row进行记录
4、sql:  show variables like '%binlog_format%';
5:、 日志查看
	由于日志是以二进制方式存储的,不能直接读取,需要通过二进制日志查询工具msyqlbinlog 来查看,具体语法:
	 mysqlbinlog [参数选项] logfilename 
	 参数选项
	 	-d   指定数据库名称,只列出指定的数据库相关操作
	 	-o 忽略掉日志中的前n 行命令
	 	-v 将行事件(数据变更)重构为SQL语句
	 	-w 将行事件(数据变更)重构为sql语句,并输出注释信息
	修改 my.conf 文件 
	 binlog_format =systement
6、二进制日志删除
	reset master   删除全部binlog日志,删除之后,日志编号,将从binlog.000001重新开始
	purge master logs to ‘binlog.*******’   删除****编号之前的所有日志
	purge master logs before 'yyyy-mm-dd hh24:mi:ss' 删除日志为'yyyy-mm-dd hh24:mi:ss'之前产生的所有日志
	show variables like '%binlog_expire_logs_seconds%'

3. 查询语句

1、查询日志中记录客户端的所有操作语句,而二进制日志不包括查询数据的sql语句。默认情况下,查询日志是未开启的,如果需要开启查询日志,如下
show variables like '%general%'

4.慢查询

1、慢查询日志记录了所有执行时间超过参数log_query_time 设置值并且扫面记录数不小于min_examined_row_limit的所有的sql语句的日志,默认未开启。long_query_time 默认为10秒,最小为0,精度可以到微秒。
#慢查询日志
slow_query_log=1
long_time_time=2

5.主从复制

1、概述
	介绍:主从复制是指将主数据库的DDL和DML操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也叫重做),从而使得从库和主库的数据保持同步。
	优点:
		1、主库出现问题,可以快速切换到从库提供服务。
		2、实现读写分离,降低主库的访问压力
		3、可以在从库中执行备份,以避免备份期间影响主库服务
2、原理
	master服务器将data的改变写入到binlog 二进制日志,slave的IOthread发起请求连接master主库之后读取二进制日志,然后写入到自身的relay log日志中,接着启动SQLthread去读取replay log 日志 去反映到自身数据库
	三步:
		1、 master 主库在事务提交时,会把数据变更记录在二进制日志文件binglog中。
		2、从库读取主库的二进制日志文件binlog,写入到从库的中继日志replay log.
		3、slave 重做中继日志中的事件,将改变反映它自己的数据
3、搭建
	1、安装两台mysql服务器 并关闭防火墙
	2、主库配置
		 1、修改配置文件 /etc/my.conf
		 	server-id=1  #mysql服务id  保证整个集群环境中唯一,取值范围1-2 的32次方-默认为1
		 	read-only=0  # 是否只读 1代表只读,0代表读写
		 2、重启数据库
		 3、登录mysql 创建远程链接的账号,并赋予主从复制的权限
			#创建itcast用户,并设置密码,该用户可在任意主机连接该mysql服务
			create user 'itcast'@'%' IDENTIFIED WITH mysql_native_password BY 'Root@123456';
			#为 'itcast'@'%'  用户分配主从复制权限
			GRANT REPLICATION SLAVE ON *.* TO  'itcast'@'%' ;
	3、从库配置
		 1、修改配置文件 /etc/my.conf
		 	server-id=2  #mysql服务id  保证整个集群环境中唯一,取值范围1-2 的32次方-默认为1
		 	read-only=1  # 是否只读 1代表只读,0代表读写
		 2、重启数据库
		 3、登录mysql 创建远程链接的账号,设置主库配置
		 	8.0.23的语法
		 	CHANGE REPLICATION SOURCE TO SOURCE_HOST='xxxx	', SOURCE_USER='xxxx',SOURCE_USER='xxxx',SOURCE_LOG_FILE='xxxxx',SOURCE_LOG_POS=xxx;
		 	8.0.23之前的语法
		 	CHANGE MASTER  TO MASTER_HOST='xxxx	', MASTER_USER='xxxx',MASTER_LOG_FILE='xxxxx',MASTER_LOG_POS=xxx;

6.分库分表

1、介绍
2、mycat 概述
3、mycat入门
4、mycat配置
5、mycat 分片
6、mycat 管理及监控

7. 读写分离

该处使用的url网络请求的数据。


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值