Mysql-存储引擎特性与选择

一、基本概念

MySQL中有存储引擎的概念,每张表可以对应一种存储引擎。在使用者看来,表就是用来存取数据,而底层数据在磁盘上的组织、查询数据时如何索引、表对使用者支持的功能等则由该表对应的存储引擎来做出规范。

不同的存储引擎有不同的特性,包括存储空间大小限制、支持的功能、存取速度、空间利用率也不尽相同,在创建表时,用户可针对不同的业务需求,自由选择最适合的存储引擎,这种插件式存储引擎是MySQL数据库最重要的特征之一。

可通过show engines来查看数据库支持的引擎(下面是Server version: 5.5.50 MySQL Community Server (GPL)):

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

在创建表时,若不指定存储引擎,则使用默认存储引擎,MySQL中默认参数均有对应的变量名,可以通过

show variables [like 'pattren'];

来显示,要查看默认存储引擎,可以这样:

mysql> show variables like '%engine%';
+---------------------------+--------+
| Variable_name             | Value  |
+---------------------------+--------+
| default_storage_engine    | InnoDB |
| engine_condition_pushdown | ON     |
| storage_engine            | InnoDB |
+---------------------------+--------+

其中default_storage_engine即为默认存储引擎。

 

  • 创建一张未指定存储引擎的表:
create table if not exists without_engin(
`id` int not null primary key auto_increment
)charset utf8;

可通过show create table 语句查询这张表的存储引擎:

mysql> show create table without_engin\G
*************************** 1. row ***************************
       Table: without_engin
Create Table: CREATE TABLE `without_engin` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

其中ENGINE=InnoDB显示该表的存储引擎为InnoDB,即用的默认引擎。

  • 创建表时指定存储引擎:
create table with_engin(
id int
)engine=MyISAM charset=utf8;

查看:

mysql> show create table with_engin\G
*************************** 1. row ***************************
       Table: with_engin
Create Table: CREATE TABLE `with_engin` (
  `id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8

存储引擎为MyISAM。

  • 修改表的存储引擎
alter table with_engin engine = innodb;

查看:

mysql> show create table with_engin\G
*************************** 1. row ***************************
       Table: with_engin
Create Table: CREATE TABLE `with_engin` (
  `id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

二、各种存储引擎特性

各存储引擎特性如下表:

特点 MyISAM InnoDB MEMORY MERGE NDB
存储限制 64TB 没有
事务安全   支持      
锁机制 表锁 行锁 表锁 表锁 表锁
B树索引 支持 支持 支持 支持 支持
哈希索引      支持    
全文索引 支持        
集群索引   支持      
数据缓存   支持 支持   支持
索引缓存 支持 支持 支持 支持 支持
数据可压缩 支持        
空间使用 N/A
内存使用 中等
批量插入速度
支持外键   支持      

可以看到不同的存储引擎可以提供不同的功能、存取性能,所以在设计表的时候,要根据实际的应用场景,选择合适的存储引擎以优化系统性能。接下来主要MyISAM、InnoDB、MEMORY和MERGE。

1.MyISAM

特性:不支持事务、不支持外键、插入速度快、支持全文索引。
优势:访问速度快。
适用场景:1.对事务完整性没有要求 2.以插入和查询为主的应用。

存储方式:每个使用MyISAM引擎穿件的表在磁盘上存储成3个文件,其文件名与表名相同,扩展名分别为

 

  •     .frm (存储表定义)
  •     .MYD(存储数据)
  •     .MYI(存储索引)

我们创建一张表,再插入数据

create table with_myisam_engin(
id int not null primary key auto_increment
)engine=MyISAM charset=utf8;
mysql> insert into with_myisam_engin values (null), (null);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from with_myisam_engin;
+----+
| id |
+----+
|  1 |
|  2 |
+----+

想要查看数据文件的位置,可通过以下命令:

mysql> show global variables like "%datadir%"
    -> ;
+---------------+---------------------------------------------+
| Variable_name | Value                                       |
+---------------+---------------------------------------------+
| datadir       | C:\ProgramData\MySQL\MySQL Server 5.5\Data\ |
+---------------+---------------------------------------------+

这里的ProgramData可能找不到,因为是隐藏文件,可以设置显示隐藏文件找到该文件夹,到该文件夹下,可以看到

其中的每个文件夹都对应我们的一个database,刚才创建的表在以prac命名的datebase下,表名为with_myisam_engin

三个文件的数据均是以二进制形式存储,表中已经插入数据1、2,因为数据单独存在于.MYD文件中,可以查看下该文件中的内容

可以看到01 02两个值。因为三个文件分别保存了表的结构、数据、存储定义,可以将这三个文件复制到其他数据库对应的文件夹下,便可以在其他数据库访问该表,这也是使用MyISAM存储引擎时一种可用的备份方式。

也可将数据文件和索引文件可以放到不同的目录,平均分配I/O,获得更快的速度,指定索引文件盒数据文件的路径,需要在创建表的时候通过DATA DIRECTORY 和 INDEX DIRECTORY语句,这里指定的路径必须要是绝对路径,并且具有访问权限(写的权限),笔者在prac文件夹下创建indexs和datas两个文件夹,并通过以下语句创建一张MyISAM引擎表,指定索引文件、数据文件位置。

create table with_myisam_engin2(
id int not null primary key auto_increment
)engine=MyISAM DATA DIRECTORY='C:/ProgramData/MySQL/MySQL Server 5.5/data/prac/datas'
INDEX DIRECTORY='C:/ProgramData/MySQL/MySQL Server 5.5/data/prac/indexs' charset=utf8;

在windows下面指定文件夹的选项是被忽略的(mysql5.5上,其他版本不知道,在mysql的bug提交网站上可以看到这部分信息

https://bugs.mysql.com/bug.php?id=77773)

存储格式:MyISAM支持三种不同的存储格式:

 

  • 静态(固定长度)表:默认存储格式,字段是非变长字段,这样每个记录都是固定长度的,这种存储方式的优点是存储迅速,容易缓存,出现故障容易恢复;缺点是占用的空间比动态的多。静态表的数据在存储时会按照列的宽度定义补足空格,但是在应用访问的时候并不会得到这些空格,这些空格在返回给应用之前已经去掉,因为补齐主要是在后面补,所以如果插入的数据尾部本身有空格,再次查询时会丢掉。
  • 动态表,包含变长字段,记录不是固定长度的,这样存储的优点是占用空间相对较少,但是频繁的更新和删除记录会产生碎片,需要定期执行OPTIMIZE TABLE语句或myisamchk-r命令来改善性能,并且在出现故障时恢复相对比较困难。
  • 压缩表由myisampack工具创建,占据非常小的磁盘空间。因为每条记录是被单独压缩的,所以只有非常小的访问开支。

上面提到的myisamchk、myisampack均位于MySQL的暗转目录下的bin文件夹下,关于静态表丢失空格可参看下面的例子

create table lost_space(
name varchar(20) not null
)engine=MyISAM charset=utf8;
insert into lost_space values (" 123"),("123 "),("1 2 3");
select * , length(name) from lost_space;

显示结果:

+-------+--------------+
| name  | length(name) |
+-------+--------------+
|  123  |            4 |
| 123   |            4 |
| 1 2 3 |            5 |
+-------+--------------+

 

 

 

 

 

 

 

 

 

 

 

(参考资料:《深入浅出MySQL》)

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章