目录
memory 引擎
memory 表结构示意图
memory表的特点
- Memory 引擎的数据和索引是分开的
- 内存表的数据部分以数组的方式单独存放,而主键 id 索引里,存的是每个数据的位置(数组的下标)。主键 id 是 hash 索引,是无序的
- 数据在数组内的排列顺序是,数据的插入顺序
- Memory 引擎采用的是把数据单独存放,索引上保存数据位置的数据组织形式,我们称之为堆组织表(Heap Organizied Table)。
- 内存表插入数据的时候,只要数组中有位置就可以插入
- 数据在数组中的位置发成变化后,主键id索引需要 reset hash
- 由于数据存储在内存的数组中,回表操作的时间复杂度是 O(1) ,而 innodb 的是 O(log2M)。
- 内存表不支持 Blob 和 Text 字段,并且即使定义了 varchar(N),实际也当作 char(N),也就是固定长度字符串来存储,因此内存表的每行数据长度相同。
在memory表上创建 B-Tree 索引
内存表也是支 B-Tree 索引的。在 id 列上创建一个 B-Tree 索引,SQL 语句可以这么写:
alter table t1 add index a_btree_index using btree (id);
结构图
为什么不建议在生产环境使用 memory 引擎的表
锁粒度
memory 表不支持行数,并发度不如 innodb 表
数据持久化问题
内存表的数据都保存在内存中,mysql重启的时候数据会丢失
主从数据同步问题
如果从库异常宕机了,内存表数据丢失了。这时主库同步给从库一条 binlog,update 语句,这时 从库应用线程就会报错“找不到要更新的行”,就是导致主从同步停止。如果这时发生主从切换的话,客户端会看到,表 t1 的数据丢失了。
在双M高可用架构中,更诡异的现象
如果备库异常重启了,重启后的备库会在 binlog 里面记录 delete 内存表数据的sql。这条 binlog 会被同步到主库,并删除掉内存表的记录。这时从 client 端看到的就是,数据库运行正常,但是表数据突然没有了“卧了个槽”