为了便于分析,我来把这个问题简化一下,假设有以下的两张表 t1 和 t2,其中表 t1 使用 Memory 引擎, 表 t2 使用 InnoDB 引擎。

CREATE TABLE t1 (id int PRIMARY KEY,c int
) ENGINE = Memory;CREATE TABLE t2 (id int PRIMARY KEY,c int
) ENGINE = innodb;INSERT INTO t1
VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5),(6, 6),(7, 7),(8, 8),(9, 9),(0, 0);INSERT INTO t2
VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5),(6, 6),(7, 7),(8, 8),(9, 9),(0, 0);

然后,我分别执行 select * from t1 和 select * from t2。

select * from t1
id   c
1   1
2   2
3   3
4   4
5   5
6   6
7   7
8   8
9   9
0   0
select * from t2
id   c
0   0
1   1
2   2
3   3
4   4
5   5
6   6
7   7
8   8
9   9

可以看到,内存表 t1 的返回结果里面 0 在最后一行,而 InnoDB 表 t2 的返回结果里 0 在第一行。

出现这个区别的原因,要从这两个引擎的主键索引的组织方式说起。

表 t2 用的是 InnoDB 引擎,它的主键索引 id 的组织方式,你已经很熟悉了:InnoDB 表的数据就放在主键索引树上,主键索引是 B+ 树。所以表 t2 的数据组织方式如下图所示


主键索引上的值是有序存储的。在执行 select * 的时候,就会按照叶子节点从左到右扫描,所以得到的结果里,0 就出现在第一行。

与 InnoDB 引擎不同,Memory 引擎的数据和索引是分开的。我们来看一下表 t1 中的数据内容。

可以看到,内存表的数据部分以数组的方式单独存放,而主键 id 索引里,存的是每个数据的位置。主键 id 是 hash 索引,可以看到索引上的 key 并不是有序的。

在内存表 t1 中,当我执行 select * 的时候,走的是全表扫描,也就是顺序扫描这个数组。因此,0 就是最后一个被读到,并放入结果集的数据。

可见,InnoDB 和 Memory 引擎的数据组织方式是不同的:
InnoDB 引擎把数据放在主键索引上,其他索引上保存的是主键 id。这种方式,我们称之为索引组织表(Index Organizied Table)。
而 Memory 引擎采用的是把数据单独存放,索引上保存数据位置的数据组织形式,我们称之为堆组织表(Heap Organizied Table)。

从中我们可以看出,这两个引擎的一些典型不同:
1 InnoDB 表的数据总是有序存放的,而内存表的数据就是按照写入顺序存放的

2 当数据文件有空洞的时候,InnoDB 表在插入新数据的时候,为了保证数据有序性,只能在固定的位置写入新值,而内存表找到空位就可以插入新值

3 数据位置发生变化的时候,InnoDB 表只需要修改主键索引,而内存表需要修改所有索引;

4 InnoDB 表用主键索引查询时需要走一次索引查找,用普通索引查询的时候,需要走两次索引查找。而内存表没有这个区别,所有索引的“地位”都是相同的

5 InnoDB 支持变长数据类型,不同记录的长度可能不同;内存表不支持 Blob 和 Text 字段,并且即使定义了 varchar(N),实际也当作 char(N),也就是固定长度字符串来存储,因此内存表的每行数据长度相同

由于内存表的这些特性,每个数据行被删除以后,空出的这个位置都可以被接下来要插入的数据复用。比如,如果要在表 t1 中执行:


delete from t1 where id=5;
insert into t1 values(10,10);
select * from t1;
id   c
1   1
2   2
3   3
4   4
10  10
6   6
7   7
8   8
9   9
0   0

就会看到返回结果里,id=10 这一行出现在 id=4 之后,也就是原来 id=5 这行数据的位置。需要指出的是,表 t1 的这个主键索引是哈希索引,因此如果执行范围查询,比如


select * from t1 where id<5;

是用不上主键索引的,需要走全表扫描。你可以借此再回顾下第 4 篇文章的内容。那如果要让内存表支持范围扫描,应该怎么办呢 ?

总结

  • 内存表的数据顺序和写入顺序是一样的
  • 内存表的每行数据长度相同
  • 内存表默认用的是哈希索引
  • 不建议在生产环境使用内存表

思考

  • 内存表的使用场景是什么?

