MySQL

文章目录

基础篇

1. mysql基础知识

1.1 分类

  • DDL(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等;
  • DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据)(增删改操作);
  • DQL(Data Query Language):数据查询语言,用来查询记录(数据)。
  • DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别;

2 mysql内置函数

2.1 字符串函数

函数功能说明
concat(s1 , s2 , … Sn)字符串拼接,将s1 s2 … Sn拼接成一个字符串
lower(str)将字符串str全部转为小写
upper()将字符串str全部转为大写
lpad(str,n,pad)左填充,用字符串pad对str左侧进行填充,达到n个字符长度
rpad(str,n,pad)右填充,用字符串pad对str右侧进行填充,达到n个字符串长度
trim(str)去掉字符串头部和尾部的空格
substring(str,start,len)返回从字符串从start位置起的len个长度的字符串起始下标从1开始

2.2 数值函数

函数功能
ceil(x)向上取整
floor(x)向下取整
mod(x,y)返回 x/y 的模(余数)
rand()返回 0~1 内的随机数
round(x,y)求参数x 的四舍五入的值,保留y位小数

2.3 日期函数

函数功能
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时间的天数

2.4 流程函数

函数功能
if(value , t , f)如果value为true , 则返回 t , 否则返回 f
ifnull(value1 , value2)如果value1不为空 , 返回value1 , 否则返回value2
case when [val1] then [res1] else [default] end如果val1 为true , 返回res1 , 否则返回default默认值
case [expr] when [val1] then [res1] else [default] end如果expr的值等于val1 , 返回res1 , 否则返回default默认值
例:
select name ,
( case address
when ‘北京’ then ‘一线城市’
when ‘上海’ then ‘一线城市’
else ‘二线城市’ end ) as ‘工作地址’
from user

3 mysql约束

概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据
目的: 保证数据库数据的正确性 有效性和完整性

约束描述关键字
非空约束限制该字段的数据不能为nulnot null
唯一约束保证该字段的所有数据都是唯一 不重复的unique
主键约束主键是一行数据的唯一标识,要求非空且唯一primary key
默认约束保存数据时,如果未指定该字段的值,则采用默认值default
检查约束(8.0.16版本之后)保证字段值满足某一个条件check
外键约束用来让两张表的数据之间建立连接,保证数据的一致性和完整性forign key

3.1 外键约束 删除/更新行为

行为说明
NO ACTION当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新.(与RESTRICT一致)
RESTRICT当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新,(与NO ACTION一致)
CASCADE当在父表中删除/更新记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录
SET NULL当在父表中删对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(这就要求该外键允许取null)
SET DEFAULT父表有变更时,子表将外键列设置成一个默认的值(innodb不支持)

4 explain执行计划

explain执行计划各字段含义

  1. id: select查询的序列号,表示查询中执行select子句或者是操作表的顺序(id相同,执行顺序从上到下;id不同,值越大,越先执行)

  2. select_type:表示select的类型,常见的取值有simple(简单表,即不使用表连接或者子查询)、primary(主查询,即外层的查询)、union(union中的第二个或者后面的查询语句)、subquery ( select/where之后包含了子查询)等

  3. type: 表示连接类型,性能由好到差的连接类型为 null、system、const、eq_ref、ref、range、index、all。

    type连接类型说明
    nullMySQL 不用访问表或者索引就直接能到结果,例如: select now() , select ‘A’
    system表只有一行
    const表最多只有一行匹配,通常用于主键或者唯一索引比较时
    ref使用非唯一性索引或者唯一索引的前缀扫描, 返回匹配某个单独值的记录行
    eq_ref类似ref, 区别就在使用的索引是唯一索引。在联表查询中使用 primary key 或者 unique key 作为关联条件。
    range常数值的范围
    all全表扫描(Full Table Scan), MySQL将遍历全表以找到匹配的行。
    index全索引扫描(Full Index Scan), index 与 ALL 区别为 index 类型只遍历索引树。MYSQL 遍历整个索引来查找匹配的行。
  4. possible_key:可能使用的索引,一个或多个

  5. key:实际使用的索引

  6. key_len:表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好

  7. rows:mysql认为必须要执行查询的行数,在innodb引擎的表中,是一个估计值,可能并不总是准确的

  8. filtered:表示返回结果的行数占需读取行数的百分比,filtered的值越大越好.

  9. extra:扩展信息

内容说明
using index condition查找使用了索引,但是需要回表查询数据
using where , using index查找使用了索引,到那时需要的数据都在索引列中能找到,所以不需要回表查询数据

5 mysql存储引擎

  1. 存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎是基于表的,而不是基于库的,所以存储引擎也可被称为表类型
  2. InnoDB是一种兼顾高可靠和高性能的通用存储引擎,在mysql5.5之后,InnoDB是默认的mysql存储引擎
    • 特点: DML操作遵循ACID模型,支持事务 ; 行级锁 , 提高并发访问性能 ; 支持外键FOREIGN KEY约束,保证数据的完整性和正确性
    • 文件 : xxx.idb xxx代表的是表名 , innodb引擎的每张表都会对应这样一个表空间文件,存储该表的表结构(frm、sdi)、数据和索引
    • 存储引擎特点:
      在这里插入图片描述
  3. 为什么InnoDB存储引擎选择使用B+tree索引结构?
    1. 相对于二叉树,层级更少,搜索效率高
    2. 对于B-tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的高度,导致性能降低
    3. 相对于Hash索引,B+tree支持范围匹配及排序操作

进阶篇

6 索引

MySQL数据库索引存储结构一般有以下几种。
二叉树红黑树HASHB-TreeB+Tree(现在常用)

为什么InnoDB存储引擎选择使用B+tree索引结构?

  1. 相对于二叉树,层级更少,搜索效率高
  2. 对于B-tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的高度,导致性能降低
  3. 相对于Hash索引,B+tree支持范围匹配及排序操作

