MySQL学习笔记04

六、MySQL表类型(存储引擎)的选择

和大多数数据库不同,MySQL中有一个存储引擎的概念,针对不同的存储需求可以选择最优的存储引擎。

6.1 MySQL存储引擎概述

插件式存储引擎是MySQL数据库最重要的特性之一,用户可以根据应用的需要选择如何存储和牵引数据、是否使用事务等。MySQL默认支持多种存储引擎,以适用于不同领域的数据库应用需要,用户可以选择不同的存储引擎提高应用的效率,提供灵活的存储。

MySQL5.7支持的存储引擎包括InnoDB、MyISAM、MEMORY、CSV、BLACKHOLE、ARCHIVE、MERGE(MRG_MyISAM)、FEDERATED、EXAMLE、NDB等,其中InnoDB

和NDB提供事务安全表,其他存储引擎都是非事务安全表。

创建新表时如果不指定存储引擎,那么系统就会使用默认存储引擎,MySQL5.5之前的默认存储引擎是MyISAM,5.5版本之后改为InnoDB。如果要修改默认的存储引擎,可以在参数文件中设置default_storage_engine。

查看当前的默认存储引擎,可以使用以下命令:

mysql> show variables like 'default_storage_engine';
+------------------------+--------+
| Variable_name          | Value  |
+------------------------+--------+
| default_storage_engine | InnoDB |
+------------------------+--------+
1 row in set, 1 warning (0.01 sec)

可以通过一下方法查询当前数据库支持的存储引擎:

mysql> show engines \G;
*************************** 1. row ***************************
      Engine: MEMORY
     Support: YES
     Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 2. row ***************************
      Engine: MRG_MYISAM
     Support: YES
     Comment: Collection of identical MyISAM tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 3. row ***************************
      Engine: CSV
     Support: YES
     Comment: CSV storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 4. row ***************************
      Engine: FEDERATED
     Support: NO
     Comment: Federated MySQL storage engine
Transactions: NULL
          XA: NULL
  Savepoints: NULL
*************************** 5. row ***************************
      Engine: PERFORMANCE_SCHEMA
     Support: YES
     Comment: Performance Schema
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 6. row ***************************
      Engine: MyISAM
     Support: YES
     Comment: MyISAM storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 7. row ***************************
      Engine: InnoDB
     Support: DEFAULT
     Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
          XA: YES
  Savepoints: YES
*************************** 8. row ***************************
      Engine: ndbinfo
     Support: NO
     Comment: MySQL Cluster system information storage engine
Transactions: NULL
          XA: NULL
  Savepoints: NULL
*************************** 9. row ***************************
      Engine: BLACKHOLE
     Support: YES
     Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 10. row ***************************
      Engine: ARCHIVE
     Support: YES
     Comment: Archive storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 11. row ***************************
      Engine: ndbcluster
     Support: NO
     Comment: Clustered, fault-tolerant tables
Transactions: NULL
          XA: NULL
  Savepoints: NULL
11 rows in set (0.00 sec)

ERROR:
No query specified

其中support不同值的含义分别为:DEFAULT——支持并启用,并且为默认引擎;YES——支持并启用;NO——不支持;DISABLED——支持,但是数据库启动的时侯被禁用。

在创建新表时,可以通过增加ENGINE关键字设置新建表的存储引擎。

例如,表ai的存储引擎是MyISAM,而country表的存储引擎是InnoDB:

mysql> CREATE TABLE ai (i bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (i)) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> CREATE TABLE country (country_id smallint UNSIGNED NOT NULL AUTO_INCREMENT,
country VARCHAR(50) NOT NULL,
last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (country_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected, 1 warning (0.02 sec)

也可以使用ALTER TABLE语句,将一个存在的表修改成其他的存储引擎。

例如:将表ai从MyISAM存储引擎修改到InnoDB存储引擎:

mysql> ALTER TABLE ai ENGINE=InnoDB;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SHOW CREATE TABLE ai \G;
*************************** 1. row ***************************
       Table: ai
Create Table: CREATE TABLE `ai` (
  `i` bigint NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`i`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
1 row in set (0.00 sec)

ERROR:
No query specified

注:修改表的存储引擎需要锁表并复制数据,对于线上环境的表进行这个操作非常危险,除非非常了解可能造成的影响,否则在线上环境请使用其他方式。例如precona的OSC工具。

6.2 各种存储引擎的特性

表6-1 常用存储引擎的对比
特点MyISAMMemoryInnoDBArchiveNDB
B树索引支持支持支持————
备份/时间点恢复支持支持支持支持支持
支持集群————————支持
聚簇索引————支持————
数据压缩支持——支持——
数据缓存——N/A支持——支持
数据加密支持支持支持支持
支持外键————支持——支持
全文索引支持——支持————
地理坐标数据类型支持——支持支持
地理坐标索引支持——支持————
哈希索引——支持————支持
索引缓存支持N/A支持——支持
锁粒度表级表级行级行级行级
MVCC多版本控制————支持————
支持复制支持有限支持支持支持支持
存储限制256TBRAM64TBNone384EB
T树索引————————支持
支持事务————支持——支持
统计信息支持支持支持支持支持

下面将重点介绍重用的4种存储引擎:MyISAM、MEMORY、InnoDB和Archive。

6.2.1 MyISAM

MyISAM是MySQL5.5之前版本的默认存储引擎,MyISAM既不支持事务,也不支持外键,在5.5版本之前的版本中,在某些场景中相对InnoDB的访问速度有明显优势,对事物完整性没有要求,以SELECT、INSERT为主的应用可以使用这个引擎来创建表。MySQL5.6之后,MyISAM越来越少使用。

每个MyISAM在磁盘上存储为3个文件,其文件名和表名都相同,但扩展名分别如下:

(1).fim(存储表定义)

(2).MYD(MYData,存储数据)

(3).MYI(MYIndex,存储索引)

数据文件和索引文件可以放置在不同的目录,平均分布IO,获得更快的速度。

要指定索引文件和数据文件的路径,需要在创建表的时候通过DATA DIRECTORY和INDEX DIRECTORY语句指定,不同的MyISAM表的索引文件和数据文件可以放置到不同的路径下,文件路径需要是绝对路径,并且具有访问权限。

MyISAM类型的表可能会损坏,原因多种多样,损坏后的表可能不能被访问,会提示需要修复或者访问后返回错误的结果。MyISAM类型的表提供修复的工具,可以用CHECK TABLE语句来检查MyISAM表,并用REPAIR TABLE语句修复。表损坏可能导致数据库异常重新启动,需要尽快修复并尽可能确认损坏的原因。

MyISAM类型的表支持3中不同的存储格式,分别如下:

(1)静态(固定长度)表;

(2)动态表;

(3)压缩表。

静态表是默认的存储格式,其中的字段都是非变长字段,这样每个记录都是固定长度的,这种存储方式优点是存储非常迅速,容易缓存,出现故障容易恢复;缺点是占用的空间通常比动态表多。

静态表的数据在存储时会按照列的宽度定义不足空格,但是在应用访问时并不会得到这些空格,这些空格在返回给应用之前就已经去掉。

如果需要保存的内容后面本来就有空格,那么在返回结果的时候也会被去掉,开发人员在编写程序时需要特别注意这一点。

动态表中包含变长字段,记录不是固定长度的,这样存储的优点是占用的空间相对较少,但是频繁更新和删除记录会产生碎片,需要定期执行OPTIMIZE TABLE语句或myisamchk-r命令来改善性能,并且动态表在出现故障时恢复相对较困难。

压缩表由myisampack工具创建,占用非常小的磁盘空间。因为每个记录都是被单独压缩的,所以只有非常小的访问开支。

6.2.2 InnoDB

InnoDB作为MySQL5.5之后的默认引擎,提供了具有提交、回滚和崩溃恢复能力的事务安全保障,同时提供了更小的锁粒度和更强的并发能力,拥有自己独立的缓存和日志,在MySQL5.6和5.7版本中性能有较大的提升。

对比MyISAM存储引擎,InnoDB会占用更多的磁盘空间以保留数据和索引。但大多数场景下,InnoDB都会是更好的选择。

下面重点介绍InnoDB类型的表在使用过程中不同于其他存储引擎的表的特点:

1.自动增长列

InnoDB表的自动增长列可以手工插入,但是插入的值如果是空,则实际插入的将是自动增长后的值。

mysql> create table autoincre_demo(i smallint not null auto_increment,name varchar(10),primary key(i))engine=innodb;
Query OK, 0 rows affected (0.03 sec)

mysql> insert into autoincre_demo values(null,'1'),(2,'2'),(null,'3');
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from autoincre_demo;
+---+------+
| i | name |
+---+------+
| 1 | 1    |
| 2 | 2    |
| 3 | 3    |
+---+------+
3 rows in set (0.00 sec)

可以通过ALTER TABLE *** AUTO_INCREMENT=n语句来强制设置自动增长列的初始值,默认从1开始,但是在MySQL8.0之前,对于InnoDB存储引擎来说,这个值只保留在内存中,如果数据库重新启动,那么这个值就会丢失,数据库将会自动将AUTO_INCREMENT重置为自增列当前存储的最大值+1,这可能会导致数据库重启之后,自增列记录的值和预期不符,从而导致在某些历史数据归档或者复制环境中发生数据冲突。

在MySQL8.0中,这个bug得到了修复。具体实现方式是将自增主键的计数器持久化到REDO LOG中,每次计数器发生改变,都会将其写入到REDO LOG。如果数据库发生重启,InnoDB会根据REDO LOG中的计数器信息来初始化其内存值。

可以使用LAST_INSERT_ID()查询当前线程最后插入记录使用的值,如果一次插入了多条记录,那么返回的是第一条记录使用的自动增长值,并且值得注意的是,如果认为指定自增列的值,那么LAST_INSERT_ID()的值不会更新。

对于InnoDB表,自动增长列必须被索引。如果是组合索引,也必须是组合索引的第一列,但是对于MyISAM表,自动增长列可以是组合索引的其他列,这样插入记录后,自动增长列是按照组合索引的前面几列进行排序后递增的。

例如,创建一个新的MyISAM表autoincre_demo,自动增长列d1作为组合索引的第二列,对该表插入一些记录后,可以发现自动增长列是按照组合索引的第一列d2进行排序后递增的。

mysql> create table autoincre_demo(d1 smallint not null auto_increment,d2 smallint not null,name varchar(10),index(d2,d1))engine=myisam;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into autoincre_demo(d2,name) values(2,'2'),(3,'3'),(4,'4'),(2,'2'),(3,'3'),(4,'4');
Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select * from autoincre_demo;
+----+----+------+
| d1 | d2 | name |
+----+----+------+
|  1 |  2 | 2    |
|  1 |  3 | 3    |
|  1 |  4 | 4    |
|  2 |  2 | 2    |
|  2 |  3 | 3    |
|  2 |  4 | 4    |
+----+----+------+
6 rows in set (0.00 sec)

2、外键约束

MySQL支持外键的常用存储引擎只有InnoDB,在创建外键时,要求父表必须有对应的索引,子表在创建外键时也会自动创建对应的索引。

下面是两个样例,country表是父表,country_id为主键索引,city表是子表,country_id字段为外键,对应于country表的主键country_id。

mysql> CREATE TABLE country(country_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
country VARCHAR(50) NOT NULL,
last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (country_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected, 1 warning (0.02 sec)

mysql> CREATE TABLE city(
city_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
city VARCHAR(50) NOT NULL,
country_id SMALLINT UNSIGNED NOT NULL,
last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (city_id),
KEY idx_fk_country FOREIGN KEY (country_id) REFERENCES country (country_id) ON DELETE RESTRICT ON UPDATE CASCADE
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

ERROR 1064 (42000): You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version 
for the right syntax to use near 
'FOREIGN KEY (country_id) REFERENCES country (country_id) ON DELETE RESTRICT ON U' 
at line 1

在创建索引时,可以指定在删除、更新父表时,对子表进行相应操作,包括RESTRICT、CASCADE、SET NULL和NO ACTION。其中RESTRICT和NO ACTION相同,是指限制在子表有关联记录的情况下父表不能更新;CASCADE表示父表在更新或者删除时,更新或删除子表对应记录;SET NULL则表示父表在更新或者删除的时候,子表对应的字段被SET NULL。选择后两种方式的时候要谨慎,可能会因为错误的操作导致数据的丢失。

当某个表被其他表创建了外键参照时,该表的对应索引或者主键禁止被删除。

在导入多个表的数据时,如果需要忽略表之前的导入顺序,可以暂时关闭外键的检查;同样在执行LOAD DATA和ALTER TABLE操作时,可以通过暂时关闭外键约束来加快处理的速度,关闭的命令是“SET FOREIGN_KEY_CHECKS=0”,执行完成后,通过执行“SET FOREIGN_KEY_CHECKS=1”语句改回原状态。

对于InnoDB类型的表,外键的信息可以通过使用show create table或者show table status命令显示。

mysql> show table status like 'country' \G
*************************** 1. row ***************************
           Name: country
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 0
 Avg_row_length: 0
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2024-02-01 22:31:41
    Update_time: NULL
     Check_time: NULL
      Collation: utf8mb3_general_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.00 sec)

注:外键需要注意的细节较多,一旦使用不当,可能会导致性能下降或者数据不一致的问题,尤其在OLTP类型的应用中,需要慎重使用外键。

3、主键和索引

不同于其他存储引擎,InnoDB的数据文件本身就是以聚簇索引的形式保存的,这个聚簇索引也被称为主索引,并且也是InnoDB表的主键,InnoDB表的每行数据都保存在主索引的叶子节点上。因此,所有InnoDB表都必须包含主键,如果创建表时没有显式指定主键,那么InnoDB存储引擎会自动创建一个长度为6个字节的long类型隐藏字段作为主键。

考虑到聚簇索引的特点和对于查询的优化效果,所有InnoDB表都应该显式地指定主键,一般来说,主键按下列原则来选择:

(1)满足唯一和非空约束;

(2)优先考虑使用最经常被当做查询条件的字段或者自增字段;

(3)字段值基本不会优先被修改;

(4)使用尽可能短的字段。

在InnoDB表上,除了主键之外的其他索引都叫做辅助索引或者二级索引,二级索引会指向主索引,并通过主索引获取最终数据。主键创建是否合理,会影响所有索引的效率。

4、存储方式

InnoDB存储表和索引有以下两种方式:

(1)使用共享表空间存储:这种方式创建的表的表结构保存在.frm文件中,数据和索引保存在innodb_data_home_dir和innodb_data_file_path定义的表空间中,可以是多个文件。

(2)使用多表空间存储:这种方式创建的表的表结构仍然保存在.frm文件中,但是每个表的数据和索引单独保存在.ibd中。如果是一个分区表,则每个分区对应单独的.ibd文件,文件名是:表名+分区名,可以在创建分区时指定每个分区的数据文件的位置,以此将表的IO均匀的分布在多个磁盘上。

使用共享表空间时,随着数据的不断增长,表空间的管理维护会变得越来越困难,一般都建议使用多表空间。

要使用多表空间的存储方式,需设置参数innodb_file_per_table,在MySQL5.7中,此参数默认设置为ON,即新建的表默认都是按照多表空间的方式创建。如果修改此参数为OFF,则新创建的表都会改为共享表空间存储,但已有的多表空间的表仍保持原来的访问方式。

可以通过下面的命令将共享表空间改为多表空间

SET GLOBAL innodb_file_per_table=1;
ALTER TABLE table_name ENGINE=InnoDB;

多表空间的数据文件没有大小限制,既不需要设置初始大小,也不需要设置文件的最大限制、扩展大小等参数。

对于使用多表空间特性的表,可以比较方便地进行单表备份和恢复操作,但是直接复制.ibd文件是不行的,因为没有共享表空间的数据字典信息,直接复制的.ibd文件和.frm文件恢复时是不能被正确识别的。但可以通过以下命令将备份恢复到数据库中。

ALTER TABLE tbl_name DISCARD TABLESPACE;
ALTER TABLE tbl_name IMPORT TABLESPACE;

注意:即便是在多表空间的存储方式下,共享表空间仍然是必须的,InnoDB把内部数据词典和在线重做日志放在这个文件中。

6.2.3 MEMORY

MEMORY存储引擎使用存在于内存中的内容来创建表,每个MEMORY表只实际对应一个磁盘文件,格式是.frm。MEMORY类型的表访问非常快,因为它的数据是放在内存中的,并且默认使用HASH索引,但是一旦服务关闭,表中的数据就会丢失掉。

在MEMORY表创建索引时,可以指定使用HASH索引还是BTREE索引:

create index men_hash USING HASH ON tab_memory(city_id);

在启动MySQL服务的时候使用--init-file选项,把INSERT INTO...SELECT或LOAD DATA INFILE这样的语句放入这个文件中,就可以在服务启动时从持久稳固的数据源装载表。

服务器需要足够的内存来维持所有在同一时间使用的MEMORY表,当不再需要MEMORY表的内容时,要释放被MEMORY表使用的内存,应该执行DELETE FROM或TRUNCATE TABLE,或者删除整个表(使用DROP TABLE操作)。

每个MEMORY表中可以防止的数据量的大小,受到max_heap_table_size系统变量的约束,这个系统变量的初始值是16MB,可以根据需要加大。此外,在定义MEMORY表时,可以通过MAX_ROWS子句指定表的最大行数。

MEMORY类型的存储引擎主要用于那些内容变化不频繁的代码表,或者作为统计操作的中间结果表,便于高效地对中间结果进行分析并得到最终的统计结果。对存储引擎为MEMORY的表进行更新操作要谨慎,因为数据并没有实际写入到磁盘中去,要对下次重新启动服务后如何获得这些修改后的数据有所考虑。

6.2.4 MERGE

MERGE存储引擎也被称为MRG_MyISAM,是一组MyISAM表的组合,这些MyISAM表必须结构完全相同,MERGE表本身并没有数据,对MERGE类型的表可以进行查询、更新、删除操作,这些操作实际上是对内部的MyISAM表进行的。对于MERGE类型表的插入操作,是通过INSERT_METHOD子句定义插入的表,可以有3个不同的值,使用FIRST或LAST值使得插入操作被相应地作用在第一个或最后一个表上,不定义这个子句或者定义为NO,表示不能对这个MERGE表执行插入操作。

可以对MERGE表进行DROP操作,这个操作只是删除MERGE的定义,对内部的表没有任何影响。

MERGE表在磁盘上保留两个文件,文件名以表的名字开始,一个.frm文件存储表定义,另一个.MRG文件包含组合表的信息,包括MERGE表由哪些表组成、插入新的数据时的依据。可以通过修改.MRG文件来修改MERGE表,但是修改后要通过FLUSH TABLES刷新。

mysql> create table payment_2006(country_id smallint,payment_date datetime,
amount DECIMAL(15,2),KEY idx_fk_country_id(country_id)
)engine=myisam;
Query OK, 0 rows affected (0.07 sec)

mysql> create table payment_2007(country_id smallint,payment_date datetime,
amount DECIMAL(15,2),KEY idx_fk_country_id(country_id)
)engine=myisam;
Query OK, 0 rows affected (0.01 sec)


mysql> create table payment_all(country_id smallint,payment_date datetime,
amount DECIMAL(15,2),KEY idx_fk_country_id(country_id)
)engine=merge union=(payment_2006,paymen_2007) 
INSERT_METHOD=LAST;
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO payment_2006 VALUES(1,'2006-05-01',100000),(2,'2006-08-15',150000);
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> INSERT INTO payment_2007 VALUES(1,'2007-02-20',250000),(2,'2007-07-15',220000);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM payment_2006;
+------------+---------------------+-----------+
| country_id | payment_date        | amount    |
+------------+---------------------+-----------+
|          1 | 2006-05-01 00:00:00 | 100000.00 |
|          2 | 2006-08-15 00:00:00 | 150000.00 |
+------------+---------------------+-----------+
2 rows in set (0.01 sec)

mysql> SELECT * FROM payment_2007;
+------------+---------------------+-----------+
| country_id | payment_date        | amount    |
+------------+---------------------+-----------+
|          1 | 2007-02-20 00:00:00 | 250000.00 |
|          2 | 2007-07-15 00:00:00 | 220000.00 |
+------------+---------------------+-----------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM payment_all;
ERROR 1168 (HY000): Unable to open underlying table
which is differently defined 
or of non-MyISAM type or doesn't exist

mysql> insert into payment_all values(3,'2006-02-01',112300);
ERROR 1168 (HY000): Unable to open underlying table 
which is differently defined or of non-MyISAM type 
or doesn't exist

mysql> select * from payment_2007;
+------------+---------------------+-----------+
| country_id | payment_date        | amount    |
+------------+---------------------+-----------+
|          1 | 2007-02-20 00:00:00 | 250000.00 |
|          2 | 2007-07-15 00:00:00 | 220000.00 |
+------------+---------------------+-----------+
2 rows in set (0.00 sec)

注:与书上不同,MySQL8.0.36中无法打开MERGE表(原因尚不知) 

MERGE表和分区表的区别,MERGE表不能智能将记录写到对应的表中,而分区表是可以的(分区功能在5.1版本中正式推出,目前比较完善)。通常使用MERGE表来透明地对多个表进行查询和更新操作,而对这种按照时间记录的操作日志表则可以透明地进行插入操作。

6.2.5 TokuDB

前面介绍的都是MySQL自带的存储引擎,除了这些外,还有一些常见的第三方存储引擎,在某些特定的应用中也广泛使用。比如列式存储引擎Infobright以及高写性能、高压缩的TokuDB。本节将简单介绍TokuDB。

TokuDB是一个高性能、支持事务处理的存储引擎,在MySQL5.6版本之前,可以安装到MySQL和MariaDB中,被Percona公司收购后,目前最新版本可以在Percona Server for MySQL之中使用。TokuDB存储引擎具有高扩展性、高压缩率、高效的写入性能,支持大多数在线DDL操作。最新版本已经开源,可以从Percona官网下载和安装(https://www.percona.com/

针对TokuDB存储引擎的主要特性,TokuDB网站公布了这款优秀存储引擎与经典的InnoDB存储引擎的对比结果。TokuDB主要有以下几项特性:

(1)使用Fractal树索引保证高效的插入性能;

(2)优秀的压缩特性,比InnoDB高近10倍;

(3)Hot Scheme Changes特性支持在线创建索引和添加、删除属性列等DDL操作;

(4)使用Bulk Loader达到快速加载大量数据;

(5)提供了主从延迟消除技术;

(6)支持ACID和MVCC。

TokuDB特别适用于以下几种场景:

(1)日志数据,因为日志通常插入频繁且存储量大;

(2)历史数据,通常不会再有写操作,可以利用TokuDB的高压缩性进行存储;

(3)在线DDL较频繁的场景,使用TokuDB可以大大增加系统的可用性。

6.3 如何选择合适的存储引擎

应该根据应用特点选择合适的存储引擎,对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合。

下面是几种常用的存储引擎的适用环境。

(1)MyISAM:MySQL5.5之前版本默认的存储引擎,如果应用是以读操作和插入操作为主,只有极少的更新和删除操作,并且对事务的完整性没有要求、没有并发写操作,那么选择这个存储引擎是合适的。OLTP环境一般建议不要再使用MyISAM。

(2)InnoDB:MySQL5.5之后版本默认的存储引擎,用于事务处理应用程序,支持外键,对于大多数的应用系统,InnoDB都是合适的选择。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性。数据操作除了插入和查询之外,还包括很多的更新、删除操作,那么应该优先选择InnoDB存储引擎。InnoDB存储引擎除了有效地降低由于删除和更新导致的锁定,还可以确保事务的完整提交(Commit)和回滚(Rollback)。

(3)MEMORY:将所有数据保存在RAM中,在需要快速定位记录和其他类似数据的环境下,可提供极快的访问速度。MEMORY的缺点是对表的大小有限制,太大的表无法缓存在内存中,其次是要确保表的数据可以恢复,数据库异常终止后表中的数据是可以恢复的。MEMORY表通常用于更新不太频繁的小表,用以快速地得到访问结果。

(4)MERGE:用于将一系列等同于MyISAM表以逻辑方式组合在一起,并作为一个对象引用它们。MERGE表的优点在于可以突破对单个MyISAM表大小的限制,并且通过将不同的表分布在多个磁盘上,有效地改善MERGE表的访问效率,这十分适合于诸如数据仓库等VLDB环境。

注:选择使用哪种存储引擎才是最佳方案不是绝对的,用户需要根据各自的应用机型测试,选择最适合的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值