内存表与 InnoDB表对比相关推荐

  1. mysql 压缩表_MySQL InnoDB 表压缩(行格式压缩)

    MySQL InnoDB支持数据压缩,有两种数据压缩方式,第一种为表压缩,通常也称之为行格式压缩,另外一种是页压缩,页压缩对操作系统及文件系统有一定的要求.本文主要介绍表压缩(行格式压缩)的原理及使用 ...

  2. mysql 创建 innodb_MySQL InnoDB 创建 InnoDB 表

    要创建 InnoDB 表,可以使用 CREATE TABLE 语句 CREATE TABLE t1 (a INT, b CHAR (20), PRIMARY KEY (a)) ENGINE=InnoD ...

  3. MySQL(九):InnoDB 表空间(Tables)

    本节着重分析一下表空间,通过本节我们将清楚以下几个问题: 1.什么是表空间(Tablespace)? 2.InnoDB 存储引擎有哪些表空间(Tablespace)? 3.InnoDB 存储引擎中的表 ...

  4. 《MYSQL是怎样运行的》笔记|配置文件|系统变量|字符集|InnoDB存储结构|数据页结构|索引结构与使用|数据目录|表空间|连表原理|查询优化|BufferPool|事务|redo与undo|锁

    <MYSQL是怎样运行的>笔记 前记: 历时15天,笔记+看书.完成于2022.2.5. 本书是讲具体的数据库实现,而数据库系统概念见:https://blog.csdn.net/qq_4 ...

  5. mysql innodb 表数据压缩

    记得一次面试中,面试官问我是否知道表的压缩,这个时候我才知道mysql有个表压缩这么个功能,今天试用下看看表的压缩率怎么样. 这里分两个部分说明,第一部分:官方文档说明:第二部分:具体实例测试. [第 ...

  6. 使用单个innodb表,实现锁,防止游戏被刷物品或者其它资源!

    webgame经常面临某个模块被多次并发提交刷物品或者经验金钱,通常使用把相关该改为innodb表加事务,但这样,会使数据库服务器内存消耗变得十分恐怖,实际使用一个表就可以实现锁了. <?php ...

  7. mysql表空间权限_MySQL InnoDB表空间加密示例详解

    前言 从 MySQL5.7.11开始,MySQL对InnoDB支持存储在单独表空间中的表的数据加密 .此功能为物理表空间数据文件提供静态加密.该加密是在引擎内部数据页级别的加密手段,在数据页写入文件系 ...

  8. mysql 查看表v空间自增涨_MySQL InnoDB表空间加密

    从 MySQL5.7.11开始,MySQL对InnoDB支持存储在单独表空间中的表的数据加密 .此功能为物理表空间数据文件提供静态加密.该加密是在引擎内部数据页级别的加密手段,在数据页写入文件系统时加 ...

  9. MYSQL 的静态表和动态表的区别, MYISAM 和 INNODB 的区别

    MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然性能极佳,但却有一个缺点 ...

最新文章

  1. comp313 formal methods lec1
  2. diff命令输出格式解读
  3. Jenkins 基本概念与简介
  4. Oracle PL/SQL语言初级教程
  5. 对比俩个字符串的相似度
  6. Linux将硬盘转化为pv,Linux扩展硬盘 物理卷(PV) 卷组(VG) 逻辑卷(LV)
  7. 关于qt中的tr( )函数
  8. 语法制导定义 SDD
  9. BizTalk Server 2010新功能介绍(四):基于安全连接的FTP适配器
  10. 生成工资条 恢复工资表 宏 巨集 vba
  11. 计算机科学与技术导论课论文题目,优秀计算机专业导论论文题目 计算机专业导论论文题目哪个好...
  12. Nmap 中的各种端口扫描技术
  13. Tupper‘s Self-Referential Formula 塔珀自指公式
  14. 看脸的世界:牙齿整齐找工作更容易
  15. Mac OS开发之icns文件
  16. 《PHASEN:A Phase and Harmonics-Aware Speech Enhancement Network》Pytorch代码学习Ⅱ
  17. MATLAB画心形立体图
  18. 解决office,word奔溃的问题
  19. 使用R语言进行协整关系检验
  20. 0基础怎么学游戏建模?

热门文章

  1. 网页视频之win7家庭版配置IIS
  2. LED显示驱动(六):LED显示设备显示单层图片调试(DE驱动测试)
  3. “后序遍历二叉运算树进行Lambda演算的化简”带来的联系
  4. 群签名和环签名的区别_Monero技术详解(三):核心技术—环签名(1)
  5. sap 中migo收货自动打印smartform_EWM MES/ERP集成 生产收货的几种方式
  6. 安装指定的vue-router版本
  7. python中自定义类中的self_学习python第52天
  8. python函数和代码复用思维导图_Python语言程序---代码复用与函数递归(二)
  9. mysql 时间戳截断_列的Mysql时间戳数据被截断
  10. qt web混合编程_基于Qt与MATLAB的混合编程技术