为啥写这篇文章呢?这些知识都比较浅,可能人人都知道,含金量不高。但是作为一名程序员,工作这么久,学到的东西肯定很杂乱。梳理知识也是非常重要的一个学习方式。一定要打好基础呀~~!
基础概念目录整理
- 悲观锁,乐观锁
- 事务
- 多版本控制 (mvcc)
- 存储引擎
- 数据类型
锁
一般情况下,数据库是可以被多个程序读取的。所以在很容易出现同一资源,在同一时刻被不同程序读取或修改。这样会导致,程序读取资源有误,或者资源被错误修改等情况。为了解决这个问题,数据库都会提供一个“锁”的机制。
在 Mysql 中则有两种锁
- 读锁(共享锁),被读锁锁定时,允许同一时刻多个程序读取该资源,但不允许写操作
- 写锁(排他锁),被写锁锁定是,该资源则不能被其他程序做读写操作
锁有不同的粒度大小
- 表锁,对整张表做锁定。优点是系统资源开销小,缺点则是并发操作不高
- 行锁,对表中的某一行数据加锁。这样一张表内能有多个锁存在,增加了单表支持并发操作数,缺点则是系统开销较大
事务
事务是数据库的高级特性,它可以将多个sql语句,变成一个工作单元。使其操作具有整体性,成功则都所有操作都成功,失败则所有操作都失败。
事务的四大特性
所有的事务,都需要满足 ACID 原则
- 原子性
- 一致性
- 隔离性
- 持久性
事务的隔离等级
那么,提到隔离性,就得讲到隔离级别。隔离级别分为四个等级
- READ UNCOMMITTED (未提交读)
- READ COMMITED (提交读)
- REPEATABLE READ (可重复读)
- SERIALIZABLE (可串行化)
不同的级别可能会出现不同的错误现象
- 脏读:未提交的事务所做的修改,对其他事务可见。当其他读取该事务修改后,该事务失败数据回滚,则出现脏读。
- 不可重复读:一般在提交读级别中出现,由于事务锁修改的,在提交前与提交后会不一样,可能会导致两次查询中得到不同结果。
- 幻读:当某个事务在读取某个范围内的记录时,其他事务插入了一条新纪录。前面的事务在此读取该范围是则会出现幻行,也就是说,两次查询数据条数不等。
隔离级别|脏读可能|不可重复读可能|幻读可能|加锁读
-| -| -| -| -| -
未提交读|yes|yes|yes|no
提交读|no|yes|yes|no
可重读读|no|no|yes|no
可串行化|no|no|no|yes
什么是死锁
死锁是两个事务在同一个资源上相互占用而导致的恶性循环现象。而在 Mysql 中的 InnoDB 引擎是有死锁检测和死锁超时机制的
死锁产生的四大条件
- 互斥:每个资源只能被一个进程使用,其它进程请求该资源是只能等待。(就是写锁)
- 请求与保持:进程保持了一个资源,但又提出了一个新的资源请求,但该资源被其他进程占有。这是请求被阻塞,但对自己获得的资源保持不放
- 不可剥夺:进程获得资源只能由进程自己释放
- 循环条件:多个进程形成首尾相接循环等待资源的关系
预防死锁,只需打破 2,3,4条件即可。
多版本控制(MVCC)
innodb 中 mvcc 的实现是通过新增两列,一列保存创建时的事务版本号,另一列保存删除时的事务版本号。实现的一个简单的乐观锁。《Mysql中MVCC的使用及原理详解》 这篇博客中有详细讲解mvcc的实现方式。
存储引擎
一般在mysql中较为常见的集中数据库引擎有
- InnoDB
- MyISAM
- Archve
- Memory
- NDB 集群
而这里面考的最多的就是 InnoDB MyISAM 这两种了。其中区别有是否支持事务,锁粒度,索引实现不同(是否为聚簇索引)。
另外网上其他博客也说MyISAM支持全文索引,InnoDB不支持。事实上在mysql 5.6+后 InnoDB 已经支持了全文索引
最后
关于 MySQL 的部分知识,先写到这。还有关于索引的知识,放到下篇再讲