知识点 | MySQL的IOT表和HEAP表有什么区别?

Posted 戏说数据那点事

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识点 | MySQL的IOT表和HEAP表有什么区别?相关的知识,希望对你有一定的参考价值。

啥是IOT表?
Index Organized table by itself is a B-tree index. Index key is the primary key and the rest of columns are index values.The rows are stored in the primary key order. IOT provides fast access to a specific row by primary ke or the prefix of primary key.
Any insert/update/delete will cause the IOT rebuilt, therefore use IOT only when data is rarely changed.
IOT cannot contain virtual columns.

简译一下:
索引组织表就是一个B树索引。索引键是主键,其余列是索引值,行按主键顺序存储。通过主键或主键的前缀可对特定行的快速访问。
任何insert/update/delete都将导致IOT重构建,因此只有在数据很少更改时才使用索引组织表。
索引组织表不能包含虚拟列。

啥是HEAP表?
As indicated by the name, MEMORY tables are stored in memory. They use hash indexes by default, which makes them very fast, and very useful for creating temporary tables. However, when the server shuts down, all rows stored in MEMORY tables are lost. The tables themselves continue to exist because their definitions are stored in .frm files on disk, but they are empty when the server restarts.MEMORY tables cannot contain BLOB or TEXT columns.The server needs sufficient memory to maintain all MEMORY tables that are in use at the same time.To free memory used by a MEMORY table when you no longer require its contents, you should execute DELETE or TRUNCATE TABLE, or remove the table altogether using DROP TABLE.

The MEMORY storage engine creates tables with contents that are stored in memory. Formerly, these were known as HEAP tables. MEMORY is the preferred term, although HEAP remains supported for backward compatibility. Each MEMORY table is associated with one disk file. The filename begins with the table name and has an extension of .frm to indicate that it stores the table definition.

简译一下:
内存表存储在内存中,默认情况下使用哈希索引,这使得数据访问非常快,对于创建临时表非常有用。当服务器关闭时,内存表中存储的所有行都会丢失。表本身继续存在,因为它们的定义存储在磁盘上的.frm文件中,但在服务器重启时它们是空的。内存表不能包含BLOB或文本列。服务器需要足够的内存来维护同时使用的所有内存表。当不再需要内存表的内容时,要释放内存表所使用的内存,应该执行DELETE或TRUNCATE table,或者使用DROP table将该表一起删除。

内存存储引擎创建包含存储在内存中的表。以前被称为堆表。内存表向后兼容仍支持堆。每个内存表都与一个磁盘文件相关联。文件名以表名开头,扩展名为.frm,表示它存储表定义。

IOT表,大家使用create table命令时创建的都是索引组织表。
大家都很熟悉了,这里就不赘述。

那HEAP表适用在什么场景下?
HEAP表使用哈希散列索引把数据保存在内存中,HEAP表是访问数据速度最快的mysql表,适合缓存中小型数据库。但如MySQL或者服务器重新启动,表中数据将会丢失。

如何创建内存表?
创建内存表只需注明 ENGINE= MEMORY 即可,举个例子:
CREATE TABLE table_name (   
  id int(10) NOT NULL auto_increment COMMENT ‘ID’,   
  username varchar(36) default NULL,   
  UNIQUE KEY id (id)   
) ENGINE=MEMORY DEFAULT CHARSET=utf8;

或者
CREATE TABLE DB ( 
id int(11) default NULL, 
songname varchar(255) NOT NULL default ”, 
singer varchar(255) NOT NULL default ”, 
KEY songname (songname,singer
) TYPE=HEAP

注意:type=heap创建内存表的方式在5.2中将删除,后续版本均使用engine=memory方式。

HEAP表在使用上又有哪些限制呐?
1.内存表不支持事务 
2.内存表不支持BLOB/TEXT列 
3.内存表大小可用 max_heap_table_size 参数来设置 
4.内存表所使用的内存不回收,除非整个表删除
5.mysql启动时,能利用–init-file参数,从其它表取数据。INSERT INTO … SELECT or LOAD DATA INFILE
6.如果heap是复制的某数据表,则复制之后所有主键、索引、自增等格式将不复存在,需要重新添加主键和索引
7.一旦服务器重启,所有heap表数据丢失,但是heap表结构仍然存在,因为heap表结构是存放在实际数据库路径下的,不会自动删除。重启之后,heap将被清空,这时候对heap的查询结果都是空的
8.仅适合使用的场合。heap不允许使用xxxTEXT和xxxBLOB数据类型;只允许使用=和<=>操作符来搜索记录(不允许<、>、<=或>=);不支持auto_increment;只允许对非空数据列进行索引(not null)。
注意:
操作符 “<=>” 说明:NULL-safe equal.这个操作符和“=”操作符执行相同的比较操作,不过在两个操作码均为NULL时,其所得值为1而不为NULL,而当一个操作码为NULL时,其所得值为0而不为NULL。

另,需注意的一个场景是:
作mysql采用主从同步机制的时候,当master shutdown或restart时,slave中内存表中数据并不清空,只有当master重新启动后,第一次使用该内存表时,master向binlog中写入一条delete命令,slave才清空该表。 
原因很简单。
无论是基于STATEMENT还是基于ROW复制,都要在二进制日志中包含改变的数据。这就要求在主从机上数据必须一致。当重启从库的时候,你就会丢失内存表的数据,复制中断。

怎么办呢?

1.使用Innodb表代替
innodb表也已经非常快,能满足业务性能需求,是在不行,可以通过高可用性读写架构/缓存进行架构层解决。

2.在复制中忽略内存表
如果不是非常有必要的话,忽略复制内存表,使用这个选项
replicate-ignore-table=db.memory_table
注意:STATEMENT复制,不要使用insert … select 添加数据到内存表。如果要使用insert … select,从机上的表将会是空的,甚至某些时候,内存表根本不会复制到从机上。还有一种解决办法是在主从机上都部署上相同的计划任务,来刷新这个表。

3.谨慎重启从机

那么,对于重启造成的数据丢失,有以下的解决办法:

  1. 在任何查询之前,执行一次简单的查询,判断heap表是否存在数据,如果不存在,则把数据重新写入,或者DROP表重新复制某张表。这需要多做一次查询。不过可以写成include文件,在需要用该heap表的页面随时调用,比较方便。

  2. 对于需要该heap表的页面,在该页面第一次且仅在第一次查询该表时,对数据集结果进行判断,如果结果为空,则需要重新写入数据。这样可以节省一次查询。

  3. 更好的办法是在mysql每次重新启动时自动写入数据到heap,但是需要配置服务器,过程比较复杂,通用性受到限制。

【oracle 堆表(Heap Table)/索引组织表(Index Organization Table)/聚簇表(Cluster Table)传送门
http://blog.sina.com.cn/s/blog_776989950102w5z3.html

文章至此。



   

近期热文

你可能也会对以下话题感兴趣。点击链接便可查看。











以上是关于知识点 | MySQL的IOT表和HEAP表有什么区别?的主要内容,如果未能解决你的问题,请参考以下文章

mysql 内存表和一般表的区别

Netezza 中的表和外部表有啥区别?

关联表和常规表有啥区别?

PostgreSQL之堆表存储(Heap Table)

来自多表和计数的 mysql group_concat

MySQL inner join判断驱动表和被驱动表的一个例子