1. 简单了解什么是存储引擎?
相信很多人在听到存储引擎这个名字的时候可能会有些疑惑,听着名字就觉得有些难,导致很多人没有兴趣了解它,那么它这究竟是个什么东西?
我来说明一个场景,大家就能大概明白它是做什么用的了。
我们都知道,既然是数据库,我们就是用来存储数据的,数据库中会有很多的表,那么各位有没有想过数据库底层究竟是以什么样的格式存储这些表的数据的呢?
这就会用到我们存储引擎,存储引擎在以前叫做表处理器,是后来才改名叫存储引擎的,它的功能就是接收收到的指令,然后对表中的数据进行读写操作。你可以把它理解为存储数据库的表时表的类型,在MySQL数据库中,有很多的存储引擎,它们在存储数据库的表时存储格式也是不一样的。
举个栗子,假设我们的学生表 t_student 使用了A存储引擎,那么底层存储学生表信息时采用了 .txt 文本文件的格式进行存储;我们的用户表 t_user 使用了B存储引擎,那么底层在存储用户表中的信息时会采用 .doc Word文档的形式存储。也就是说,存储引擎不同,数据库底层在存储这些表的数据的时候采用的存储格式也不相同,这样说各位应该就能理解了吧。
在 MySQL数据库中,有好多种存储引擎,这里我重点说明 InnoDB和MyISAM,这两种也是面试中经常问到的两种引擎,问的最多的也是这两种引擎的原理和区别。
2. InnoDB 引擎概述
(1)MySQL 自从 3.23.34 开始就包含了InnoDB引擎,在 5.5 的版本之后 InnoDB 成为了 MySQL 的默认存储引擎;
(2)InnoDB 引擎对于数据的增删改查都具有很好的性能支持;
(3)InnoDB 本身是为了处理巨大量的数据的最大性能而设计的, 当我们表中存储的数据非常非常多时,InnoDB 存储引擎能很好地发挥出它性能的优越性,这与它底层存储数据和索引的结构有关系。
(4)InnoDB 引擎还支持数据库表外键的功能。而且,InnoDB 引擎是MySQL数据库众多引擎中唯一一个支持事务的引擎,可以确保事务的完整提交(Commit)和回滚(Rollback)。在一般情况下,我们建表时都会使用InnoDB作为存储引擎,因为现在绝大多数业务都需要用到事务,而InnoDB引擎又是唯一一个支持事务的存储引擎。
(5)大家可能不知道,在数据库的底层,当你使用不同的存储引擎,它们底层在存储数据的时候生成的文件也是不同的,在8.0以后的版本中 ,InnoDB 存储引擎中数据文件就只有一个 表名.ibd 文件了,它里面不仅会存储表的结构以及表的数据,还有索引也会一并存入其中,生成一个文件,合三为一,这一点要记住,与下面我们要说的 MyISAM 引擎存储数据时文件的格式有别哦!
(6)正是由于 InnoDB 存储引擎将所有的信息存储到了一个数据文件中,所以在读取数据时,InnoDB 引擎不仅要缓存表的数据,还要缓存表的索引,表中的数据如果很多,那么索引占据内存也会很大,因此从另一方面来讲 InnoDB 引擎对内存要求较高,效率也会受内存的影响。
(7)此外,因为 InnoDB 存储引擎支持事务,所以当我们的数据库在受到网络波动或者服务器宕机等一系列不可控不过因素导致崩溃时,它就会开启事务保护功能,我们再次重启数据库服务器,它就会自动从上一次崩溃的时候重新恢复数据,正常运行,极大程度地保证了我们数据的安全性。
3. MyISAM 引擎概述
(1)MyISAM 引擎也是数据库中一个比较重要的引擎,它提供了大量的特性,全文索引,压缩,空间函数等,但不支持事务,行级锁,外键等功能。因此当服务器崩溃时,它就无法基于事务的功能保证数据的安全性,崩溃后数据也无法恢复。
(2)在5.5 版本之前,MyISAM 是数据库的默认存储引擎,到了5.5 版本之后才从 MyISAM 转换成了 InnoDB 。
(3)MyISAM 存储引擎中数据的优势是访问速度特别快,主要针对于对事务完整性没有要求的 SELECT与INSERT 两个操作。最形象的就是历史相关软件,我们可以向数据库中添加历史信息,查询浏览历史信息,但几乎不会去更新历史信息或者删除历史信息,否则不就成了纂改历史了吗。
(4)MyISAM 存储引擎中,它是有一个常量存储表中的数据量的,即 COUNT(*),因此他的时间复杂度为O(1);而我们的 InnoDB 存储引擎在去统计数据时,则是去一条数据一条数据的累加,是现用现算,因此时间复杂度为O(n),因此在数据量的统计上来说,MyISAM 引擎性能是高于 InnoDB 的。
(5)刚才我们提 InnoDB 引擎的时候他也说到了,它的数据文件适合成了一个文件,而 MyISAM 则没有,它是分成了三个文件,分别存储表的结构,表的数据以及表的索引。在底层形成的三个文件分别是 表名.frm(存储表结构),表名.MYD(存储表的数据),表名.MYI(存储索引)。
4. InnoDB 与 MyISAM 的一些区别
InnoDB 存储引擎与 MyISAM 的一些区别我直接放到下边了,重点记住我画线的五个;
这要是给大家来说说行表锁。
行表锁其实不难理解,我举个栗子各位就懂了。
假设现在有一张用户表,有张三和李四,如果我们采用的是 InnoDB 存储引擎,当我们对张三数据进行读写操作的时候,我们只会把张三这一行的数据锁起来,不让其他的线程的读写操作对我们造成干扰,但是如果有线程想要操作李四的信息,是完全可以的,因为李四的数据并没有被锁起来,我们锁住的就是张三这一行的数据;
而假如说我们采用的是 MyISAM 存储引擎,当我们对张三的数据进行读写操作的时候,会把整张用户表都锁起来,即便是有其他操作想要对李四进行读写操作也不行,必须等到张三的信息操作完成才可以,这样各位就能理解了吧!
其实这个行表锁有点类似于Java中的 HashTable与ConcurrentHashMap,HashTable就是操作时锁起来整个数据,不让其他线程进来,而ConcurrentHashMap 则是只锁我们链表的头节点,对其他哈希桶位元素的操作不影响,能够适应多线程并发操作。