学习关系型数据库MySQL是很好的切入点,大部分人工做中用惯了CRUD,对面试官刨根问底的灵魂拷问你还能对答如流吗?咱们有必要了解一些更深层次的数据库基础原理。html
整理了面试中,关于MySQL事务和存储引擎10个FAQ(Frequently asked questions),你想知道的都在这里。mysql
事务就是「一组原子性的SQL查询」,或者说一个独立的工做单元。若是数据库引擎可以成功地对数据库应用该组查询的所有语句,那么就执行该组查询。若是其中有任何一条语句由于崩溃或其余缘由没法执行,那么全部的语句都不会执行。也就是说,事务内的语句,要么所有执行成功,要么所有执行失败。git
BEGIN 或 START TRANSACTION 显式地开启一个事务; COMMIT / COMMIT WORK两者是等价的。提交事务,并使已对数据库进行的全部修改为为永久性的; ROLLBACK / ROLLBACK WORK。回滚会结束用户的事务,并撤销正在进行的全部未提交的修改; SAVEPOINT identifier 在事务中建立一个保存点,一个事务中能够有多个 SAVEPOINT; RELEASE SAVEPOINT identifier 删除一个事务的保存点; ROLLBACK TO identifier 把事务回滚到标记点; SET TRANSACTION 用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE
用银行业务举个栗子,用户lemon有两银行卡,一张是招商银行CMBC的工资卡,另外一张是工商银行ICBC的储蓄卡,每个月5号发工资都要把招行卡的100万转到建设银行储蓄卡帐户。记住这里的银行缩写后面就是对应的数据表名称,你要记不住,我给你理一理。程序员
招商银行(CMBC):“存么?白痴!” 中国工商银行(ICBC): “爱存不存!” 中国建设银行(CCB): “存?存不?” 中国银行(BC): “不存!” 中国农业银行(ABC): “啊,不存!” 民生银行(CMSB):“存么?SB!" 兴业银行(CIB):“存一百。” 国家开发银行(CDB):“存点吧!” 汇丰银行(HSBC):“仍是不存!”
这个转帐的操做能够简化抽成一个事务,包含以下步骤:github
如下语句对应建立了一个转帐事务:web
START TRANSACTION; SELECT balance FROM CMBC WHERE username='lemon'; UPDATE CMBC SET balance = balance - 1000000.00 WHERE username = 'lemon'; UPDATE ICBC SET balance = balance + 1000000.00 WHERE username = 'lemon'; COMMIT;
ACID实际上是事务特性的英文首字母缩写,具体的含义是这样的:面试
在事务A修改数据以后提交数据以前,这时另外一个事务B来读取数据,若是不加控制,事务B读取到A修改过数据,以后A又对数据作了修改再提交,则B读到的数据是脏数据,此过程称为脏读Dirty Read。redis
一个事务内在读取某些数据后的某个时间,再次读取之前读过的数据,却发现其读出的数据已经发生了变动、或者某些记录已经被删除了。sql
事务A在按查询条件读取某个范围的记录时,事务B又在该范围内插入了新的知足条件的记录,当事务A再次按条件查询记录时,会产生新的知足条件的记录(幻行 Phantom Row)
shell
SQL实现了四个标准的隔离级别,每一种级别都规定了一个事务中所作的修改,哪些在事务内和事务间是可见的,哪些是不可见的。低级别的隔离级通常支持更高的并发处理,并拥有更低的系统开销。
各个隔离级别能够不一样程度的解决脏读、不可重复读、幻读。隔离级别各有所长,没有完美的解决方案,脱离业务场景谈具体实施都是耍流氓。
MySQL中InnoDB和NDB Cluster存储引擎提供了事务处理能力,以及其余支持事务的第三引擎。
MySQL默认采用自动提交AUTOCOMMIT
模式。也就是说,若是不是显式地开始一个事务,则每一个查询都被看成一个事务执行提交操做。
对于MyISAM或者内存表这些事务型的表,修改AUTOCOMMIT
不会有任何影响。对这类表来讲,没有COMMIT
或者ROLLBACK
的概念,也能够说是至关于一直处于AUTOCOMMIT
启用的模式。
尽可能不要再同一个事务中使用多种存储引擎,MySQL服务器层无论理事务,事务是由下层的存储引擎实现的。
若是在事务中混合使用了事务型和非事务型的表(例如InnoDB和MyISAM表),在正常提交的状况下不会有什么问题。
但若是该事务须要回滚,非事务型的表上的变动就没法撤销,这会致使数据库处于不一致的状态,这种状况很难修复,事务的最终结果将没法肯定。因此,为每张表选择合适的存储引擎很是重要。
最经常使用的存储引擎是InnoDB引擎和MyISAM存储引擎,InnoDB是MySQL的默认事务引擎。
查看数据库表当前支持的引擎 :
show table status from 'your_db_name' where name='your_table_name'; 查询结果表中的`Engine`字段指示存储引擎类型。
InnoDB是MySQL的默认「事务引擎」,被设置用来处理大量短时间(short-lived)事务,短时间事务大部分状况是正常提交的,不多会回滚。
更多InnoDB事务模型相关,参考MySQL官方手册,这里贴一下连接:https://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-model.html
现代MySQL版本中的InnoDB在历史上叫InnoDB plugin,这个MySQL插件在2008年被开发出来,直到2010在Oracle收购了Sun公司后,发布的MySQL5.5才正式使用InnoDB plugin替代了旧版本的InnoDB,至此 「备胎」成功转正成为MySQL的御用引擎而再也不是插件,你看一个插件都这么努力。
采用多版本并发控制(MVCC,MultiVersion Concurrency Control)来支持高并发。而且实现了四个标准的隔离级别,经过间隙锁next-key locking
策略防止幻读的出现。
引擎的表基于聚簇索引创建,聚簇索引对主键查询有很高的性能。不过它的二级索引secondary index
非主键索引中必须包含主键列,因此若是主键列很大的话,其余的全部索引都会很大。所以,若表上的索引较多的话,主键应当尽量的小。另外InnoDB的存储格式是平台独立。
InnoDB作了不少优化,好比:磁盘读取数据方式采用的可预测性预读、自动在内存中建立hash索引以加速读操做的自适应哈希索引(adaptive hash index),以及可以加速插入操做的插入缓冲区(insert buffer)等。
InnoDB经过一些机制和工具支持真正的热备份,MySQL的其余存储引擎不支持热备份,要获取一致性视图须要中止对全部表的写入,而在读写混合场景中,中止写入可能也意味着中止读取。
MyISAM是MySQL 5.1及以前的版本的默认的存储引擎。MyISAM提供了大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM不「支持事务和行级锁」,对于只读数据,或者表比较小、能够容忍修复操做,依然可使用它。
MyISAM「不支持行级锁而是对整张表加锁」。读取时会对须要读到的全部表加共享锁,写入时则对表加排它锁。但在表有读取操做的同时,也能够往表中插入新的记录,这被称为并发插入。
MyISAM表能够手工或者自动执行检查和修复操做。可是和事务恢复以及崩溃恢复不一样,可能致使一些「数据丢失」,并且修复操做是很是慢的。
对于MyISAM表,即便是BLOB
和TEXT
等长字段,也能够基于其前500个字符建立索引,MyISAM也支持「全文索引」,这是一种基于分词建立的索引,能够支持复杂的查询。
若是指定了DELAY_KEY_WRITE
选项,在每次修改执行完成时,不会当即将修改的索引数据写入磁盘,而是会写到内存中的键缓冲区,只有在清理键缓冲区或者关闭表的时候才会将对应的索引块写入磁盘。这种方式能够极大的提高写入性能,可是在数据库或者主机崩溃时会形成「索引损坏」,须要执行修复操做。
说了这么多估计看一眼也没记住,给你一张表,简单罗列两种引擎的主要区别,以下图。
MySQL还支持其余一些存储引擎,好比memory引擎、NDB集群引擎、CSV引擎,因为这些引擎没有上述InnoDB 和MyISAM 经常使用,这里不做介绍,感兴趣能够去翻MySQL文档了解。这里一样给出官方连接:https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html
这一篇是MySQL基础篇,我力求用通俗易懂和图表结合的形式给你们梳理这块知识,越是基础和底层的知识越容易被考察掌握程度,以上知识点均可能成为面试中的一个考察点,相信看完对MySQL事务和存储引擎应该有一个比较完整的理解。
最后,感谢各位的阅读,文章的目的是分享对知识的理解,若文中出现明显纰漏也欢迎指出,咱们一块儿在探讨中学习。
https://book.douban.com/subject/23008813/
https://juejin.im/post/5c519bb8f265da617831cfff#comment
https://tech.meituan.com/2014/08/20/innodb-lock.html
https://blog.csdn.net/shellching/article/details/8106156
https://coolshell.cn/articles/6790.html
https://zhuanlan.zhihu.com/p/29166694
https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html
https://www.zhihu.com/question/27876575
https://www.runoob.com/mysql/mysql-transaction.html
https://blog.csdn.net/qq_35642036/article/details/82820178?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
https://github.com/CyC2018/CS-Notes/blob/master/notes/MySQL.md#b-tree-%E5%8E%9F%E7%90%86
更多精彩原创关注公众号「后端技术学堂」大厂程序员,十年多编程学习经验,用通俗易懂的方式与你分享技术学习和程序员的那些事。
在公众号回复「资源」各类你想要都在里面。
我用大数据分析了一线城市1000多份岗位招聘需求,告诉你如何科学找工做
很是详细的 Linux C/C++ 学习路线总结!已拿腾讯offer
腾讯后台开发面试笔试C++知识点参考笔记
还能这么玩?我用VsCode画类图、流程图、时序图、状态图不要太爽!
面试官:你会几种redis分布式锁?我会三种!
最详细的我的博客教程搭建教程GithubPages+Jekyll 简约风格博客