数据库-MySQL
数据库-Mysql
Mysql数据库的关键词:事务、存储引擎、索引、SQL优化、锁、日志、主从复制、读写分离、分库分表
数据库基础
1、Mysql概述
关系型数据库:建立在关系模型基础上,由多张互连接的二维表组成的数据库
特点:使用表存储数据,便于维护;使用sql语句操作,使用方便
MySQL数据模型
1、客户端通过与数据库管理系统进行连接
2、使用sql语句通过数据库管理系统对指定的数据库进行增删改查
3、一个数据库模型中可以对多个数据库进行管理,一个数据库中可以拥有多个表
// TODO数据库模型的图
2、SQL
SQL分类
分类 | 全称 | 说明 |
---|---|---|
DDL | Data Definition Language | 数据库定义语句,定义数据库对象,数据库,表,字段等 |
DML | Data Manipulation Language | 数据库操作语句,用于对数据库表中的数据进行增增删改 |
DQL | Data Query Language | 数据库查询语句,查询数据库表中的记录 |
DCL | Data Control Language | 数据库控制语句,创建数据库用户,控制数据库的访问权限 |
1 |
|
表结构
1 |
|
MySQL中的数据类型
数据类型 | 描述 | 大小 |
---|---|---|
TINYINT | 微小整数,有符号或无符号(UNSIGNED) | 1 字节 |
SMALLINT | 小整数,有符号或无符号 | 2 字节 |
MEDIUMINT | 中等整数,有符号或无符号 | 3 字节 |
INT 或 INTEGER | 整数,有符号或无符号 | 4 字节 |
BIGINT | 大整数,有符号或无符号 | 8 字节 |
FLOAT(M,D) | 单精度浮点数,M 是总位数,D 是小数位数 | 4 字节 |
DOUBLE(M,D) | 双精度浮点数,M 是总位数,D 是小数位数 | 8 字节 |
DECIMAL(M,D) | 定点数,M 是总位数,D 是小数位数 | 取决于 M 和 D |
DATE | 日期 YYYY-MM-DD | 3 字节 |
TIME | 时间 HH:MM:SS | 3 字节 |
DATETIME | 日期和时间 | 8 字节 |
TIMESTAMP | 时间戳 | 4 字节 |
CHAR(N) | 定长字符串,最大长度为 N | 最大 255 字节 |
VARCHAR(N) | 变长字符串,最大长度为 N | 最大 65,535 字节 |
TEXT | 变长文本,最大长度为 65,535 字节 | 最大 65,535 字节 |
BLOB | 二进制大对象,最大长度为 65,535 字节 | 最大 65,535 字节 |
ENUM | 枚举类型 | 1 或 2 字节,取决于成员数量 |
SET | 集合类型 | 1、2、3、4 或 8 字节,取决于成员数量 |
创建表:
1 |
|
表结构的修改
1 |
|
添加数据
1 |
|
修改数据
1 |
|
删除数据
1 |
|
语法结构
1 |
|
基本查询
1 |
|
条件查询
条件运算符
比较运算符 | 功能 |
---|---|
<>或!= | 不等于 |
BETWEEN … AND … | 在某个范围之内 |
IN(…) | 在in之后的列表中的值,多选一 |
LIKE 占位符 | 模糊匹配(_匹配单个字符,%匹配任意个字符) |
IS NULL | 是NULL |
聚和函数
将一列数据作为一个整体,进行纵向计算。
所有的null值不参与聚合函数的计算
函数 | 功能 |
---|---|
count | 统计数量 |
max | 最大值 |
min | 最小值 |
avg | 平均值 |
sum | 求和 |
1 |
|
分组查询
在where中不可以使用聚合函数,在having中可以使用聚合函数
分组之前过滤用where,分组之后过滤条件用having
1 |
|
执行顺序:where > 聚合函数 > having
排序查询
1 |
|
排序方式: ASC升序(默认),DESC降序
分页查询
1 |
|
显示从起始索引开始的记录数条的查询结果
DQL执行顺序
FROM > WHERE > GROUP BY > SELECT > ORDER BY > LIMIT
数据控制语句,用来管理数据库用户,控制数据库访问权限
DCL用户管理
1 |
|
权限控制
常用权限
权限 | 说明 |
---|---|
ALL, ALL PRIVILEGES | 所有权限 |
SELECT | 查询数据 |
INSERT | 插入数据 |
UPDATE | 修改数据 |
DELETE | 删除数据 |
ALTER | 修改表 |
DROP | 删除数据库/表/视图 |
CREATE | 创建数据库/表 |
1 |
|
3、函数
- 字符串函数
函数 | 功能 |
---|---|
CONCAT(S1,S2, … Sn) | 字符串拼接,将S1-Sn拼接成一个字符串 |
LOWER(str) | 将字符串str全部转为小写 |
UPPER(str) | 将字符串全部转为大写 |
LPAD(str, n, pad) | 左填充,用字符串pad对str的左边进行填充,达到n个字符串长度 |
RPAD(str, n, pad) | 右填充 |
TRIM(str) | 去掉字符串头部和尾部的空格 |
SUBSTRING(str, start, len) | 返回从字符串str从start起的len长度的字符串 |
1 |
|
- 数值函数
函数 | 功能 |
---|---|
CEIL(x) | 向上取整 |
FLOOR(x) | 向下取整 |
MOD(x, y) | 返回x/y的模 |
RAND() | 返回0~1内的随机数 |
ROUND(x, y) | 求参数x的四舍五入的值,保留y位小数 |
- 日期函数
函数 | 功能 |
---|---|
CURDATE() | 返回当前日期 |
CURTIME() | 返回当前时间 |
NOW() | 返回当前日期和时间 |
YEAR(date) | 获取指定date的年份 |
MONTH(date) | 获取指定date的月份 |
DAY(date) | 获取指定date的日期 |
DATE_ADD(date, INTERVAL expr type) | 返回上一个日期加上时间间隔expr以后的时间值,type(year,month,day)指定年月天 |
DATEDIFF(date1, date2) | 返回起始时间date1和结束时间date2之间的天数,第一个时间减去第二个时间 |
- 流程函数
函数 | 功能 |
---|---|
IF(value, t. f) | 如果value为true,返回t,否则返回f |
IFNULL(value1, value2) | 如果value1不为空,返回value1,否则返回value2 |
CASE WHEN [val] THEN [res1] … ELSE [ default ] END | 如果val1为true,返回res1,…否则返回default默认值 |
CASE [expr] WHEN [val1] THEN [res1] … ELSE [default] END | 如果expr的值等于val1,返回res1,…否则返回default默认值 |
4、约束
作用于表中字段上的规则,用于限制存储在表中的数据
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | ||
唯一约束 | ||
主键约束 | ||
默认约束 | ||
检查约束 | ||
外键约束 |
5、多表查询
多表关系
一对多:在多的一方建立外键,指向一的一方的主键
多对多:建立第三张中间表,中间表至少包含两个外键,分别关联两方的主键
一对一:用于做单表拆分,基础字段放在一张表,详情字段放在另一张表。在任意一方加入外键,关联另一方的主键,并设置外键为唯一(UNIQUE)
多表查询
内连接
相当于查询A、B交集部分数据
1
2
3
4
5# 隐式内连接
SELECT 字段列表 FROM 表1,表2 WHERE 条件...;
# 显示内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件;外连接
左外连接:查询左表所有数据,以及两张表交集部分数据,将左表的数据和右表的部分数据连接起来
右外连接:查询右表所有数据,以及两张表交集部分数据
1
2
3
4
5# 左外连接,表1所有数据以及和表2交集部分的数据
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件;
# 右外连接,表2所有数据以及和表1交集部分的数据
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件;自连接
自连接:当前表与自身的连接查询,自连接必须使用表别名
联合查询-union,union all
1
2
3
4
5# 把多次查询的结果合并起来,形成一个新的查询结果集
# ALL去掉以后会对结果进行去重
SELECT 字段列表 表A
UNION [ALL]
SELECT 字段列表 表B;子查询
标量子查询,子查询返回一个标量
列子查询,子查询返回一列
| 操作符 | 描述 |
| :——: | :—————————————————: |
| IN | 在指定的集合范围之内,多选一 |
| NOT IN | 不在指定的范围之内 |
| ANY | 子查询返回列表中,有任意一个满足即可 |
| SOME | 与ANY等同 |
| ALL | 子查询返回列表的所有值都必须满足 |行子查询,子查询返回的结果是一行
此时column1可以使用(column1, column2)聚合成多个参数
操作符:=、<>、IN、NOT IN
表子查询,子查询的返回结果是一个表,可以和行子查询加上列子查询的操作符使用,表可以放到from后面
1 |
|
6、事务
一组操作的集合,是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,这些操作要么同时成功,要么同时失败
默认Mysql的事务是自动提交的,当执行一条DML语句,Mysql会立即隐式的提交事务
- 事务操作
1 |
|
1 |
|
事务四大特性
- 原子性(Atomicity):事务时不可分割的最小操作单元,要么全部成功,要么全部失败
- 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态
- 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
- 持久性(Durability):事务一旦提交或者回滚,它对数据库中的数据改变就是永久的
并发事务问题
问题 | 描述 |
---|---|
脏读 | 一个事务读到另一个事务还没有提交的数据 |
不可重复读 | 一个事务先后读取同一条记录,但两次读取的数据不同,称为不可重复读 |
幻读 | 一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这一行数据已经存在 |
事务隔离级别
读未提交、读已提交、可重复读、串行化
√表示会出现这个问题,×表示不会出现这个问题
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted | √ | √ | √ |
Read committed | × | √ | √ |
Repeatable Read | × | × | √ |
Serializable | × | × | × |
1 |
|
事务的隔离界别越高,数据越安全,但是性能越低
数据库进阶
1、存储引擎
Mysql体系结构
连接层:完成一些类似于连接处理、授权认证及相关的安全方案
服务层:主要完成大多数的核心服务功能
引擎层:负责mysql中数据的存储和提取,服务器通过API和存储引擎进行通信
存储层:将数据存储在文件系统之上,并完成与存储引擎的交互
存储引擎
存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎时基于表的,而不是基于库的。一个数据库的不同的表可以选择不同的存储引擎
Mysql默认InnoDB
1 |
|
InnoDB
- DML操作遵循ACID模型,支持事务
- 行级锁,提高并发访问性能
- 支持外键,保证事务的完整性和正确性
文件:每个表对应一个.ibd文件,代表表空间文件,可以通过命令
idb2sdi 文件名
查看表结构json文件格式MyISAM
- 不支持事务,不支持外键
- 支持表锁、不支持行锁
- 访问速度快
文件.MYD(数据),.MYI(索引),.sdi(表结构)
Memory
- 表数据存储在内存当中,收到硬件问题或断电影响只能作为临时表或者缓存使用
- 内存存放
- hash索引(默认)
存储引擎选择
InnoDB:如果对事务的完整性有比较高的要求,在并发情况下要求事务的一致性,数据操作除了插入和查询意外,还包括很多的更新、删除操作,InnoDB引擎比较合适
MyISAM:如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性和并发现要求不是很高。这个场景被Nosql数据库MongoDB替代了
MEMORY:将所有数据保存在内存当中,访问速度快,通常用于临时表以及缓存。MEMORY对表的大小有限制,太大的表无法缓存在内存中。这个场景被Redis替代了
2、索引
分类 | 含义 | 特点 | 关键字 |
---|---|---|---|
主键索引 | 针对于表中主键创建的索引 | 默认自动创建,只能有一个 | PRIMARY |
唯一索引 | 避免同一个表中某数据列中的值重复 | 可以有多个 | UNIQUE |
常规索引 | 快速定位特定数据 | 可以有多个 | |
全文索引 | 全文索引查找的是文本中通过的关键词 | 可以有多个 | FULLTEXT |
按照索引的存储形式分类
分类 | 含义 | 特点 |
---|---|---|
聚集索引 | 将数据存储与索引放到了一块 | 必须有,而且只有一个 |
二级索引 | 将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键 | 可以存在多个 |
1 |
|
1 |
|
SQL语句的频率
慢查询日志
慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10)的所有SQL语句的日志
1 |
|
profile详情
1 |
|
执行完SQL语句以后,通过以下指令查看执行耗时情况
1 |
|
explain执行计划
EXPLAIN或者DESC命令获取Mysql如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序
1 |
|
表头的含义:
1 |
|
联合索引
使用要遵循最左前缀法则:查询从索引的最左列开始,并且不跳过索引中的列。如果跳跃某一列,索引将部分失效(后面的字段索引失效)。
范围查询:联合索引中出现范围查询(>,<),范围查询右侧的列索引失效。但是使用大于等于和小于等于索引并不会失效。
例子
1 |
|
索引失效
索引列操作:不要在索引上进行列操作,否则索引会失效
字符串类型:不加单引号索引会失效
模糊查询:头部进行模糊匹配(%%某某),索引会失效,尾部进行模糊匹配(某某%%),索引不会失效。
or连接的条件:如果or前面的条件列有索引,后面的条件没有索引,所涉及的索引都不会引用到,只有两侧都有索引的时候,才有效
数据分布影响:如果索引比全表扫描更慢,则不使用索引,查询的数据大于一半,走全表不走索引。
SQL提示
在sql语句中加入一些认为的提示来达到优化操作的目的
1 |
|
覆盖索引
尽量使用覆盖索引:查询使用了索引,并且需要返回的列,在该索引中已经能够全部找到,减少使用select *
using index condition:查找使用了索引,但是需要回表查询数据
using where, using index:查询使用了索引,但是不需要回表
前两条不需要回表,后一条需要回表
前缀索引
将字符串的前缀提取出来,创建索引,可以节约索引空间
1 |
|
单列索引和联合索引选择
如果涉及到多个查询条件,推荐使用联合索引,联合索引会更少的回表查询
Quetion
建立id主键,username,password联合索引
3、SQL优化
插入数据insert优化
批量插入而不是单条插入:批量插入只需要建立一次连接即可
建议手动提交事务:不需要每一次插入时自动开启和关闭事务,而是将所有insert执行结束以后统一关闭
建议主键顺序插入
大批量插入数据:使用Mysql数据库提供的load指令进行插入
1
2
3
4
5
6
7
8
9# 如何使用load
# 1、连接服务器时加上参数--local-infile
mysql --local-infile -u root -p
# 2、设置全局参数local_infile为1
set global local_infile = 1;
# 3、执行load指令将数据加载表结构中
load data local infile '文件名' into table '表名' fields teminated by '分割符' lines terminated by '行分隔符\n';主键优化
InnoDB中表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表。
页大小为16kb,每个页至少包含两行数据
主键乱序插入可能会出现页分裂现象,执行删除操作会出现页合并现象
主键设计原则:
满足业务需求的情况下,尽量降低主键的长度
插入时尽量按照主键顺序插入,选择自增主键
尽量不要使用无序的自然主键
业务操作,避免对主键的修改
- order by优化
排序方式
Using filesort:先找到数据再进行排序
Using index:通过有序索引直接返回,不需要额外排序
默认会对索引进行升序排序
- limit优化
对于数据量大的,优化思路为使用覆盖索引+子查询
对需要更新的字段尽可能建立索引,这样如果处于多个事务情况下,只会使用行锁,如果没有建立索引,行锁会升级为表锁,无法进行并行
4、视图/存储过程/触发器
Mysql数据库当中的存储对象
视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。
操作视图中的数据就和操作数据库表一样,可以将视图理解为一张不被存储的虚拟表。
视图当中的数据并不存在,如果往视图里面插入数据,数据将存在基表当中,如果不想给用户表的权限,可以给用户一个视图。
1 |
|
视图当中的检查选项
CASCADED(向下级联)
当使用WITH CHECK OPTION子句创建视图时,Mysql会通过视图检查正在更改的每个行。进行校验,所插入的数据是否满足SELECT语句。
Mysql中还可以为视图再创建新的视图,新的视图如果有option选项会影响到之前的视图
LOCAL(不向下级联,只是检查有option的条件)
视图的更新和作用
要使视图可以更新,视图中的行与基础表中的行之间必须存在一对一的关系。如果视图包含以下中任何一项,则该视图不可更新:
聚合函数、DISTINCT、GROUP BY、HAVING、UNION或者UNION ALL
作用:1、可以简化用户对数据的理解,简化用户操作。2、控制用户对表的查看权限。3、数据独立,屏蔽真实表结构。4、可以简化多表联查的操作。
存储过程是事先经过编译并存储在数据库中的一段SQL语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输
思想上就是数据库SQL语言层面的代码封装与重用,下一次如果执行相同的业务直接调用存储过程
特点 好像跟函数有点像
封装、复用
可以接收参数,也可以返回数据
作用:减少网络交互,提升效率
在命令行中,执行创建存储过程的sql时,需要通过关键字
delimiter
指定SQL语句的结束符
1 |
|
系统变量(全局GLOBAL,会话SESSION)
重启以后系统参数会恢复为默认值
永久修改系统参数需要修改/etc/my.cnf中配置
1 |
|
用户自定义变量
作用域为当前连接
变量无需声明,如果拿到的是没有声明的变量,则会获得NULL
1 |
|
局部变量
在局部生效,需要DECLARE声明,作用域在BEGIN…END块内
1 |
|
存储过程相关语法
逻辑语言都在存储过程中定义,可以使用传入的参数
1 |
|
游标Cursor
游标(Cursor)是一种用于在存储过程或函数中遍历结果集的机制。游标允许逐行访问结果集,并在每行上执行相应的操作
通常情况下,当执行一个查询语句时,MySQL 会返回一个结果集,该结果集包含了查询返回的所有行。以使用游标来逐行处理这个结果集,而不是一次性获取所有结果。这在处理大量数据或需要逐行处理结果的情况下非常有用
1 |
|
有返回值的存储过程,存储函数的参数只能时IN类型’
1 |
|
在insert/update/delete之前或者之后,触发并执行触发器中定义的SQL语句集合。
使用别名OLD和NEW来引用触发器中发生变化的记录内容
触发器只支持行级触发,不支持语句级别触发:如果一个UPDATE语句影响了5行,则触发器会被出发5次
触发器类型 | NEW和OLD |
---|---|
INSERT型触发器 | NEW表示将要或者已经新增的数据 |
UPDATE型触发器 | OLD表示修改之前的数据,NEW表示将要或已经修改后的数据 |
DELETE型触发器 | OLD表示将要或者已经删除的数据 |
1 |
|
5、锁
锁是计算机协调多个进程或线程并发访问某一资源的机制,用于保证数据的一致性和有效性。
- 全局锁
对整个数据库进行加锁,加锁以后整个实例就处于只读状态,后续的DML的写语句,DDL语句以及更新操作的事务提交语句都会被阻塞
做数据库的全库逻辑备份的时候,会对所有的表进行锁定
1 |
|
- 表级锁
每次操作会锁住整张表,发生锁冲突的概率最高,并发度最低
表锁
表共享读锁:对于所有客户端的连接都只能读,不能写
表独占写锁:对于获取锁资源的客户端可以写,其他客户端不能进行读也不能执行写会被阻塞
语法
1、加锁:lock tables 表名… read/write
2、释放锁:unlock tables / 客户端断开连接
元数据锁(meta data lock)
MDL加锁过程是系统自动控制的,无需显示使用,在访问一张表的时候会自动加上
元数据锁就是对表结构进行加锁
当对一张表进行增删改查的时候,自动会加上MDL读锁,当对表结构进行变更时,会自动加上MDL写锁
对应SQL | 锁类型 |
---|---|
lock table xx read/write | SHARED_READ_ONLY/SHARED_NO_READ_WRITE |
select、select .. lock in share mode | SHARED_READ |
insert、update、delet、sekect…from update | SHARED_WRITE |
alter table… | EXCLUSIVVE |
意向锁
- 行级锁
应用在InnoDB存储引擎当中
InnoDB的数据时基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁
行锁
锁定单个行记录的锁,防止其他事务对此进行update和delete,在RC、RR隔离级别都支持
1、共享锁(S):允许一个事务去读取一行,阻止其他事务获得相同数据集的排它锁,其他事务能读不能写
2、排它锁(X):允许获取排它锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排它锁,其他事务不能写也不能读
SQL | 行锁类型 | 说明 |
---|---|---|
INSERT | 排它锁 | 自动加锁 |
UPDATE | 排它锁 | 自动加锁 |
DELETE | 排它锁 | 自动加锁 |
SELECT | 不加任何锁 | |
SELECT … LOCK IN SHARE MODE | 共享锁 | 手动加锁 |
SELECT … FOR UPDATE | 排它锁 | 手动 |
间隙锁
锁定索引记录间隙,确保索引记录间隙不变,防止其他事务在这个间隙执行insert,产生幻读,在RR级别下支持
临建锁(next-key)
同时锁住行记录也锁住间隙
1 |
|
6、InnoDB引擎
表空间(ibd文件):一个mysql实例可以对应多个表空间,用于存储记录、索引等数据
段:分为数据段、索引段、回滚段,InnoDB是索引组织表,数据段就是B+书的叶子节点,索引段即是B+书的非叶子节点,段用来管理多个区
区:表空间的单元结构,每个区的大小为1M,一个区中一共有64个连续的页
页:页大小16kB,是InnoDB存储引擎磁盘管理的最小单元,保证页的连续性,会申请4-5个区
内存结构
磁盘结构存储的是一些表空间和表数据文件,包括日志表空间,系统表空间,撤销表空间,重做表空间等等
buffer pool缓存池
缓冲区是内存中的一个区域,可以缓冲存储磁盘上经常要操作的数据,利用局部性原理减少磁盘IO,加快处理速度
缓冲池以page页为单位,底层采用链表数据结构管理page
change buffer更改缓存,针对非唯一二级索引页
当需要对数据进行变更,即执行DML语句时,如果buffer pool中不存在当前数据page,不会直接操作磁盘,会先将数据变更缓存在change buffer在未来数据被读取的时候,再将数据合并恢复到buffer pool中
Adaptive Hash Index自适应哈希索引
log buffer日志缓存区
后台线程
作用:将InnoDB缓冲区当中的数据在合适的时间写入到磁盘当中
1、Master Thread
核心后台线程,负责调度其他线程,将缓冲池中的数据异步刷新到磁盘当中,保持数据的一致性
2、IO Thread
采用的是AIO(异步非阻塞IO)来处理IO请求
4个读线程、4个写线程、1个日志线程、1个插入缓存线程(写缓冲区刷新到磁盘)
3、Purge Thread
回收事务已经提交的undo log,在事务提交之后,undo log可能不用了,就用它来回收
4、Page Cheaner Thread
协助Master Thread刷新脏页到磁盘的线程
事务的原子性、一致性和持久性是通过日志文件来保证的,包括redo.log和undo.log
事务的隔离性是通过锁+MVCC(多版本并发控制)来进行保证的
redo log事务的持久性(事务提交后数据的改变是永久的)
重做日志,记录事务提交时数据页的物理修改,用来实现事务的持久性(事务一旦提交,对数据的改变时持久的)
当系统在执行Mysql的DML语句时,会先从数据库缓存中查找是否有对应的页面,如果在缓存当中则对数据进行修改,这种在缓冲中修改后但还未写入磁盘的数据页,叫做脏页,后通过后台进程写入到磁盘当中,如果在写入的过程中发生异常,就会出现持久性消失的现象
redo log会把数据页的变化记录到redo log当中,当事务提交时,会把redo log刷新到磁盘当中,可以通过log对数据进行恢复,如果redo log刷新页失败,则事务执行也就失败,不影响一致性
undo log事务的原子性(事务是最小操作单位,要么全部成功,要么全部失败)
回滚日志,用于记录数据被修改前的信息,提供回滚和MVCC。当执行DML语句时,会记录数据变化前的数据长什么样,在回滚日志中,记录的时执行sql的反向操作,逆操作
undo log存放在段当中,回滚段
Mutil-Version Concurrency Control,多版本并发控制。维护一个数据的多个版本,使得读写此操作没有冲突。依赖于数据库记录中的三个隐式字段、undo log日志、readView
相关概念
当前读:读取的时记录的最新版本。因为Mysql的默认隔离界别是RR(repeatable read)可重复读,所以当另一个事务对数据进行修改时,当前事务读到的数据就不是当前最新的版本。要想读到最新版本,可以通过select .. lock in share mode,select .. for update来完成
快照读:正常的select(不加锁)就是快照读,读取的是数据的可见版本
Read Committed:每一次select 都会生成一个快照读
Repeatable Read:开始事务后第一个select才是产生快照读的地方,后面的select都是查询快照
Serializable:快照读会退化为当前读
记录当中的隐藏字段
DB_TRX_ID:最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID
DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本,用于配合undo log
DB_ROW_ID:隐藏主键,表结构没有主键,则会自动生成隐藏字段
undo log日志
如果使用insert的时候产生的日志只在回滚的时候需要,在事务提交后,可以立即删除
如果使用的是update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读的时候也需要,不会立即被删除
ReadView
读视图:快照读SQL执行时MVCC提取数据的一句,记录并维护系统当前活跃的事务id
字段,通过对比当前事务的id:trx_id和下面的id进行对比来实现版本访问控制
字段 | 含义 |
---|---|
m_ids | 当前活跃的事务ID集合 |
min_trx_id | 最小活跃事务ID |
max_trx_id | 预分配事务ID,当前最大事务ID+1 |
creator_trx_id | ReadView创建者的事务ID |
Read Commited读提交下的规则
事务中每一次执行快照读时都会生成ReadView
通过上面四条规则可以找到最新已经提交的事务版本
Repeatable Read可重复读的情况
仅在事务中第一次执行快照读的时候生成ReadView,后续会复用该ReadView
隔离性:保证事务不在外部并发操作影响下独立完成,通过MVCC+锁来保证
一致性:事务完成时,所有数据都保持一致,通过日志实现
7、MySQL管理
- 系统数据库
数据库 | 含义 |
---|---|
mysql | 存储Mysql服务器正常运行所需要的各种信息(用户、权限等) |
information_schema | 提供了访问数据库元数据的各种表和视图,包含数据库、表、字段类型以及访问权限 |
performance_schema | 为Mysql服务器运行时状态提供了一个底层监控功能,用于收集数据库服务器性能参数 |
sys | 方便开发人员进行性能调优和诊断的视图 |
- 常用工具
1 |
|
mysqladmin
执行管理操作的客户端程序
—help查看帮助文档
mysqlbinlog
如果查看一些二进制文本的数据,使用这个可以进行数据查看
mysqlshow
客户端对象查找工具,可以用于查找存在哪些数据库、数据库中的表、表中的列或者索引
—count 显示数据库及表的统计信息
-i 显示指定数据库或指定表的状态信息
mysqldump
用于备份数据库或在不同数据库之间进行数据迁移
mysqlimport/source
用于数据的导入工具
QA
1、InnoDB数据页中的数据存储
2、B+树是如何进行查询的
3、MySql单表最大限制,为什么
4、索引失效有哪些
5、count(*)和count(1)哪个性能好一些