6.1 索引分类

索引我们分为四类来讲单列索引(普通索引,唯一索引,主键索引)、组合索引、全文索引、空间索引、

1.1、单列索引:一个索引只包含单个列,但一个表中可以有多个单列索引。 这里不要搞混淆了。

普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。

唯一索引:索引列中的值必须是唯一的,但是允许为空值,

主键索引:是一种特殊的唯一索引,不允许有空值。(主键约束,就是一个主键索引)

1.2、组合索引:在表中的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用,使用组合索引时遵循最左前缀集合。例如,这里由id、name和age3个字段构成的索引,索引行中就按id/name/age的顺序存放,索引可以索引下面字段组合(id,name,age)、(id,name)或者(id)。如果要查询的字段不构成索引最左面的前缀,那么就不会是用索引,比如,age或者(name,age)组合就不会使用索引查询

1.3、全文索引:全文索引,只有在MyISAM引擎上才能使用,只能在CHAR,VARCHAR,TEXT类型字段上使用全文索引,介绍了要求,说说什么是全文索引,就是在一堆文字中,通过其中的某个关键字等,就能找到该字段所属的记录行。这里说的是可能,因为全文索引的使用涉及了很多细节,我们只需要知道这个大概意思。

1.4、空间索引:空间索引是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有四种,GEOMETRY、POINT、LINESTRING、POLYGON。在创建空间索引时,使用SPATIAL关键字。要求,引擎为MyISAM,创建空间索引的列,必须将其声明为NOT NULL。可能跟游戏开发有关。

根据索引的存储形式,又可以分为以下两种:

分类含义特点
聚集索引
(聚簇索引)
将数据存储与索引放到了一块,索引结构的叶子节点保存了行数据必须有,而且只有一个
二级索引
非聚簇索引
将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键可以存在多个

簇索引选取规则:

  1. 如果存在主键,主键索引就是聚簇索引聚
  2. 如果不存在主键,将使用第一个唯一索引作为聚簇索引
  3. 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚簇索引.

6.2 索引使用

  1. 最左前缀法则:如果索引了多列(复合索引),要遵循最左前缀法则,最左前缀法则指得是查询从索引的最左列开始,并且不跳过索引中的列,如果跳跃某一列,索引将部分失效(后面的字段索引失效)

  2. 范围查询:联合索引中,出现范围查询(> < ) , 范围查询右侧的列索引失效,如果业务允许尽量使用 >= <= ,会避免索引失效.

  3. 索引运算: 不要在索引列上进行运算操作(mysql的函数等),索引将失效.

  4. 字符串不加引号:字符串类型字段使用时,不加引号,索引将失效

  5. 模糊查询:如果仅仅是尾部模(“123%”)匹配,索引不会失效。如果是头部模糊匹配,索引失效(全表扫描)。头尾同时模糊,索引失效(全表扫描)

  6. or连接的条件: 用or分割开的条件,如果or的一侧列中有索引,另一侧列中没有索引,那么涉及的索引都不会被用到. 只有or前后的列都有索引,那么涉及的索引不会失效

  7. 数据分布影响:如果mysql评估使用索引比全表更慢(超过一半的数据符合查询条件时),则不会使用索引.

  8. sql提示:sql提示,是优化数据库的一个重要手段,是在sql语句中加入一些人为的提示来达到优化操作的目的.

    语法说明示例
    use index建议使用指定索引select * from 表名 use index(index名称)
    ignore index不使用指定索引select * from表名 ignore index(index名称)
    force index强制使用指定索引select * from 表名 fore index(index名称)
  9. 覆盖索引:尽量使用覆盖索引(查询使用了索引,并且需要返回的列在该索引中已经全部能够找到),减少select * 。

  10. 前缀索引:当字段类型为字符串(varchar , text等)时,有时候需要索引很长的字符串,这会 让索引变得很大,查询时,浪费大量的磁盘IO,影响查询效率。此时可以只将字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率

    1. 语法: create index 索引名 on 表名(列名(长度n))
    2. 长度前缀:可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表的记录总和的比值,索引选择性越高则查询效率越高。唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的
    # 选择性计算方式
    # 如下 计算表中email字段的前五个长度的选择性
    select count(distinct substring(email , 1 , 5)) / count(*) from 表名
    
  11. 单列索引和联合索引:

    1. 单列索引:即一个索引只包含单个列.
    2. 联合索引:即一个索引包含了多个列.
    3. 在业务场景中,如果存在多个查询条件,考虑针对于查询字段建立索引时,建 议建立联合索引,而非单列索引.
    4. 多条件联合查询时,mysql优化器会评估哪个字段的索引效率更高,会选择该索引完成本次查询.

6.3 索引设计原则

  1. 针对于数据量较大,且查询比较频繁的表建立索引。
  2. 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。
  3. 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。
  4. 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。
  5. 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率。
  6. 要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率。
  7. 如果索引列不能存储NULL值,请在创建表时使用NOTNULL约束它。当优化器知道每列是否包含NULL值时,它可以更好地确定哪个索引最有效地用于查询。

7. sql优化

7.1 插入数据

7.1.1 insert优化:

批量插入:如果插入的数据较多,可以采用批量插入,单次500-1000行最佳
手动提交事务
主键顺序插入

7.1.2 大批量插入数据

如果一次性需要插入大批量数据,使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入。

# 客户端连接服务端时,加上参数 --local-infile
mysql --local-infile -uroot -p
#设置全局参数local-infile为1,开启从本地加载文件导入数据的开关
set global local-infile = 1;
#执行load指令将准备好的数据加载到表结构中
#  数据分隔符为逗号(,)  , 换行符为回车(\n)
load data local infile '文件路径' into table 表名 fields teminated by ',' lines teminated by '\n';

