摘要:MySQL的存储引擎之MEMORY
MEMORY引擎在内存中创建表。由于数据是放在内存中的,所以访问速度非常快,但是硬件问题、断电或MySQL服务关闭等,表中数据就会丢失。因此MEMORY表主要用于临时用途、从其他表中提取数据的只读缓存等场景。
在MySQL 5.7里MEMORY引擎的特性如下:
| Feature | Support |
|---|---|
| B-tree indexes | Yes |
| Backup/point-in-time recovery (Implemented in the server, rather than in the storage engine.) | Yes |
| Cluster database support | No |
| Clustered indexes | No |
| Compressed data | No |
| Data caches | N/A |
| Encrypted data | Yes (Implemented in the server via encryption functions.) |
| Foreign key support | No |
| Full-text search indexes | No |
| Geospatial data type support | No |
| Geospatial indexing support | No |
| Hash indexes | Yes |
| Index caches | N/A |
| Locking granularity | Table |
| MVCC | No |
| Replication support (Implemented in the server, rather than in the storage engine.) | Limited (See the discussion later in this section.) |
| Storage limits | RAM |
| T-tree indexes | No |
| Transactions | No |
| Update statistics for data dictionary | Yes |
下面我们通过例子来看看
root@database-one 08:15: [gftest]> CREATE TABLE testmemory(
-> `eno` int(11) NOT NULL AUTO_INCREMENT,
-> `ename` varchar(10) DEFAULT NULL,
-> `age` int(11) DEFAULT NULL,
-> `sal` decimal(10,2) DEFAULT NULL,
-> `hiredate` date DEFAULT NULL,
-> `deptno` int(2) DEFAULT NULL,
-> PRIMARY KEY (`eno`)
-> ) ENGINE=memory;
Query OK, 0 rows affected (0.46 sec)
root@database-one 08:17: [gftest]> insert into testmemory select * from emp_copy;
Query OK, 40 rows affected (0.13 sec)
Records: 40 Duplicates: 0 Warnings: 0
root@database-one 08:17: [gftest]> select count(*) from testmemory;
+----------+
| count(*) |
+----------+
| 40 |
+----------+
1 row in set (0.01 sec)
root@database-one 08:17: [gftest]> show table status like 'testmemory' \G
*************************** 1. row ***************************
Name: testmemory
Engine: MEMORY
Version: 10
Row_format: Fixed
Rows: 40
Avg_row_length: 52
Data_length: 7046424
Max_data_length: 65431132
Index_length: 3019896
Data_free: 0
Auto_increment: 50
Create_time: 2020-03-01 08:17:05
Update_time: NULL
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.01 sec)
MEMORY表上也可以建索引,并且可以指定使用HASH索引还是BTREE索引,不指定时默认是HASH索引。
root@database-one 08:20: [gftest]> create index idx_testmemory_ename on testmemory(ename);
Query OK, 40 rows affected (0.11 sec)
Records: 40 Duplicates: 0 Warnings: 0
root@database-one 08:21: [gftest]> show index from testmemory \G
*************************** 1. row ***************************
Table: testmemory
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: eno
Collation: NULL
Cardinality: 40
Sub_part: NULL
Packed: NULL
Null:
Index_type: HASH
Comment:
Index_comment:
*************************** 2. row ***************************
Table: testmemory
Non_unique: 1
Key_name: idx_testmemory_ename
Seq_in_index: 1
Column_name: ename
Collation: NULL
Cardinality: 4
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: HASH
Comment:
Index_comment:
2 rows in set (0.03 sec)
root@database-one 08:21: [gftest]> drop index idx_testmemory_ename on testmemory;
Query OK, 40 rows affected (0.00 sec)
Records: 40 Duplicates: 0 Warnings: 0
root@database-one 08:23: [gftest]> create index idx_testmemory_ename using btree on testmemory(ename);
Query OK, 40 rows affected (0.01 sec)
Records: 40 Duplicates: 0 Warnings: 0
root@database-one 08:25: [gftest]> show index from testmemory \G
*************************** 1. row ***************************
Table: testmemory
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: eno
Collation: NULL
Cardinality: 40
Sub_part: NULL
Packed: NULL
Null:
Index_type: HASH
Comment:
Index_comment:
*************************** 2. row ***************************
Table: testmemory
Non_unique: 1
Key_name: idx_testmemory_ename
Seq_in_index: 1
Column_name: ename
Collation: A
Cardinality: NULL
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
2 rows in set (0.01 sec)
MEMORY表的数据是在内存中,但是表定义是落在磁盘上的,永久的,可以使用drop table删除。表定义文件名以表名开头,扩展名为.frm。
[root@database-one ~]# cd /home/mysql/gftest/ [root@database-one gftest]# ls -l testmemory* -rw-r----- 1 mysql mysql 8718 3月 1 08:23 testmemory.frm
因为MEMORY表中的数据会随着MySQL关闭释放掉,为了在MySQL启动时自动填充数据到表里,可以使用–init-file选项指定文件,在文件中用INSERT INTO … SELECT或LOAD DATA等来实现数据填充。
每个MEMORY表中可以放置的数据量最大上限,由max_heap_table_size限制,笔者环境里是96M。
root@database-one 08:44: [gftest]> show variables like 'max_heap_table_size'; +---------------------+-----------+ | Variable_name | Value | +---------------------+-----------+ | max_heap_table_size | 100663296 | +---------------------+-----------+ 1 row in set (0.01 sec)
在创建MEMORY表的时候,也可以通过MAX_ROWS指定表的最大行数。
MEMORY表还有几个特点:
- MEMORY表的空间是以小块的形式分配的。
- MEMORY表使用固定长度的行存储格式。可变长度类型(如VARCHAR)也是用固定长度存储的。
- MEMORY表不支持BLOB和TEXT。
- MEMORY表支持AUTO_INCREMENT列。
© 2020, morinson. 版权所有. 欢迎转载,但请保留作者及出处。