MySQL基础(一)

46 阅读10分钟

解析器:将sql语句变成数据结构,并将这个结构传递到后续步骤。后面sql语句的传递和处理就是基于这个结构的。

server层

sql语句的解析 在这里插入图片描述

mysql线上版本是8.0以上,默认不开启查询缓存。 在这里插入图片描述

在这里插入图片描述 抛弃查询缓存原因有如下: 1.缓存命中需要两次查询语句是一模一样,例如 SELECT * FROM e1; 不等于 select * from e1 此外,一些不确定的查询结果无法 被缓存,任何对表的修改都会导致这些表的所有缓存无效。 2.查询缓存的另一个大问题是它受到单个互斥锁的保护。在具有多个内 核的服务器上,大量查询会导致大量的互斥锁争用。

存储引擎

MySQL 数据库区别于其他数据库的最重要的一个 特点就是其插件式的表存储引擎,存储引擎是底层物理结构和实际文件 读写的实现,每个存储引擎开发者可以按照自己的意愿来进行开发。需要特别注 意的是,存储引擎是基于表的,而不是数据库

MySQL 5.5 版本将 InnoDB 作为默认的存储引擎了。 ALTER TABLE 将表从一个引擎修改为另一个引擎最简单的办法是使用 ALTER TABLE 语句。 下面的语句将 mytable 的引擎修改为 InnoDB : mysql> ALTER TABLE mytable ENGINE = InnoDB; 存储引擎是基于表的,而不是数据库。 上述语法可以适用任何存储引擎。但需要执行很长时间,在实现上,MySQL 会按行将数据从原表复制到一张新的表中,在复制期间可能会消耗系统所有的 I/O 能力,同时原表上会加上读锁。所以,在繁忙的表上执行此操作要特别小心。

默认的存储引擎是InnoDB 在这里插入图片描述

MyISAM与InnoDB比较

在这里插入图片描述 可以通过命令 show variables 查看数据库中的所有参数,参数的具体含义可以参考 MySQL 官方手册: dev.mysql.com/doc/refman/…

到底 MySQL 把数据都存到哪个路径下呢?

show variables like 'datadir'; 在这里插入图片描述 这个目录可以通过配置文件进行修改,由我们自己进行指定。

数据库在文件系统中的表示

每当我们使用 CREATE DATABASE 语句创建一个数据库的时候,在文件系统上实际发生了什么呢?其实很简单,每个数据库都对应数据目录下的一个子目录, 或者说对应一个文件夹。 1.在数据目录下创建一个和数据库名同名的子目录(或者说是文件夹)。 2.在该与数据库名同名的子目录下创建一个名为 db.opt 的文件,这个文件 中包含了该数据库的各种属性,比方说该数据库的字符集和比较规则是个啥。

表在文件系统中的表示

每个表的信息其实可以分 为两种: 1.表结构的定义 2.表中的数据 表结构就是该表的名称是啥,表里边有多少列,每个列的数据类型是啥,有 啥约束条件和索引,用的是啥字符集和比较规则各种信息,这些信息都体现在了 我们的建表语句中了。 为了保存这些信息,InnoDB 和 MyIASM 这两种存储引擎 都在数据目录下对应的数据库子目录下创建了一个专门用于描述表结构的文件, 文件名是这样:表名.frm,该文件二进制格式存储的。

那表中的数据存到什么文件中了呢? lnnoDB 是如何存储表数据的 InnoDB 的数据会放在一个表空间或者文件空间(英文名: table space 或者 file space)的概念,这个表空间是一个抽象的概念,它可以对应文件系统上一个或多 个真实文件〈不同表空间对应的文件数量可能不同)。

系统表空间(system tablespace) 这个所谓的系统表空间可以对应文件系统上一个或多个实际的文件,默认情 况下,InnoDB 会在数据目录下创建一个名为 ibdata1(在你的数据目录下找找看有 木有)、大小为 12M 的文件,这个文件就是对应的系纳表空间在文件系统上的表示。 在一个 MySQL 服务器中,系统表空间只有一份。

独立表空间(file-per-table tablespace) 在 MySQL5.6.6 以及之后的版本中,InnoB 并不会默认的把各个表的数据存储 到系统表空间中,而是为每一个表建立一个独立表空间,也就是说我们创建了多 少个表,就有多少个独立表空间。 举例我们使用了独立表空间去存储 xiaohaizi 数据库下的 test 表的话, 那么在该表所在数据库对应的 xiaohaizi 目录下会为 test 表创建这两个文件: test.frm 和 test.ibd

日志文件

错误日志 在这里插入图片描述 当 MySQL 不能正常启动时,第一个必须查找的文件应该就是错误日志文件, 该文件记录了错误信息。

慢查询日志 show variables like "%slow%"; 在这里插入图片描述 通用日志 通用日志记录了所有对 MySQL 数据库请求的信息,无论这些请求是否得到 了正确的执行。 show variables like 'general_log'; 在这里插入图片描述 通用日志未开启

二进制日志(binlog) binlog 二进制日志记录了对 MySQL 数据库执行更改的所有操作,若操作本身没有 导致数据库发生变化,该操作可能也会写入二进制文件。但是不包括 select 和 show 这类操作(因为这些操作对数据本身不会进行修改)。

