Mysql 基础相关知识整理(-)

为啥写这篇文章呢?这些知识都比较浅,可能人人都知道,含金量不高。但是作为一名程序员,工作这么久,学到的东西肯定很杂乱。梳理知识也是非常重要的一个学习方式。一定要打好基础呀~~!

基础概念目录整理

  1. 悲观锁,乐观锁
  2. 事务
  3. 多版本控制 (mvcc)
  4. 存储引擎
  5. 数据类型

一般情况下,数据库是可以被多个程序读取的。所以在很容易出现同一资源,在同一时刻被不同程序读取或修改。这样会导致,程序读取资源有误,或者资源被错误修改等情况。为了解决这个问题,数据库都会提供一个“锁”的机制。

在 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 引擎是有死锁检测和死锁超时机制的

死锁产生的四大条件

  1. 互斥:每个资源只能被一个进程使用,其它进程请求该资源是只能等待。(就是写锁)
  2. 请求与保持:进程保持了一个资源,但又提出了一个新的资源请求,但该资源被其他进程占有。这是请求被阻塞,但对自己获得的资源保持不放
  3. 不可剥夺:进程获得资源只能由进程自己释放
  4. 循环条件:多个进程形成首尾相接循环等待资源的关系

预防死锁,只需打破 2,3,4条件即可。

多版本控制(MVCC)

innodb 中 mvcc 的实现是通过新增两列,一列保存创建时的事务版本号,另一列保存删除时的事务版本号。实现的一个简单的乐观锁。《Mysql中MVCC的使用及原理详解》 这篇博客中有详细讲解mvcc的实现方式。

存储引擎

一般在mysql中较为常见的集中数据库引擎有

  • InnoDB
  • MyISAM
  • Archve
  • Memory
  • NDB 集群

而这里面考的最多的就是 InnoDB MyISAM 这两种了。其中区别有是否支持事务,锁粒度,索引实现不同(是否为聚簇索引)。

另外网上其他博客也说MyISAM支持全文索引,InnoDB不支持。事实上在mysql 5.6+后 InnoDB 已经支持了全文索引

最后

关于 MySQL 的部分知识,先写到这。还有关于索引的知识,放到下篇再讲