Skip to content

MySQL mysql 学习 ​

AI 整理版

本篇已整理为更适合学习与复习的笔记结构,欢迎前往阅读:mysql 学习-AI整理版。

简述 MyISAM和InnoDB的区别 ​

MyISAM ​

不支持事务,但是每次查询都是原子的;

支持表级锁,即每次操作都是对整个表加锁;

存储表的总行数;

一个MyISAM表有三个文件:索引文件、表结构文件、数据文件;

采用非聚集索引,索引文件的数据域储存指向数据文件的指针。辅索引与主索引基本一致,但是辅索引不用保证唯一性。

InnoDB ​

支持ACID的事务,支持事务的四种隔离级别;

支持行级锁及外键索引约束,因此可以支持写并发;

不存储表的总行数;

一个InnoDB引擎存储在一个文件空间(共享表空间,表大小不受操作系统控制,一个表可能分布在多个文件里)

,也有可能为多个(设置为独立表空间,表大小受操作系统文件大小限制,一般为2G),受操作系统文件大小的限制;

主键索引采用聚集索引(索引的数据域存储数据文件本身),辅索引的数据域存储主键的值,因此从辅索引查找数据,需要先通过辅索引找到主键值,再访问主索引;最好使用自增主键,防止插入数据时,为维护B+树结构,文件的大调整。

mysql-执行计划查看 ​

事务的基本特性和隔离级别 ​

事务基本特性ACID分别是: ​
  • 原子性
  • 一致性
  • 隔离性
  • 持久性
原子性 ​

指的是一个事务中的操作要么全部成功,要么全部失败。

一致性 ​

指的是数据库总是从一个一致性的状态转换到另一个一致性的状态。

比如A转账给B 100 块钱,假设A只有90块,支付之前我们数据库里的数据都是符合约束的,但是如果事务执行成功看,我们的数据库数据破坏约束了,因此事务不能成功,这里我们说事务提供看一致性的宝座。

隔离性 ​

指的是一个事务的修改在最终提交前,对其他事务是不可见得。

持久性 ​

指的是一旦事务提交,所做的修改就会永久保存在数据库中。

隔离性有4个隔离级别,分别是: ​
read uncommit ​

读未提交,可能会读到其他事务未提交的数据,也叫做脏读。

用户本来应该读取到 id=1 的用户age应该是 10,结果读取到了其他事务还没有提交的事务。结果读取结果age=20,这就是脏读。

read commit ​

读已提交,两次读取结果不一致,叫做不可重复读。

不可重复读解决了脏读的问题,他只会读取已提交的事务。

用户开启事务读取 id=1 的用户,查询到age=10,再次读取发现结果=20,在同一个事务里同一个查询读取到不同的结果叫做不可重复读。

repeatable read ​

可重复读,这是mysql的默认级别,就是每次读取结果都一样,但是有可能产生幻读。

serializable ​

串行,一般是不会使用的,他会给每一行读取的数据加锁,会导致大量超时和锁竞争的问题。

脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因。前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

不可重复读(Non-repeatable Read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。

幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它之前所没有的。

ACID靠什么保证的 ​

A: 原子性

由 undo log 日志保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的sql

C:一致性

由 其他三大特征保证、程序代码要保证业务上的一致性

I:隔离性

由 MVVC 来保证

D:持久性

由 内存+redo log 来保证,mysql修改数据同时在内存和redo log记录这次操作,宕机的时候可以从redo log恢复

mysql
InnoDb redo log 写盘,InnoDb事务进入 prepare 状态。
如果前面 prepare 成功,binlog 写盘,再继续将事务日志持久化到 binlog ,如果持久化成功,那么 InnoDb 事务则进入 commit状态(在 redo log 里面写一个 commit 记录)

redo log 的刷盘会在系统空闲时进行

慢查询怎么优化? ​

慢查询的优化首先要搞明白慢的原因是什么?

是查询条件没有命中索引?

是load了不需要的数据列? 例如select *

还是数据量太大?

针对这三个方向我们可以这样优化,

  1. 首先分析语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写。
  2. 分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者索引,使得语句可以尽可能的命中索引。
  3. 如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可以进行横向或者纵向的分表。

mysql主从同步原理 ​

Mysql的主从复制中主要有三个线程:master(binlog dump thread)、slave(I/O thread、SQL thread),Master一条线程和Slave中的两条线程。

  • 主节点 binlog,主从复制的基础是主库记录的所有变更记录到binlog。binlog是数据库服务器启动的那一刻起,保存所有修改数据库结构或内容的一个文化。
  • 主节点 log dump 线程,当 binlog 有变动时, log dump 线程读取其内容并发送给从节点。
  • 从节点 I/O 线程接收 binlog 内容,并将其写入到 relay log 文件中。
  • 从节点的 SQL 线程读取 relay log 文件内容对数据更新进行重放,最终保证主从数据库的一致性。

注:主从节点使用 binlog 文件 + position 偏移量来定位主从同步的位置,从节点会保存其已接收到的偏移量,如果从节点发生宕机重启,则会自动从 position 的位置发起同步。

由于mysql默认的复制方式是异步的,主库把日志发送给从库后不关心从库是否已经处理,这样会产生一个问题就是假设主库挂了,从库处理失败了,这时候从库升为主库后,日志就丢失了。因此产生两个概念。

全同步复制 ​

主库写入binlog后强制同步日志到从库,所有的从库都执行完成后才返回给客户端,但是很显然这个方式的话性能会受到严重影响。

半同步复制 ​

和全同步不同的是,半同步复制的逻辑是这样的,从库写入日志成功后返回ACK确认给主库,主库收到至少一个从库的确认就认为写操作完成。

简述mysql中索引类型及对数据库的性能的影响 ​

普通索引 ​

允许被索引的数据列包含重复的值。

唯一索引 ​

可以保证数据记录的唯一性。

主键 ​

是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字PRIMARY KEY 来创建。

联合索引 ​

索引可以覆盖多个数据列,如像INDEX(columnA,columnB)索引。

全文索引 ​

通过建立倒排索引,可以极大的提升检索效率,解决判断字段是否包含的问题,是目前搜索引擎使用的一种关键技术。可以通过 ALTER table_name ADD FULLTEXT(column)创建全文索引。

索引可以极大的提高数据的查询速度。

通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

但是会降低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作索引文件,索引需要占用物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,

如果要建立聚集索引,那么需要的空间就会很大;

如果非聚集索引很多,一旦聚集索引改变,那么所有非聚集索引都会跟着变。