7.2 主键优化

  • 数据组织方式 : 在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table IOT)。

  • 页分裂 : 页可以为空,也可以填充一半,也可以填充100%。每个页包含了2~N行数据(如果一行数据多大,会行溢出),根据主键排列。
    如图所示:当主键乱序插入时,此时插入id=50的数据,第一页23和47所占空间超过50%,此时会开辟第三页,把23和47移动到第三页同时把50追加到第三页,然后页码指针会重排布
    在这里插入图片描述
    页分裂后如下图所示:
    在这里插入图片描述

  • 页合并: 当删除一行记录时,实际上记录并没有被物理删除,只是记录被标记(flaged)为删除并且它的空间变得允许被其他记录声明使用。
    当页中删除的记录达到MNERGE_THRESHOLD(默认为页的50%),InnoDB会开始寻找最靠近的页(前或后)看看是否可以将两个页合并以优化空间使用。
    如图所示:此时会把第三个数据合并到第二页
    在这里插入图片描述
    页合并后如图所示:
    在这里插入图片描述
    MERGE_THRESHOLD:合并页的阈值,可以自己设置,在创建表或者创建索引时指定。

  • 主键设计原则

    1. 满足业务需求的情况下,尽量降低主键的长度。
    2. 插入数据时,尽量选择顺序插入,选择使用AUTO_INCREMENT自增主键。
    3. 尽量不要使用UUID做主键或者是其他自然主键,如身份证号。
    4. 业务操作时,避免对主键的修改。

7.3 order by 优化

7.3.1 排序方式

  1. Using filesort : 通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫FileSort 排序。
  2. Using index : 通过有序索引顺序扫描直接返回有序数据,这种情况即为using index,不需要额外排序,操作效率高。

7.3.2 优化方案:

  1. 根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则.
  2. 尽量使用覆盖索引
  3. 多字段排序,一个升序一个降序,此时需要注意联合索引在创建时的规则(ASC/DESC)
  4. 如果不可避免的出现filesort,大量数据排序时,可以适当增加排序缓冲区大小 sort_buffer_size(默认256k)

7.4 group by 优化

  1. 在分组操作时,可以通过索引来提高效率
  2. 分组操作时,索引的使用也是满足最左前缀法则的.
  3. 分组字段和where条件字段使用的索引组合起来如果满足最左前缀法则,索引会生效

7.5 limit优化

一个常见又非常头疼的问题就是limit 2000000,10,此时需要MySQL排序前2000010记录,仅仅返回2000000 - 2000010的记录,其他记录丢弃,查询排序的代价非常大。

优化思路 : 一般分页查询时,通过创建覆盖索引能够比较好地提高性能,可以通过覆盖索引加子查询形式进行优化。

explain select * from tb_sku t , (select id from tb_sku order by id limit 2000000,10) a where tid = a.id;

7.5.1

假如只查前一千条数据
数据库只会返回前一千条
如果深翻页,就是看最后一页的数据的话,数据库会扫描所有的全部数据然后回表查询select字段,然后过滤掉前边的数据只要最后一页,这样是查询了无用的数据
优化 先做一个子查询,把要查询的分页数据区间的主键id使用覆盖索引查询回来,然后这个结果集跟原表做一个连接查询,这样的话 ,只会在原表中扫描指定分页区间的数据,减少回表查询
耗时总结 原表有百万数据,优化之前十几秒甚至更久 优化后 几百毫秒

7.6 count优化

MyISAM引擎把一个表的总行数存在了磁盘上,因此执行count(*)的时候会直接返回这个数,效率很高;

InnoDB引擎就麻烦了,它执行count(*)的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。

优化思路:自己计数(利用reids内存数据库,)。count本身很耗时,难以优化

7.6.1 count的几种用法:

  1. count()是一个聚合函数,对于返回的结果集,一行行地判断,如果count函数的参数不是NULL,累计值就加1,否则不加,最后返回累计值。
  2. 用法: count (* ) .count(主键)、count(字段)、count ( 1)
用法说明
count(主键)InnoDB引擎会遍历整张表,把每一行的主键id值都取出来,返回给服务层。
服务层拿到主键后,直接按行进行累加(主键不可能为null)。
count(字段)没有not null约束: InnoDB引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,服务层判断是否为null,不为null,计数累加。
有not null约束: InnoDB引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,直接按行进行累加。
count(1)InnoDB引擎遍历整张表,但不取值。服务层对于返回的每一行,放一个数字“1”进去,直接按行进行累加。
count(*)InnoDB引擎并不会把全部字段取出来,而是专门做了优化,不取值,服务层直接按行进行累加。

按照效率排序的话,count(字段) < count(主键id) < count(1) ≈ count(*),所以尽量使用count(*)。

7.7 update优化

InnoDB的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则会从行锁升级为表锁。
所以update时尽量根据主键或者索引进行更新

8. 视图 / 存储过程 / 存储函数 / 触发器

8.1 视图

8.1.1 介绍:

视图〈View)是一种虚揪存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。

通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上。

8.1.2 创建

create [or  replace] view 视图名称[(列名列表)] as select语句

8.1.3 查询

查看创建视图语句:

SHOW CREATE VIEW  视图名称;

查看视图数据:

SELECT *FROM   视图名称...... ;

8.1.4 修改

方式一:

CREATE [OR REPLACE] VIEW视图名称[(列名列表)] AS SELECT语句

方式二:

ALTER VIEW 视图名称[(列名列表)] AS SELECT语句

8.1.5 删除

DROP VIEW [IF EXISTS]视图名称[视图名称]...

8.1.6 视图的检查选项

当使用 WITH CHECK OPTION 子句创建视图时,MySQL会通过视图检查正在更改的每个行,例如插入,更新,删除,以使其符合视图的定义。

