MySQL数据库总结
版本:8.0
查看会话当前使用的哪个数据库:
1 | select database(); |
设置关闭自动提交事务:
1 | set autocommit = 0; |
1. 事务的隔离级别
隔离级别总共有四种:
- 读未提交(Read-Uncommited)
- 读提交(Read-Commited)解决“脏读”
- 可重复读(Repeatable-Read)解决“不可重复读”
- 串行化(Serializable)解决“幻读”
查看当前会话事务的隔离级别:
1 | select @@transaction_isolation; |
查看数据库的隔离级别:
1 | select @@global.transaction_isolation; |
1 | mysql> select @@global.transaction_isolation; |
可见innoDB默认的是可重复读这一隔离级别。可重复读可以避免”不可重读“(innoDB在PR级别通过MVCC解决了幻读这一现象)
排他锁,共享锁
排它锁(Exclusive),又称为X 锁,写锁。
共享锁(Shared),又称为S 锁,读锁。
读写锁之间有以下的关系:
- 一个事务对数据对象O(多行,或者表等等)加了S锁,可以对O进行读取操作,但是不能进行更新(update、delete)操作。加锁期间其它事务能对O加S锁,但是不能加 X 锁。
- 一个事务对数据对象 O 加了 X 锁,就可以对 O 进行读取和更新。加锁期间其它事务不能对 O 加任何锁。
读写锁之间的关系可以概括为:允许多个事务一起读,读写互斥!
但加行锁并不可以解决”幻读“这一现象,因为行锁无法对后insert的数据加锁。幻读指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新行,当之前的事务再次读取该范围的记录时,会产生幻行。解决幻读要么序列化,要么加表锁。
首先了解两个概念:
- 一致读:consistent read 也叫快照读,当事务开始时会给数据“拍个照”,只要本事务不做update、insert操作,无论其他事务怎样提交,在本事务结束前select查到的内容不会改变。
- 当前读:
select * from table_1 for update
读取数据库最新的内容
Mysql中主要通过MVCC来保证可重复读,和select级别的幻读。注意:当其他事务进行提交后,本事务要对提交的数据进行修改时,会使用当前读,即update之前先select数据库最新的内容,这就会导致幻读。所以说只保证select级别的幻读,看以下例子:
- A、B事务同时开始
- A事务查询table中的记录,得到一条记录;B事务插入table一条记录,id=2,B事务提交
- A事务当前update id为2的数据,A事务会先查询table中的所有数据,再进行更新。之后查询table中的记录,发现有了两条记录。
- 注意,当不进行更新操作,即使其他事务插入数据并提交,快照读可以保证可重复读,加行锁不可以。
多版本并发控制:multi-versioned concurrency control,是MySQL中基于乐观锁理论实现隔离级别的方式,用于实现读已提交和可重复读取隔离级别的实现。在MySQL中,会在表中每一条数据后面添加两个字段:创建版本号:创建一行数据时,将当前系统版本号作为创建版本号赋值;删除版本号:删除一行数据时,将当前系统版本号作为删除版本号赋值。
2. MySQL索引
2.1 InnoDB引擎
聚集索引,B+树
2.3 MyISAM引擎
叶节点并不存储数据,而是存储指向数据的指针。
非聚集索引
区别 | Innodb | Myisam |
---|---|---|
事务 | 安全 | 非安全 |
锁 | 行级 | 表级 |
效率 | 低 | 高 |
索引 | 聚集索引 | 非聚集索引 |
外键 | 支持 | 不支持 |
使用环境 | 需要事务,大量增,改 | 多查询,不需要事务 |
附:在Ubuntu上安装MySQL8.0
请参考:https://computingforgeeks.com/how-to-install-mysql-8-on-ubuntu/