数据库学习笔记

2020-04-22  本文已影响0人  Nifury

Mysql常用的存储引擎对比

Mysql的存储结构

系统从磁盘读取数据到内存以块(block)为单位,Mysql数据存储在磁盘中,以页为单位,默认每页16k,系统磁盘块一般没有这么大,所以一般是使用连续的若干个块来构成页

InnoDB存储引擎中页的大小为16KB,一般表的主键类型为INT(占用4个字节)或BIGINT(占用8个字节),指针类型也一般为4或8个字节,也就是说一个页(B+Tree中的一个节点)中大概存储16KB/(8B+8B)=1K个键值(因为是估值,为方便计算,这里的K取值为10^3)。 也就是说一个深度为3的B+Tree索引可以维护10^3 * 10^3 * 10^3 = 10亿 条记录。

Mysql的数据库索引

B+树的查找过程如下图

20160202204827368.png

数据库悲观锁和乐观锁

加了写锁以后,其他的事务就不能对它修改了!

select * from xxxx for update

通过给表增加版本号来实现,更新时对比版本号

update A set Name=lisi,version=version+1 where ID=#{id} and version=#{version}

常见数据库优化手段

Mysql事务隔离级别

事务的四大基本要素(ACID):原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation,同一时间不同事务间没有干扰)、持久性(Durability,事务完成后数据被持久化)

事务的并发问题:脏读(读到了其他事务未提交的数据)、不可重复读(事务期间多次读取的数据不一致)、幻读(一个事务改全表多条数据期间,另一进程插入数据导致全表更新结果不完整,解决幻读需锁表)

事务隔离级别 脏读 不可重复读 幻读 解释
读未提交(read-uncommitted) 允许读取其他事务未提交的数据
不可重复读(read-committed) 只读取其他事务已提交的数据
可重复读(repeatable-read) select操作不更新版本号,后续重复读取的是历史版本,update/insert/delete操作时读取最新版本
串行化(serializable) 操作串行化、锁表,事务操作时全表不允许其他线程修改,并发极低,很少用

Mysql默认使用repeatable-read级别,有索引时,默认使用next-key锁(锁定数据及前后几条,一定程度上避免幻读)。如果检索条件没有索引,更新数据时会锁住整张表!

上一篇 下一篇

猜你喜欢

热点阅读