在mysql的众多存储引擎中 只有,MYISAM与INNODB以及其他存储引擎区别

  • Post author:
  • Post category:mysql


·如果允许NULL值的列有唯一的索引,只有单个NULL值是被允许的。这不同于其它存储引擎。

MERGE MyISAM

MERGE(MERGE MyISAM )引擎有很多特殊的地方:

MERGE引擎类型允许你把许多结构相同的表合并为一个表。然后,你可以执行查询,从多个表返回的结果就像从一个表返回的结果一样。每一个合并的表必须有同样的表定义。

MERGE存储引擎在下面这种使用场合会最为有用,如果需要把日志纪录不停的录入MySQL数据库,并且每天、每周或者每个月都创建一个单一的

表,而且要制作来自多个表的合计查询,MERGE表这时会非常有效。然而,这项功能有局限性。你只能合并MyISAM表而且必须严格遵守相同的表定义的限

制。虽然这看起来好像是一个大问题,但是,如果你使用另外一种表类型(例如InnoDB),这种合并可能就不需要了。

其创建方法如下:

他将多个表在逻辑上当作一个表来查询。他建立后有两个文件,

.frm 表结构定义

.mrg union表的名字清单

两个基本表:

CREATE TABLE TEST_MERGE_1(

ID INT(5) NOT NULL,

VALUE VARCHAR(100) NOT NULL,

PRIMARY KEY(ID)

) ENGINE=MyISAM DEFAULT CHARSET=utf8

CREATE TABLE TEST_MERGE_2(

ID INT(5) NOT NULL,

VALUE VARCHAR(100) NOT NULL,

PRIMARY KEY(ID)

) ENGINE=MyISAM DEFAULT CHARSET=utf8

MERGE表的建立:

CREATE TABLE TEST_MERGE(

ID INT(5) NOT NULL,

VALUE VARCHAR(100) NOT NULL,

PRIMARY KEY(ID)

) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8 INSERT_METHOD=LAST

UNION=(TEST_MERGE_1,TEST_MERGE_2) ;

1. 此表类似于SQL中的union机制。

2. 此表结构必须与基本表完全一致,包括列名、顺序。UNION表必须同属一个DATABASE。

3. 基本表类型必须是MyISAM。

4. 可以通过修改.mrg文件来修改MERGE表,每个基本表的名字占一行。注意:修改后要通过FLUSH

TABLES刷新表缓存。

5. 对基本表的更改可以直接反映在此表上。

6. INSERT_METHOD的取值可以是: 0 不允许插入 FIRST 插入到UNION中的第一个表 LAST

插入到UNION中的最后一个表。(4.0之后可用)

7.

定义在它上面的约束没有任何作用,约束是由基本表控制的,例如两个基本表中存在着同样的一个Key值,那么在MERGE表中会有两个一样的Key值。

8. 连接的几张表都必须是myisam engine的。

因为MySQL利用底层文件系统来保存数据库名和表定义,因此是否大小写敏感取决于使用的平台。在一个基于Windows的MySQL实例上,

表和数据库名是大小写不敏感的;而在类Unix系统上,它们是大小写敏感的。每一种存储引擎对于数据和索引的存储是不一样的,但是关于表的定义却是由服务

器层来完成的。

Memory存储

内存表(以前被称为HEAP表)当你需要极快速的获取一些不需要修改或不需要在重启后持久化的数据时会非常有用。内存表一般会比MyISAM表

快上一个数量级。所有的数据都被存储在内存中,因此查询不需要磁盘IO等待。内存表的表结构在会服务器重启过程中进行持久化,但是数据不会。

下面是一些内存表比较好的应用:

作为查询表或者映射表,如邮编和省份的映射表

作为周期性更新的数据缓存表

作为分析数据的中间结构表

内存表支持HASH索引,HASH索引在查询中非常快速。关于“哈希索引”的具体内容可以查看后面章节。

创建,使用并删除一个MEMORY表:

mysql> CREATE TABLE test ENGINE=MEMORY

-> SELECT ip,SUM(downloads) AS down

-> FROM log_table GROUP BY ip;

mysql> SELECT COUNT(ip),AVG(down) FROM test;

mysql> DROP TABLE test;

尽管内存数据库很快,但是它们仍然不用作为一个基于硬盘表的替换产品。因为它只支持表级别的锁定,这使得它的写并发效率很快,另外它不支持

TEXT和BLOB类型。另外,内存数据库只支持固定大小的行,因此它会将VARCHAR作为CHAR来进行存储,这将会浪费许多内存。

MySQL将内存引擎作为处理查询时的中间结果的内部临时数据库来使用。如果中间结果太大或者有TEXT和BLOB列的话,MySQL会把内存表转换为MyISAM表。我们将在后面章节中详细讨论这个问题。

人们经常把内存表和临时表相混淆。事实上临时表是用CREATE TEMPORARY

TABLE命令来他创建的。一个临时表可以使用任何存储引擎;它与使用内存引擎的表不是一回事。临时表仅对于单个的连接是可见的,当连接关闭时这个临时表就会被销毁。

Archive存储引擎

Archive引擎只支持INSERT和SELECT语句,并且它不支持索引。它比MyISAM使用更少的磁盘IO,因此它会在写操作之前将数

据缓存并利用zlib来压缩。而SELECT查询操作则需要一个全表扫描。因此Archive表是日志和数据采集的理想选择,在这些应用中,一般分析是需

要扫描整张表或者需要在一个备份主机上进行快速的INSERT操作。备份从机上可以为相同的表选用一个不同的存储引擎,这意味着从机上的表可以有索引,以

达到快速分析的目的。

Archive引擎支持行级别的锁以及一个特殊的缓冲系统以期达到高并发的写操作。它在查询时会将整个表扫描一次。它同时也会将批量写操作屏蔽