MySQL允许基于另一个视图创建视图,它还会检查依赖视图中的规则以保持一致性。

为了确定检查的范围,mysql提供了两个选项:CASCADED 和LOCAL,默认值为CASCADED。

8.1.7 视图的更新

要使视图可更新,视图中的行与基础表中的行之间必须存在一对一的关系。如果视图包含以下任何一项,则该视图不可更新:

1.聚合函数或窗口函数(SUM()、MIN()、MAX()、COUNT()等)
2. DISTINCT
3. GROUP BY
4. HAVING
5. UNION 或者UNION ALL

8.1.8 视图的作用

  • 简单

视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。

  • 安全

数据库可以授权,但不能授权到数据库特定行和特定的列上。通过视图用户只能查询和修改他们所能见到的数据

  • 数据独立

视图可帮助用户屏蔽真实表结构变化带来的影响。

8.2 存储过程

  • 介绍

存储过程是事先经过编译并存储在数据库中的一段SQL语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。
存储过程思想上很简单,就是数据库SQL语言层面的代码封装与重用。

8.2.1 创建、调用、查看、删除

  • 创建
CREATE PROCEDURE存储过程名称(〔参数列表
BEGIN
	-- SQL语句
END ;
  • 调用
CALL名称([参数]);
  • 查看
# 查询指定数据库的存储过程及状态信息
SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE RDUTINE_SCHEMA='.sx '; 
# 查询某个存储过程的定义
SHOw CREATE PROCEDURE存储过程名称;
  • 删除
DROP PROCEDURE [ IF EXISTS]存储过程名称;

8.2.2 参数

8.2.2.1 变量

系统变量 : 是MySQL服务器提供,不是用户定义的,属于服务器层面。分为全局变量(GLOBAL)、会话变量(SESSION)。

  • 查看系统变量
# 查看所有系统变量
SHOW [ SESSION | GLOBAL ] VARIABLES ; 
# 可以通过LIKE模糊匹配方式查找变量
SHOW [ SESSION | GLOBAL ] VARIABLES LIKE.....;
# 查看指定变量的值
SELECT @@[ SESSION | GLOBAL] 系统变量名; 
  • 设置系统变量
SET [ SESSION | GLOBAL] 系统变量名 =;
SET @@[ SESSION | GLOBAL] 系统变量名 =;

用户定义变量 : 用户定义变量是用户根据需要自己定义的变量,用户变量不用提前声明,在用的时候直接用“@变量名”使用就可以。其作用域为当前连接。

  • 赋值
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 FROM 表名;
  • 使用
SELECT @var_name ;

局部变量 : 局部变量是根据需要定义的在局部生效的变量,访问之前,需要DECLARE声明。可用作存储过程内的局部变量和输入参数,局部变量的范围是在其内声明的 BEGIN…END块。

  • 声明
# 变量类型就是数据库字段类型:INT、BIGINT、CHAR、VARCHAR、DATE、TIME等。
DECLARE 变量名  变量类型 [DEFAULT ...];
  • 赋值
SET 变量名 =;
SET 变量名 :=;
SELECT 字段名 INTO 变量名 FROM 表名....;
  • if
# 语法
IF 条件1  THEN
	......
ELSEIF 条件2  THEN   	可选
	......
ELSE 					可选
	......
END IF;
  • 参数
类型含义备注
IN该类参数作为输入,也就是需要调用时传入值默认
OUT该类参数作为输出,也就是该参数可以作为返回值
INOUT既可以作为输入参数,也可以作为输出参数

用法

CREATE PROCEDURE 存储过程名称 ([ IN / OUT / INOUT 参数名 参数类型])
BEGIN
	--SQL语句
END;
  • case
# 语法一
CASE case_value
	WHEN when_value1 THEN statement_list1
	[WHEN when_value2 THEN staterment_list 2] ...
	[ ELSE statement_list ]
END CASE;
# 语法二
CASE
	WHEN search_condition1 THEN statement_list1
	[WHEN search_condition2 THEN statement_list2]...
	[ELSE statement_list]
END CASE;
  • while

while循环是有条件的循环控制语句,满足条件后,再执行循环体中的sql语句,具体语法为

# 先判定条件,如果条件为true,则执行逻辑,否则,不执行逻辑
WHILE 条件 DO
	SQL逻辑...
END WHILE;
  • repeat

repeat是有条件的循环控制语句,当满足条件的时候退出循环,具体语法为

# 先执行一次逻辑,然后判定逻辑是否满足,如果满足,则退出。如果不满足,则继续下一次循环
REPEAT
	SQL逻辑...
	UNTIL 条件
END REPEAT;
  • loop

loop实现简单的循环 ,如果不在sql逻辑中增加退出循环的条件,可以用其来实现简单的死循环,loop可以配合以下两个语句使用:

  1. LEAVE : 配合循环使用,退出循环

  2. ITERATE: 必须用在循环中,作用是跳过当前循环剩下的语句,直接进入下一次循环

[begin_label:] LOOP
	SQL逻辑...
END LOOP[end _label];
LEAVE label; --退出指定标记的循环体
ITERATE label;--直接进入下一次循环
  • 游标

游标是用来存储查询结果集的数据类型,在存储过程和函数中可以使用游标对结果集进行循环的处理,游标的使用包括游标的声明、OPEN、FETCH和CLOSE,其语法分别如下

  1. 声明游标
DECLARE 游标名称 CURSOR FOR 查询语句;
  1. 打开游标
OPEN 游标名称;
  1. 获取游标记录
FETCH 游标名称 INTO 变量[,变量];
  1. 关闭游标
CLOSE 游标名称;
  • 条件处理程序

条件处理程序,可以用来定义在流程控制结构执行过程中遇到问题时相应的处理步骤,具体语法为

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代码的简写

8.3 存储函数

存储函数是有返回值的存储过程,存储函数的参数只能是IN类型的,具体语法如下

CREATE FUNCTION 存储函数名称([参数列表])
RETURNS type [characteristic ...]
BEGIN
	--SQL语句
	RETURN ...;
END ;

##########分割线############
characteristic说明:
DETERMINISTIC : 相同的输入参数总是产生相同的结果
NO SQL : 不包含SQL语句。
READS SQL DATA : 包含读取数据的语句,但不包含写入数据的语句。

能使用存储函数的地方就可以使用存储过程,所以存储过程比存储函数使用频繁

8.4 触发器

  • 介绍

触发器是与表有关的数据库对象,指在insert/update/delete之前或之后,触发并执行触发器中定义的sql语句集合,触发器的这种特性可以协助应用在数据库端确保数据的完整性,记录日志,数据校验等操作
使用别名OLD和NEW来引发触发器中发生变化的记录内容,这与其他的数据库是相似的,现在触发器还支持行级触发,不支持语句级触发

触发器类型NEW 和 OLD
INSERT类型触发器NEW表示将要或者已经新增的数据
UPDATE类型触发器OLD表示修改之前的数据,NEW表示将要修改或者已经修改后的数据
DELETE类型触发器OLD表示将要或者已经删除的数据
  • 语法
  1. 创建
CREATE TRIGGER trigger_name
BEFORE/AFTER  INSERT/UPDATE/DELETE
ON table_name FOR EACH ROW   --行级触发器
BEGIN
	trigger_stmt ;  -- 触发器内部逻辑
END;
  1. 查看
SHOW TRIGGERS;
  1. 删除
# 如果没有指定schema_name,默认为当前数据库。
DROP TRIGGER[schema_name.] trigger_name ;

9. 锁🔒

9.1 概述

  • 介绍

锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。

默认情况下,InnoDB在REPEATABLEREAD事务隔离级别运行,InnoDB使用行级锁下的行锁下的next-key(临键)锁进行搜索和索引扫描,以防止幻读

  • 分类

mysql中的锁,按照锁的粒度分,分为以下三类

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

9.2 全局锁

  • 介绍

全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,以及更新操作的事务提交语句都将被阻塞。
其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。

  • 数据备份示例
# 添加全局锁
flush tables with read lock;
# 数据备份  , 在win dos窗口
mysqldump -h 主机地址  -u 用户名  -p 密码 数据库名 > win本地存放路径
# 释放锁
unlock tables;
  • 特点

数据库中添加全局锁,是一个比较重的操作,存在以下问题

  1. 如果在主库上备份,那么在备份期间都不能执行更新,业务基本就得停摆。
  2. 如果在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志(binlog),会导致主从延迟

在innoDB引擎中,我么可以在备份时加上参数 --single-transaction 参数来完成不加锁的一致性数据备份 实现原理是innodb底层使用快照.

mysqldump --single-transaction -h 主机地址  -u 用户名  -p 密码 数据库名 > win本地存放路径

9.3 表级锁

  • 介绍

表级锁,每次操作锁住整张表,锁定粒度大,发生所冲突的概率最高,并发度最低,应用在MyISAM 、InnoDB 、BDB等存储引擎中

对于表级锁,主要分为以下三类

  1. 表锁
  2. 元数据锁(meta data lock , 简称MDL)
  3. 意向锁

9.3.1 表锁

对于表锁,分为两类

  1. 表共享读锁(read lock)
    在这里插入图片描述

  2. 表独占写锁(write lock)
    在这里插入图片描述

语法:

  1. 加锁: lock tables 表名… read/write
  2. 释放锁: unlock tables 或 断开客户端连接

9.3.2 元数据锁(meta data lock , 简称MDL)

元数据就是指表结构

MDL加锁过程是系统自动控制的,无需显式使用,在访问一张表的时候会自动加上,MDL锁主要作用就是维护元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入操作,为了避免DML与DDL冲突,保证读写的正确性

在mysql5.5中引入了MDL.当对一张表进行增删改查的时候,加MDL读锁(共享); 当对表结构进行变更操作的时候,加MDL写锁(排他)

对应SQL锁类型说明
lock tables xxx read / writeSHARED_READ_ONLY / SHARED_NO_READ_WRITE
select 、
select … lock in share mode
SHARED_READ与SHARED_READ、SHARED_WRITE兼容,
与EXCLUSIVE互斥
insert 、update、delete、
select … for update
SHARED_WRITE与SHARED_READ、SHARED_WRITE兼容,
与EXCLUSIVE互斥
alter table …EXCLUSIVE与其他的MDL都互斥

查看元数据锁

select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks ;

9.3.3 意向锁

为了避免DML在执行时,加的行锁与表锁的冲突,在innoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查

  • 对于意向锁分为以下两种
1. 意向共享锁(IS) : 与表锁共享锁(read)兼容,与表锁排他锁(write)互斥
2. 意向排他锁(IX): 与表锁共享锁(raed)及排他锁(write)都互斥.`意向锁之间不会互斥`

可以通过以下sql,查看意向锁及行锁的加锁情况

select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;

9.4 行级锁

  • 介绍

行级锁,每次操作锁住对应的行数据,锁定力度最小,发生锁冲突的概率最低,并发度最高.应用在InnoDB存储引擎中

InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁.

对于行级锁,主要分为以下三类:

1.  行锁(Record Lock) : 锁定单个记录的锁,防止其他事务对此进行update和delete,在RC 、RR隔离级别下都支持
2.  间隙锁(Gap Lock) : 锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读,在RR隔离级别下都支持.
3.  临键锁(Next-Key Lock) : 行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap.在RR隔离级别下支持.
  • InnoDB实现了以下两种类型的行锁
1. 共享锁(S) : 允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁
2. 排他锁(X) : 允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁.
请求锁类型
当前锁类型
(请求)    S(共享锁)(请求)    X(排他锁)
(当前)    S(共享锁)兼容冲突
(当前)    X(排他锁)冲突冲突
  • 增删改查的行锁类型
SQL行锁类型说明
INSERT …排他锁自动加锁
UPDATE …排他锁自动加锁
DELETE …排他锁自动加锁
SELECT (正常)不加任何锁
SELECT … Lock IN SHARE MODE共享锁需要手动在SELECT之后加LOCK IN SHARE MODE
SELECT … FROM UPDATE排他锁需要手动在SELECT 之后加FOR UPDATE

9.4.1 行级锁进阶

  • 行锁

默认情况下,InnoDB在REPEATABLEREAD事务隔离级别运行,InnoDB使用next-key锁进行搜索和索引扫描,以防止幻读。

1.针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将会自动优化为行锁。
2. InnoDB的行锁是针对于索引加的锁,不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁。
  • 间隙锁/临键锁

默认情况下,InnoDB在REPEATABLE READ事务隔离级别运行,InnoDB使用next-key锁进行搜索和索引扫描,以防止幻读。

1.索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁。
2.索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock退化为间隙锁。
3.索引上的范围查询(唯一索引)--会访问到不满足条件的第一个值为止。

注意:间隙锁唯一目的是防止其他事务插入间隙。间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁

10 InnoDB引擎

10.1 逻辑存储结构

在这里插入图片描述

  1. 表空间(idb文件) : 一个mysql实例可以对应多个表空间,用于存储记录、索引等数据.

  2. 段 : 分为数据段(Leaf node segment)、索引段(Non-leaf node segment)、回滚段(Rollback segment), InnoDB是索引组织表,数据段就是B+树的叶子节点,索引段即为B+树的非叶子节点。段用来管理多个Extent(区)。

  3. 区 : 表空间的单元结构,每个区的大小为1M。默认情况下,InnoDB存储引擎页大小为16K,即一个区中一共有64个连续的页。

  4. 页 : 是InnoDB存储引擎磁盘管理的最小单元,每个页的大小默认为16KB。为了保证页的连续性,InnoDB存储引擎每次从磁盘申请4-5个区。

  5. 行 : InnoDB存储引擎数据是按行进行存放的。

    1. Trx_id : 每次对某条记录进行改动时,都会把对应的事务id赋值给trx_id隐藏列。
    2. Roll_pointer : 每次对某条索引记录进行改动时,都会把旧的版本写入到undo日志中,然后这个隐藏列相当于一个指针,可以通过它来找到该记录修改前的信息

10.2 架构

MySQL5.5版本开始,默认使用InnoDB存储引擎,它擅长事务处理,具有崩溃恢复特性,在日常开发中使用非常广泛。
下面是InnoDB架构图,左侧为内存结构,右侧为磁盘结构。
在这里插入图片描述

10.2.1 内存架构

10.2.1.1 Buffer Pool 缓冲池

Buffer Pool:缓冲池是主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载并缓存),然后再以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度。

