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)创建全文索引。

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

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

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

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

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