binlog日志的几种作用: 1.恢复(recovery):某些数据的恢复需要二进制日志,例如,在一个数据库全备文件恢复后,用户可以通过二进制文件进行 point-in-time 的恢复 2.复制(replication):其原理与恢复类似,通过复制和执行二进制日志使一 台远程的 MySQL 数据库(一般称为 slave 或 standby)与一台 MySQL 数据库(一 般称为 master 或 primary)进行实时同步 3.审计(audit):用户可以通过二进制日志中的信息来进行审计,判断是否有 对数据库进行注入的攻击

在这里插入图片描述

事务和事务的隔离级别

事务特性 事务应该具有 4 个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为 ACID 特性。 原子性(atomicity) 一个事务必须被视为一个不可分割的最小单元,整个事务中的所有操作要么 全部提交成功,要么全部失败,对于一个事务来说,不能只执行其中的一部分操 作。比如: King 老师借给大飞老师生活费: 1.King 老师工资卡扣除 500 元 2.大飞老师工资卡增加 500 整个事务的操作要么全部成功,要么全部失败,不能出现 King 老师工资卡 扣除,但是大飞老师工资卡不增加的情况。如果原子性不能保证,就会很自然的 出现一致性问题。 一致性(consistency) 一致性是指事务将数据库从一种一致性转换到另外一种一致性状态,在事务 开始之前和事务结束之后数据库中数据的完整性没有被破坏。 King 老师借给大飞老师生活费: 1.King 老师工资卡扣除 500 元 2.大飞老师工资卡增加 500 扣除的钱(-500) 与增加的钱(500) 相加应该为 0,或者说 King 老师和 大飞老师的账户的钱加起来,前后应该不变。 持久性(durability) 一旦事务提交,则其所做的修改就会永久保存到数据库中。此时即使系统崩溃,已经提交的修改数据也不会丢失。 隔离性(isolation) 一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

事务并发引发的问题

脏读 当一个事务读取到了另外一个事务修改但未提交的数据,被称为脏读。 在这里插入图片描述 事务 2 修改了一行记录,但是没有提交。然后事务 1 读取到了未提交的数据, 如果事务 2 回滚其更改的数据或者再次更新,那么在事务 1 中看到的记录可能就 是错误的。事务 1 读取到了 King 老师余额为 1500 的记录,但是事务 2 执行了回 滚操作,这时并不存在 King 老师余额为 1500 记录。

不可重复读 当事务内相同的记录被检索两次,且两次得到的结果不同时,此现象称为不 可重复读。 在这里插入图片描述 事务 2 对记录做了修改并提交成功,这意味着修改的记录对其他事务是可见的, 因此事务 1 两次读取的 money 值不同。

幻读 在事务执行过程中,另一个事务将新记录添加到正在读取的事务中时,会发 生幻读。 当事务 1 重复执行 SELECT... WHERE 语句时,在这期间事务 2 执行 INSERT 语句插入了满足 where 条件的新记录。于是事务 1 执行两次一模一样的 SELECT... WHERE,返回却是两组不同的记录。 在这里插入图片描述 有的同学会有疑问,那如果事务 2 中是删除了符合的记录而不是插入新记录, 那事务 1 中之后再根据条件读取的记录变少了,这种现象算不算幻读呢?明确说 一下,在 MySQL 中这种现象不属于幻读,幻读强调的是一个事务按照某个相同 条件多次读取记录时,后读取时读到了之前没有读到的记录。

SQL 标准中的四种隔离级别

READ UNCOMMITTED: 读未提交。 READ COMMITTED: 读已提交。 REPEATABLE READ: 可重复读。 SERIALIZABLE: 可串行化。 在这里插入图片描述 MySQL 的默认隔离级别为 REPEATABLE READ:可重复读。

如何设置事务的隔离级别

SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL level; 其中的 level 可选值有 4 个: level: { REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED | SERIALIZABLE }

MySQL 事务

事务基本语法 事务开始 1、begin 2、START TRANSACTION(推荐) 3、begin work 事务回滚 rollback 事务提交 commit

隐式提交 当我们使用 START TRANSACTION 或者 BEGIN 语句开启了一个事务,或者把 系统变量 autocommit 的值设置为 OFF 时,事务就不会进行自动提交,但是如果 我们输入了某些语句之后就会悄悄的提交掉,就像我们输入了 COMMIT 语句了 一样,这种因为某些特殊的语句而导致事务提交的情况称为隐式提交,这些会导 致事务隐式提交的语句包括: 执行 DDL 定义或修改数据库对象的数据定义语言(Data definition language,缩写为:DDL)。所谓的数据库对象,指的就是数据库、表、视图、存储过程等等这些东西。 当我们使用CREATE、ALTER、DROP 等语句去修改这些所谓的数据库对象时,就 会隐式的提交前边语句所属于的事务,就像这样: BEGIN; SELECT ... # 事务中的一条语句 UPDATE ... # 事务中的一条语句 ... # 事务中的其它语句 create table ...# 此语句会隐式的提交前边语句所属事务。 隐式使用或修改 mysql 数据库中的表 当我们使用 ALTER USER、CREATE USER、DROP USER、GRANT、RENAME USER、 REVOKE、SET PASSWORD 等语句时也会隐式的提交前边语句所属于的事务。