缓冲池以Page页为单位,底层采用链表数据结构管理Page。根据状态,将Page分为三种类型:

free page:空闲page,未被使用。
clean page:被使用page,数据没有被修改过。
dirty page:脏页,被使用page,数据被修改过,页中数据与磁盘的数据产生了不一致。
10.2.1.2 Change Buffer 更改缓冲区

Change Buffer : 更改缓冲区(针对于非唯一二级索引页),在执行DML语句时,如果这些数据Page没有在Buffer Pool中,不会直接操作磁盘,而会将数据变更存在更改缓冲区Change Buffer中,在未来数据被读取时,再将数据合并恢复到Buffer Pool中,再将合并后的数据刷新到磁盘中。

Change Buffer的意义是什么?
与聚集索引不同,二级索引通常是非唯一的,并且以相对随机的顺序插入二级索引。同样,删除和更新可能会影响索引树中不相邻的二级索引页,如果每一次都操作磁盘,会造成大量的磁盘IO。有了ChangeBuffer之后,我们可以在缓冲池中进行合并处理,减少磁盘IO。

10.2.1.3 Log Buffer 日志缓冲区

Log Buffe r: 日志缓冲区,用来保存要写入到磁盘中的log日志数据(redo log , undo log),默认大小为16MB,日志缓冲区的日志会定期刷新到磁盘中。如果需要更新、插入或删除许多行的事务,增加日志缓冲区的大小可以节省磁盘I/O。