直到全部的写操作完成。这些特性模拟了事务和MVCC行为的一些方面,但是Archive引擎并不是一个事务型引擎。它只是一个优化了插入操作以及压缩了

数据的引擎。

选择正确的存储引擎

当设计基于MySQL的应用时,你应该首先决定利用哪种存储引擎来存储你的数据。如果你不在设计阶段考虑这个问题,你极有可能在后面的开发中面

临复杂的情况。你很可能发现默认的存储引擎并没有提供你需要的一个特性,比如事务,或者你需要比MyISAM的表锁定更细粒度的读写锁定。

因为你可以在表级别来选择存储引擎,因此你需要对如何使用每个表以及每个表中存的数据有一个清楚的认识。它不仅可以帮助你对于整个应用有一个比较好的整体理解,同时也可以对它的增长规模有一个估计。借助于这些信息,你可开始决定利用哪些存储引擎来完成这些任务了。

注:对于不同的表使用不同的存储引擎并不是很必要。如果你可以为所有的表使用同一个存储引擎来完成既定的任务,那么你将会发现你后面的工作要简单很多。

存储引擎选择的考查点

尽管许多因素都可以对存储引擎的选择造成影响,它通常还是可以归结为一些很基本的考查点。下面列出就是一些主要的考查点:

事务

如果你的需要事务,那么InnoDB是最稳定、并且集成度比较好的经过验证的选择。但是随着时间的推进,我们也将会看到许多更有竞争力的事务型

引擎出现。如果不需要事务,而只是执行一些基本的查询和插入操作的话,MyISAM是一个比较好的选择。有时一个应用的一些特定的组件(比如日志)可能会

归入这类应用。

并发

开发性需求的最好的衡量标准是你的工作量。如果你只量需要插入和写操作的并发性的话,不管你相信不相信,MyISAM是一个很不错的选择。如果你需要许多操作混合执行而互不影响的话,一个支持行锁的引擎将会是比较不错的选择。

备份

对于常规备份的需求也可能成为影响你的表选择的一个因素。如果你的服务器可以定时的关闭来备份的话,所有的存储引擎在处理上基本都差不多。但是

如果你需要执行一个线上备份的话,选择就不是那么清晰了。第11章将会针对这个话题进行更详细的描述。但是需要记住一点,如果选用了多种存储引擎的话,将

会增大备份和服务器调优的复杂性。

故障恢复

如果你有很多的数据,你需要很严肃地考虑它需要多久从一个故障中恢复。MyISAM表相对于InnoDB表来说,一般更容易损坏,并且需要花更多的时间来恢复。事实上这是为什么很多在即使不需要事务的时候也仍然选择InnoDB的原因。

特殊功能

最后,你有时可能会发现一个应用依赖于一些特定的功能或者优化,而这些优化可能只有一些MySQL的存储引擎提供。比如,许多应用依赖于簇索引

的优化。在这个时候,你的选择就只有InnoDB和solidDB了。另一方面来说,只有MyISAM支持全文检索。如果一个存储引擎只符合其中的一些条

件,而不符合其他的,你就需要妥协或者找到一个更聪明的设计方案了。你可能会经常遇到一种存储引擎只符合你的众多需求中的一些的情况

表的存储引擎转换

将一个表从一种存储引擎转换成另外一种有许多种方法,每一种都有它各自的优缺点。在下面的章节中我们将来详细介绍三种更大众的方法。

修改表

最简单的办法莫过于直接使用ALTER TABLE命令。下面的命令可以将mytable表转换为Falcon:

这个语法对于所有的存储引擎都是有效的,但是这里有一个陷阱:它可能会需要很长的时间。MySQL将会执行一个行到行的拷贝,将旧表的数据拷贝

到新表中去。这个段时间里,你可能会将整个服务器的磁盘IO用尽,并且在这个过程中旧表是处于锁定状态的。因此,如果你需要在一个使用率很高的表上进行这

个操作需要额外的小心。当然,你也可以使用下面讨论的其他方法中的一个,它们都会先拷贝一份原表。

当你将一个表的存储引擎从一种转换成另外一种时,任何针对原存储引擎的特性都会被丢弃。举个例子来说,如果你把一个InnoDB表转换成MyISAM,然后再转换回来,那么你将会发现InnoDB表上定义的所有外键约束都没有了。

1.5.19.2. 导出和导入

为了在整个转换过程中得到更大的控制权,你可以选择利用mysqldump工具先将表里的数据导出为文本文件。当你将表导出之后,你可简单地修

改一下导出文件使得CREATE

TABLE语句中的存储引擎变成你需要的。注意一定要将表名也修改了,因为同一个数据库里不可能有同名的表,即使它们是不同的类型。另外

mysqldump默认会导出一个DROP TABLE命令,因此如果你不小心的话,你可能就会丢失数据。

1.5.19.3. CREATE和SELECT

第三种方法是在前两种之间的一个融合,同时具有第一种的速度和第二种的安全性。与第二种导出整个表并且将它整个转换不同,第三种方案采用先建一张表,然后利用MySQL的INSERT…SELECT语法来填充它,如下所示:

如果你的数据不是很多的话,这个方案将会工作地很好;但是如果你有很多数据的话,比较有效的方法是增量式填充,将整个转换分成多个事务块来执

行,这样子可以避免重做日志变得很大。假如id是主键,可以利用反复执行下面的命令来将表中的数据拷贝到新表中去(每次都增大x和y):

在这个过程完成之后,你将有拥有两张表,一个是原表,你可以在不再需要它时将它drop掉;另外一个是新表,它现在已经被完全的填充。如果需要防止数据的不一致拷贝将记得将原表锁定。