参数:
innodb_log_buffer_size:缓冲区大小
innodb_flush_log_at_trx_commit:日志刷新到磁盘时机

 0 : 每秒将日志写入并刷新到磁盘一次。
 1 : 日志在每次事务提交时写入并刷新到磁盘。
 2 : 日志在每次事务提交后写入,并每秒刷新到磁盘。
10.2.1.4 Adaptive Hash Index 自适应hash索引

Adaptive Hash Index : 自适应hash索引,用于优化对Buffer Pool数据的查询。InnoDB存储引擎会监控对表上各索引页的查询,如果观察到hash索引可以提升速度,则建立hash索引,称之为自适应hash索引。
自适应哈希索引,无需人工干预,是系统根据情况自动完成。
参数: adaptive_hash_index

10.2.2 磁盘架构

10.2.2.1 System Tablespace 系统表空间

System Tablespace : 系统表空间是更改缓冲区的存储区域。如果表是在系统表空间而不是每个表文件或通用表空间中创建的,它也可能包含表和索引数据。(在MySQL 5.x版本中还包含InnoDB数据字典、undolog等)
参数 : innodb_data_file_path

在mysql目录下的 ibdata1文件

当系统表空间不够用时(也就是ibdata1文件),它会自动扩展(autoextend),每次自动扩展64M , 这个扩展不是说再重新生成一个文件ibdat2,而是在ibdata1的基础上进行扩展。当扩展了一次后,又不够用时,又会在ibdat1文件的基础上再扩展64M,至于这个文件能够扩展到多大,默认是没有限制的,就看你的磁盘有多大了

10.2.2.2 File-Pre-Table Tablespaces 每个表的文件表空间

File-Per-Table Tablespaces : 每个表的文件表空间包含单个InnoDB表的数据和索引,并存储在文件系统上的单个数据文件中。
参数: innodb_file_per_table

在mysql目录下的 ibd文件

10.2.2.3 General Tablespaces 通用表空间

General Tablespaces : 通用表空间,需要通过CREATE TABLESPACE语法创建通用表空间,在创建表时,可以指定该表空间。

# 创建表空间
CREATE TABLESPACE 表空间名称 ADDDATAFILE 表对应的磁盘ibd文件名  ENGINE = engine_name(存储引擎名称);
# 创建表时指定表空间
create建表语句  TABLESPACE  表空间
10.2.2.4 Undo Tablespaces 撤销表空间

Undo Tablespaces : 撤销表空间,MySQL实例在初始化时会自动创建两个默认的undo表空间(初始大小16M),用于存储undo log日志。

10.2.2.5 TemporaryTablespaces 临时表空间

Temporary Tablespaces : InnoDB使用会话临时表空间和全局临时表空间。存储用户创建的临时表等数据。

10.2.2.6 Doublewrite Buffer Files 双写缓冲区

Doublewrite Buffer Files : 双写缓冲区,innoDB引擎将数据页从Buffer Pool刷新到磁盘前,先将数据页写入双写缓冲区文件中,便于系统异常时恢复数据。

#  dblwr文件
ib_16384_0.dblwr
ib_16384_1.dblwr
10.2.2.7 Redo Log 重做日志

Redo Log : 重做日志,是用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都会存到该日志中,用于在刷新脏页到磁盘时,发生错误时,进行数据恢复使用。

以循环方式写入重做日志文件,涉及两个文件 :

ib_logfile0
ib_logfile1

10.2.3 后台线程

  • Master Thread

核心后台线程,负责调度其他线程,还负责将缓冲池中的数据异步刷新到磁盘中,保持数据的一致性,还包括脏页的刷新、合并插入缓存、undo页的回收。

  • IO Thread

在InnoDB存储引擎中大量使用了AIO来处理IO请求,这样可以极大地提高数据库的性能,而IO Thread主要负责这些lO请求的回调。

线程类型默认个数指责
Read thread4负责读操作
Write thread4负责写操作
Log thread1负责将日志缓冲区刷新到磁盘
Insert buffer thread1负责将写缓冲区内容刷新到磁盘
  • Purge Thread

主要用于回收事务已经提交了的undo log,在事务提交之后,undo log可能不用了,就用它来回收。

  • Page cleaner Thread

协助Master Thread刷新脏页到磁盘的线程,它可以减轻Master Thread的工作压力,减少阻塞.

10.3 事务原理

  • 事务

事务是一组操作的集合,他是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败.

  • 特性
  1. 原子性 (Atomicity) : 事务是不可分割的最小操作单元,要么全部成功,要么全部失败
  2. 一致性(Consistency) : 事务完成时,必须使所有的数据都保持一致状态.
  3. 隔离性(Isolation) : 数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
  4. 持久性(Durability) : 事务一旦提交或回滚,他对数据库中的数据的改变就是永久的.

在这里插入图片描述

  • ACID 是靠什么保证的?
  1. 原子性由undolog日志来保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的sql
  2. —致性是由其他三大特性保证,程序代码要保证业务上的一致性
  3. 隔离性是由MVCC来保证
  4. 持久性由redolog来保证,mysql修改数据的时候会在redolog中记录一份日志数据。就算数据没有保存成功,只要日志保存成功了,数据仍然不会丢失

10.3.1 持久性

Redo Log 重做日志,是用来实现事务的持久性

当一组事务包含多个操作语句时,进行update和delete操作的时候,会先去缓冲池冲找目标数据,如果没有找到就异步去磁盘文件中找并缓冲目标数据到缓冲池中,此时直接操作缓冲池中的数据

操作之后会在 Redo Log Buffer中备份, Redo Log Buffer会记录数据页的变化,当事务提交时,日志缓冲区会把数据写入到磁盘日志中,对磁盘的写入是追加的顺序磁盘 IO,节省性能.

每间隔一段时间会把Buffer Pool缓冲池中的数据写入到磁盘中,如果此时写入失败,会使用磁盘中的日志文件进行写入.

客户端每次操作数据的时候,数据在数据库中是乱序存储的,对数据库的操作也是乱序的 , 所以Buffer Pool缓冲池不是实时刷新到磁盘的,消耗大量磁盘随机 I/O, 太浪费性能, 所以每间隔一段时间才会把Buffer Pool缓冲池中的数据写入到磁盘中.

会定时清理磁盘中的日志文件

在这里插入图片描述

10.3.2 原子性

  • undo log 回滚日志

回滚日志,用于记录数据被修改前的信息,作用包含两个:提供回滚和MVCC(多版本并发控制)。
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。

10.4 MVCC

  • 当前读

读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁.对于我们日常的操作,如:select … lock in share mode(共享锁) , select … from update 、 update 、insert 、 delete(排他锁) 都是一种当前读.

  • 快照读

简单的select(不加锁)就是快照读,快照读,读取的是激励数据的可见版本,有可能是历史数据,不加锁,是非阻塞读

  1. Read Committed : 每次select , 都生成一个快照读
  2. Repeatable Read : 开启事务后第一个select语句才是快照读的地方
  3. Serializable : 快照读会退化为当前读

10.4.1 MVCC

全称Multi-Version Concurrency Control , 多版本并发控制.指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读的功能.MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志 、 readView

10.4.1.1 记录中的隐藏字段

假设有一张表,我们定义了三个字段 id name age , 那么会自动生成两个或三个隐藏字段

idagenameDB_TRX_IDDB_ROLL_PTRDB_ROW_ID
隐藏字段含义
DB_TRX_ID最近修改事务ID,记录插入记录或最后一次修改该记录的事务ID
DB_ROLL_PTR回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版本
DB_ROW_ID隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段

查看某张表的结构,以及字段

# 不用登录mysql
ibd2sdi ibd文件名
10.4.1.2 undo log

回滚日志,在insert 、 update、delete的时候产生的便于数据回滚的日志。

当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。

而update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。

10.4.1.3 undo log版本链

不同事务或相同事务对同一条记录进行修改,会导致该记录的undo log生成一条记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。
在这里插入图片描述

10.4.1.4 readView

ReadView(读视图)是快照读SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的) id。
ReadView中包含了四个核心字段:

字段含义
m_ids当前活跃的事务ID集合
min_trx_id最小活跃事务ID
max_trx_id预分配事务ID,当前最大事务ID+1 (因为事务ID是自增的)
creator_trx_idReadView创建者的事务ID

在这里插入图片描述

不同的隔离级别,生成readview的时机不同

READ COMMITTED : 在事务中每一次执行快照读时生成readview
REPEATABLE READ : 仅在事务第一次执行快照读时生成readview,后续复用该readview

10.4.1.5 总结

MVCC和锁🔒保证了事务的隔离性
redo log 和 undo log 保证了事务的一致性

在这里插入图片描述

10.5 InnoDB总结

  • 逻辑存储结构

表空间、段、区、页、行

  • 架构

内存结构、磁盘结构

  • 事务原理

原子性 : undo log
持久性 : redo log
一致性 : undo log + redo log
隔离性 : 锁 + MVCC

  • MVCC

记录隐藏字段、undo log 版本链 、readView

11 Mysql管理

11.1 系统数据库

MySQL数据库安装完成后,自带了以下四个数据库,具体作用如下

数据库含义
mysql存储MysQL服务器正常运行所需要的各种信息(时区、主从、用户、权限等)
information_schema提供了访问数据库元数据的各种表和视图,包含数据库、表、字段类型及访问权限等
performance_schema为MysQL服务器运行时状态提供了一个底层监控功能,主要用于收集数据库服务器性能参数
sys包含了一系列方便DBA和开发人员利用performance_schema性能数据库进行性能调优和诊断的视图

11.2 常用工具

  • mysql

该mysql不是指mysql服务,而是指mysql的客户端工具

语法:

mysql [options] [database]

选项:

-u		# 指定用户名
-p		# 指定密码
-h		# 指定ip
-P		# 指定连接端口
-e		# 执行sql语句并退出
  • mysqladmin

mysqladmin是一个执行管理操作的客户端程序,可以用它来检查服务器的配置和当前状态、创建并删除数据库等

通过帮助文档查看选项

mysqladmin --help
  • mysqlbinlog

由于服务器生成的二进制日志文件以二进制格式保存,所以如果想检查这些文本的文本格式,就会使用到mysqlbinlog日志管理工具

语法 :

mysqlbinlog [options] log-files1 log-files2 ...

选项:

-d		# 指定数据库名称,只列出指定的数据库相关操作
-o		# 忽略掉日志中的前n行命令
-r		# 将输出的文本格式日志输出到指定文件
-s		# 简单输出格式,省略掉一些信息
# 指定日期间隔内的所有日志
--start-datetime=date1 --stop-datetime=date2
# 指定位置间隔内的所有日志
--start-position=pos1 --stop-position=pos2
  • mysqlshow

mysqlshow客户端对象查找工具,用来很快地查找存在哪些数据库、数据库中的表、表中的列或者索引.

语法 :

mysqlshow [options] [db_name] [table_name] [col_name]

选项 :

--count			# 显示数据库及表的统计信息(数据库、表均可以不指定)
-i					# 显示指定数据库或者指定表的状态信息

示例 :

# 查询每个数据库的表的数量及表中记录的数量
mysqlshow -u 用户名 -p 密码--count
# 查询test库中每个表中的字段数,及行数
mysqlshow -u 用户名 -p 密码 test --count
# 查询test库中book表的详细情况
mysqlshow -u 用户名 -p 密码 test book --count
  • mysqldump

mysqldump客户端工具用来备份数据库或在不同数据库之间进行数据迁移。备份内容包含创建表,及插入表的sql语句。

语法:

mysqldump [options] db_name [tables]
mysqldump [options] --database/-B db1 [db2 db3...]
mysqldump [aptions]--all-databases/-A

连接选项:

-u		# 指定用户名
P		# 指定密码
-h		# 指定服务器ip或域名
-P		# 指定连接端口

输出选项:

# 在每个数据库创建语句前加上drop database语句
--add-drop-database

# 在每个表创建语句前加上drop table语句,默认开启;不开启(--skip-add-drop-table)
--add-drop-table

# 不包含数据库的创建语句
-n

# 不包含数据表的创建语句
-t

# 不包含数据
-d 

# 自动生成两个文件:一个 .sql文件,创建表结构的语句;一个.txt文件,数据文件
-T
  • mysqlimport / source

mysqlimport 是客户端数据导入工具,用来导入mysqldump 加-T参数后导出的文本文件。

语法:

mysqlimport [options] db_name textfile1 [textfile2...]

示例:

mysqlimport -u 用户名 -p 密码 数据库名 导出的txt文件路径

如果需要导入sql文件,可以使用mysql中的source指令:

语法:

source sql脚本文件路径

运维篇

12 日志

13 主从复制

14 分库分表

15 读写分离

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值