每個(gè)MyISAM在磁盤上存儲(chǔ)成三個(gè)文件。第一個(gè)文件的名字以表的名字開(kāi)始,擴(kuò)展名指出文件類型。.frm文件存儲(chǔ)表定義。數(shù)據(jù)文件的擴(kuò)展名為.MYD (MYData)。索引文件的擴(kuò)展名是.MYI (MYIndex)。
MyISAM引擎是大多數(shù)MySQL安裝程序的默認(rèn)引擎,起源于早期版本MySQL支持的ISAM引擎。這種引擎提供了最佳的性能和功能的組合,盡管它缺少事務(wù)處理功能(使用InnoDB或者BDB引擎)并且使用表級(jí)鎖定。
但是執(zhí)行一下查詢發(fā)現(xiàn),我在測(cè)試的時(shí)候使用的兩個(gè)測(cè)試表在創(chuàng)建的時(shí)候沒(méi)有指定引擎,但是發(fā)現(xiàn)這兩個(gè)表的存儲(chǔ)引擎都為InnoDB。(當(dāng)然我們修改配職文件my.ini中的default-storage-engine=INNODB來(lái)修改)。
mysql> select table_name,engine from tables where table_name like 'test%';
+------------+--------+
| table_name | engine |
+------------+--------+
| test | InnoDB |
| test1 | InnoDB |
+------------+--------+
2 rows in set (0.08 sec)
MYSQL文檔的解釋是:“存儲(chǔ)引擎和表類型:當(dāng)MySQL被用MySQL配置向?qū)О惭b在Windows平臺(tái)上,InnoDB存儲(chǔ)引擎替代MyISAM存儲(chǔ)引擎作為替代。 ”
為了測(cè)試MyISAM引擎表級(jí)鎖定,我們是用MyISAM引擎創(chuàng)建測(cè)試表TEST_ISAM。
測(cè)試中打開(kāi)兩個(gè)數(shù)據(jù)庫(kù)連接,一個(gè)連接執(zhí)行call p_tst_isam();另外一個(gè)執(zhí)行單條mysql> insert into test_isam(id,mc) values(1,'1');結(jié)果在第一個(gè)連接還沒(méi)有執(zhí)行完的時(shí)候,第二個(gè)就完畢,沒(méi)有發(fā)現(xiàn)MyISAM引擎鎖表,這個(gè)問(wèn)題我們暫時(shí)不再繼續(xù)測(cè)試下去。測(cè)試中發(fā)現(xiàn)一個(gè)問(wèn)題,MyISAM引擎的表的INSERT速度遠(yuǎn)遠(yuǎn)大于InnoDB引擎:
mysql> CREATE TABLE TEST_ISAM(ID INTEGER,MC VARCHAR(60)) ENGINE=MyISAM;
Query OK, 0 rows affected (0.38 sec)
mysql> select table_name,engine from information_schema.tables where table_name like 'test%';
+------------+--------+
| table_name | engine |
+------------+--------+
| test | InnoDB |
| test1 | InnoDB |
| test_isam | MyISAM |
+------------+--------+
3 rows in set (0.00 sec)
創(chuàng)建存儲(chǔ)過(guò)程p_test_isam
delimiter //
create procedure p_test_isam()
begin
declare counter int;
set counter = 1000000;
while counter >= 1 do
insert into test_isam(id,mc) values(counter,'test');
set counter = counter - 1;
end while;
end
//
delimiter ;
我們?cè)谝郧暗臏y(cè)試?yán)又校?InnoDB引擎 INSERT 1000條數(shù)據(jù)花費(fèi)34秒
mysql> call p_test();
Query OK, 1 row affected (34.48 sec)
MyISAM引擎INSERT 1000000 條數(shù)據(jù)花費(fèi)時(shí)間20多秒:
mysql> call p_test_isam();
Query OK, 1 row affected (22.95 sec)
所以,我們?nèi)绻谑褂梅鞘挛锾幚淼谋?也就是一些只有單用戶使用的表)的時(shí)候可以采用MyISAM引擎來(lái)提高速度,當(dāng)然了,INSERT的時(shí)候可以利用 MYSQL的BULK INSERT功能來(lái)出也是能大大提高性能的,這些我們將在MYSQL數(shù)據(jù)庫(kù)優(yōu)化一?***:
INSERT INTO TEST VALUES(VAL11,VAL12),(VAL21,VAL22)……
測(cè)試完畢,翻看一下MYSQL文檔,的確有下面一段話,和我們的測(cè)試結(jié)果吻合。
MyISAM管理非事務(wù)表。它提供高速存儲(chǔ)和檢索,以及全文搜索能力。MyISAM在所有MySQL配置里被支持,它是默認(rèn)的存儲(chǔ)引擎,除非你配置MySQL默認(rèn)使用另外一個(gè)引擎。
delimiter //
create procedure p_test_isam()
begin
declare counter int;
set counter = 1000000;
while counter >= 1 do
insert into test_isam(id,mc) values(counter,'test');
set counter = counter - 1;
end while;
end
//
delimiter ;
我們?cè)谝郧暗臏y(cè)試?yán)又校?InnoDB引擎 INSERT 1000條數(shù)據(jù)花費(fèi)34秒
mysql> call p_test();
Query OK, 1 row affected (34.48 sec)
MyISAM引擎INSERT 1000000 條數(shù)據(jù)花費(fèi)時(shí)間20多秒:
mysql> call p_test_isam();
Query OK, 1 row affected (22.95 sec)
所以,我們?nèi)绻谑褂梅鞘挛锾幚淼谋?也就是一些只有單用戶使用的表)的時(shí)候可以采用MyISAM引擎來(lái)提高速度,當(dāng)然了,INSERT的時(shí)候可以利用 MYSQL的BULK INSERT功能來(lái)出也是能大大提高性能的,這些我們將在MYSQL數(shù)據(jù)庫(kù)優(yōu)化一?***:
INSERT INTO TEST VALUES(VAL11,VAL12),(VAL21,VAL22)……
測(cè)試完畢,翻看一下MYSQL文檔,的確有下面一段話,和我們的測(cè)試結(jié)果吻合。
MyISAM管理非事務(wù)表。它提供高速存儲(chǔ)和檢索,以及全文搜索能力。MyISAM在所有MySQL配置里被支持,它是默認(rèn)的存儲(chǔ)引擎,除非你配置MySQL默認(rèn)使用另外一個(gè)引擎。
MERGE引擎
MERGE引擎類型允許你把許多結(jié)構(gòu)相同的表合并為一個(gè)表。然后可以執(zhí)行查詢,從多個(gè)表返回的結(jié)果就像從一個(gè)表返回的結(jié)果一樣。每一個(gè)合并的表必須有同樣的表定義。
MERGE存儲(chǔ)引擎在下面這種使用場(chǎng)合會(huì)最為有用,如果需要把日志紀(jì)錄不停的錄入MySQL數(shù)據(jù)庫(kù),并且每天、每周或者每個(gè)月都創(chuàng)建一個(gè)單一的表,而且要制作來(lái)自多個(gè)表的合計(jì)查詢,MERGE表這時(shí)會(huì)非常有效。然而,這項(xiàng)功能有局限性。只能合并MyISAM表而且必須嚴(yán)格遵守相同的表定義的限制。雖然這看起來(lái)好像是一個(gè)大問(wèn)題,但是,如果使用另外一種表類型(例如InnoDB),這種合并可能就不需要了。
MEMORY(內(nèi)存)存儲(chǔ)引擎
MEMORY(內(nèi)存)存儲(chǔ)引擎(以前稱作HEAP存儲(chǔ)引擎)在內(nèi)存中存儲(chǔ)全部數(shù)據(jù)。一旦MySQL服務(wù)器關(guān)閉,存儲(chǔ)在內(nèi)存中的任何信息都將丟失。然而,單個(gè)表的格式將保留,使你能夠創(chuàng)建一個(gè)用于存儲(chǔ)信息的臨時(shí)表。這樣,每次數(shù)據(jù)庫(kù)服務(wù)器啟動(dòng)時(shí),你不需要重新創(chuàng)新這個(gè)表就可以快速地訪問(wèn)信息。
長(zhǎng)期使用MEMORY存儲(chǔ)引擎一般來(lái)說(shuō)不是一個(gè)好主意,因?yàn)閿?shù)據(jù)很容易丟失。然而,如果你有足夠的內(nèi)存,使用基于MEMORY的表在大型數(shù)據(jù)集中執(zhí)行復(fù)雜的查詢是一種非常有效的方法,它能夠很大程度的提高性能。
使用MEMORY表的最佳方法是使用一個(gè)“select”語(yǔ)句從你原來(lái)的基于磁盤的表中選擇一個(gè)大型的數(shù)據(jù)集,然后對(duì)你需要的具體部分進(jìn)一步分析那些信息。我過(guò)去曾經(jīng)使用這個(gè)技術(shù)提取了一個(gè)月的網(wǎng)絡(luò)記錄數(shù)據(jù),實(shí)際上就是從使用ARCHIVE存儲(chǔ)引擎制作的表中提取的數(shù)據(jù),然后對(duì)具體的URL、網(wǎng)站和其它重點(diǎn)進(jìn)行查詢。
EXAMPLE引擎
EXAMPLE引擎實(shí)際上是一個(gè)存儲(chǔ)引擎編程的例子,能夠用作MySQL系統(tǒng)中其它引擎的基礎(chǔ)。EXAMPLE不支持?jǐn)?shù)據(jù)插入,對(duì)于任何形式的數(shù)據(jù)庫(kù)訪問(wèn)來(lái)說(shuō)也不是一個(gè)實(shí)用的引擎。然而,EXAMPLE是一個(gè)很好的指南,指導(dǎo)你如何開(kāi)發(fā)自己的存儲(chǔ)引擎,因此對(duì)于程序員來(lái)說(shuō)是一個(gè)有效的引擎。
BDB存儲(chǔ)引擎
BDB表可能有一個(gè)更大的崩潰幸存機(jī)會(huì),并且也具有對(duì)事務(wù)COMMIT和ROLLBACK操作的能力,BDB引擎支持頁(yè)級(jí)鎖定。
InnoDB存儲(chǔ)引擎
InnoDB給MySQL提供了具有提交、回滾、崩潰恢復(fù)能力的事務(wù)安全(ACID兼容)存儲(chǔ)引擎。InnoDB鎖定在行級(jí)并且也在SELECT語(yǔ)句提供一個(gè)Oracle風(fēng)格一致的非鎖定讀。這些特色增加了多用戶部署和性能。沒(méi)有在InnoDB中擴(kuò)大鎖定的需要,因?yàn)樵贗nnoDB中行級(jí)鎖定適合非常小的空間。InnoDB也支持FOREIGN KEY強(qiáng)制。在SQL查詢中,你可以自由地將InnoDB類型的表與其它MySQL的表的類型混合起來(lái),甚至在同一個(gè)查詢中也可以混合。
InnoDB是為處理巨大數(shù)據(jù)量時(shí)的最大性能設(shè)計(jì)。它的CPU效率可能是任何其它基于磁盤的關(guān)系數(shù)據(jù)庫(kù)引擎所不能匹敵的。
InnoDB存儲(chǔ)引擎被完全與MySQL服務(wù)器整合,InnoDB存儲(chǔ)引擎為在主內(nèi)存中緩存數(shù)據(jù)和索引而維持它自己的緩沖池。InnoDB存儲(chǔ)它的表&索引在一個(gè)表空間中,表空間可以包含數(shù)個(gè)文件(或原始磁盤分區(qū))。這與MyISAM表不同,比如在MyISAM表中每個(gè)表被存在分離的文件中。InnoDB 表可以是任何尺寸,即使在文件尺寸被限制為2GB的操作系統(tǒng)上。
MERGE引擎類型允許你把許多結(jié)構(gòu)相同的表合并為一個(gè)表。然后可以執(zhí)行查詢,從多個(gè)表返回的結(jié)果就像從一個(gè)表返回的結(jié)果一樣。每一個(gè)合并的表必須有同樣的表定義。
MERGE存儲(chǔ)引擎在下面這種使用場(chǎng)合會(huì)最為有用,如果需要把日志紀(jì)錄不停的錄入MySQL數(shù)據(jù)庫(kù),并且每天、每周或者每個(gè)月都創(chuàng)建一個(gè)單一的表,而且要制作來(lái)自多個(gè)表的合計(jì)查詢,MERGE表這時(shí)會(huì)非常有效。然而,這項(xiàng)功能有局限性。只能合并MyISAM表而且必須嚴(yán)格遵守相同的表定義的限制。雖然這看起來(lái)好像是一個(gè)大問(wèn)題,但是,如果使用另外一種表類型(例如InnoDB),這種合并可能就不需要了。
MEMORY(內(nèi)存)存儲(chǔ)引擎
MEMORY(內(nèi)存)存儲(chǔ)引擎(以前稱作HEAP存儲(chǔ)引擎)在內(nèi)存中存儲(chǔ)全部數(shù)據(jù)。一旦MySQL服務(wù)器關(guān)閉,存儲(chǔ)在內(nèi)存中的任何信息都將丟失。然而,單個(gè)表的格式將保留,使你能夠創(chuàng)建一個(gè)用于存儲(chǔ)信息的臨時(shí)表。這樣,每次數(shù)據(jù)庫(kù)服務(wù)器啟動(dòng)時(shí),你不需要重新創(chuàng)新這個(gè)表就可以快速地訪問(wèn)信息。
長(zhǎng)期使用MEMORY存儲(chǔ)引擎一般來(lái)說(shuō)不是一個(gè)好主意,因?yàn)閿?shù)據(jù)很容易丟失。然而,如果你有足夠的內(nèi)存,使用基于MEMORY的表在大型數(shù)據(jù)集中執(zhí)行復(fù)雜的查詢是一種非常有效的方法,它能夠很大程度的提高性能。
使用MEMORY表的最佳方法是使用一個(gè)“select”語(yǔ)句從你原來(lái)的基于磁盤的表中選擇一個(gè)大型的數(shù)據(jù)集,然后對(duì)你需要的具體部分進(jìn)一步分析那些信息。我過(guò)去曾經(jīng)使用這個(gè)技術(shù)提取了一個(gè)月的網(wǎng)絡(luò)記錄數(shù)據(jù),實(shí)際上就是從使用ARCHIVE存儲(chǔ)引擎制作的表中提取的數(shù)據(jù),然后對(duì)具體的URL、網(wǎng)站和其它重點(diǎn)進(jìn)行查詢。
EXAMPLE引擎
EXAMPLE引擎實(shí)際上是一個(gè)存儲(chǔ)引擎編程的例子,能夠用作MySQL系統(tǒng)中其它引擎的基礎(chǔ)。EXAMPLE不支持?jǐn)?shù)據(jù)插入,對(duì)于任何形式的數(shù)據(jù)庫(kù)訪問(wèn)來(lái)說(shuō)也不是一個(gè)實(shí)用的引擎。然而,EXAMPLE是一個(gè)很好的指南,指導(dǎo)你如何開(kāi)發(fā)自己的存儲(chǔ)引擎,因此對(duì)于程序員來(lái)說(shuō)是一個(gè)有效的引擎。
BDB存儲(chǔ)引擎
BDB表可能有一個(gè)更大的崩潰幸存機(jī)會(huì),并且也具有對(duì)事務(wù)COMMIT和ROLLBACK操作的能力,BDB引擎支持頁(yè)級(jí)鎖定。
InnoDB存儲(chǔ)引擎
InnoDB給MySQL提供了具有提交、回滾、崩潰恢復(fù)能力的事務(wù)安全(ACID兼容)存儲(chǔ)引擎。InnoDB鎖定在行級(jí)并且也在SELECT語(yǔ)句提供一個(gè)Oracle風(fēng)格一致的非鎖定讀。這些特色增加了多用戶部署和性能。沒(méi)有在InnoDB中擴(kuò)大鎖定的需要,因?yàn)樵贗nnoDB中行級(jí)鎖定適合非常小的空間。InnoDB也支持FOREIGN KEY強(qiáng)制。在SQL查詢中,你可以自由地將InnoDB類型的表與其它MySQL的表的類型混合起來(lái),甚至在同一個(gè)查詢中也可以混合。
InnoDB是為處理巨大數(shù)據(jù)量時(shí)的最大性能設(shè)計(jì)。它的CPU效率可能是任何其它基于磁盤的關(guān)系數(shù)據(jù)庫(kù)引擎所不能匹敵的。
InnoDB存儲(chǔ)引擎被完全與MySQL服務(wù)器整合,InnoDB存儲(chǔ)引擎為在主內(nèi)存中緩存數(shù)據(jù)和索引而維持它自己的緩沖池。InnoDB存儲(chǔ)它的表&索引在一個(gè)表空間中,表空間可以包含數(shù)個(gè)文件(或原始磁盤分區(qū))。這與MyISAM表不同,比如在MyISAM表中每個(gè)表被存在分離的文件中。InnoDB 表可以是任何尺寸,即使在文件尺寸被限制為2GB的操作系統(tǒng)上。
InnoDB默認(rèn)地被包含在MySQL二進(jìn)制分發(fā)中。Windows Essentials installer使InnoDB成為Windows上MySQL的默認(rèn)表。
InnoDB被用來(lái)在眾多需要高性能的大型數(shù)據(jù)庫(kù)站點(diǎn)上產(chǎn)生。著名的Internet新聞?wù)军c(diǎn)Slashdot.org運(yùn)行在InnoDB上。 Mytrix, Inc.在InnoDB上存儲(chǔ)超過(guò)1TB的數(shù)據(jù),還有一些其它站點(diǎn)在InnoDB上處理平均每秒800次插入/更新的負(fù)荷。
給出一個(gè)事務(wù)控制的例子:
mysql> CREATE TABLE CUSTOMER (A INT, B CHAR (20), INDEX (A)) ENGINE=InnoDB;
Query OK, 0 rows affected (0.30 sec)
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO CUSTOMER VALUES (10, 'Heikki');
Query OK, 1 row affected (0.00 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.03 sec)
mysql> SET AUTOCOMMIT=0;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO CUSTOMER VALUES (15, 'John');
Query OK, 1 row affected (0.00 sec)
mysql> ROLLBACK;
Query OK, 0 rows affected (0.06 sec)
mysql> SELECT * FROM CUSTOMER;
+------+--------+
| A | B |
+------+--------+
| 10 | Heikki |
+------+--------+
1 row in set (0.00 sec)
InnoDB存儲(chǔ)引擎相關(guān)的內(nèi)容非常復(fù)雜涉及到事物處理、日志、備份和恢復(fù)、鎖定、多版本、性能、表和索引的結(jié)構(gòu)、磁盤IO等很多方面的知識(shí)。
我們以上只講述了MYSQL的幾個(gè)存儲(chǔ)引擎,使我們能夠?qū)YSQL的存儲(chǔ)引擎有個(gè)基本的認(rèn)識(shí)。MYSQL還提供了BDB (BerkeleyDB)存儲(chǔ)引擎、FEDERATED存儲(chǔ)引擎、ARCHIVE存儲(chǔ)引擎、CSV存儲(chǔ)引擎、BLACKHOLE存儲(chǔ)引擎等,這里就不再詳細(xì)說(shuō)明了。
InnoDB被用來(lái)在眾多需要高性能的大型數(shù)據(jù)庫(kù)站點(diǎn)上產(chǎn)生。著名的Internet新聞?wù)军c(diǎn)Slashdot.org運(yùn)行在InnoDB上。 Mytrix, Inc.在InnoDB上存儲(chǔ)超過(guò)1TB的數(shù)據(jù),還有一些其它站點(diǎn)在InnoDB上處理平均每秒800次插入/更新的負(fù)荷。
給出一個(gè)事務(wù)控制的例子:
mysql> CREATE TABLE CUSTOMER (A INT, B CHAR (20), INDEX (A)) ENGINE=InnoDB;
Query OK, 0 rows affected (0.30 sec)
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO CUSTOMER VALUES (10, 'Heikki');
Query OK, 1 row affected (0.00 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.03 sec)
mysql> SET AUTOCOMMIT=0;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO CUSTOMER VALUES (15, 'John');
Query OK, 1 row affected (0.00 sec)
mysql> ROLLBACK;
Query OK, 0 rows affected (0.06 sec)
mysql> SELECT * FROM CUSTOMER;
+------+--------+
| A | B |
+------+--------+
| 10 | Heikki |
+------+--------+
1 row in set (0.00 sec)
InnoDB存儲(chǔ)引擎相關(guān)的內(nèi)容非常復(fù)雜涉及到事物處理、日志、備份和恢復(fù)、鎖定、多版本、性能、表和索引的結(jié)構(gòu)、磁盤IO等很多方面的知識(shí)。
我們以上只講述了MYSQL的幾個(gè)存儲(chǔ)引擎,使我們能夠?qū)YSQL的存儲(chǔ)引擎有個(gè)基本的認(rèn)識(shí)。MYSQL還提供了BDB (BerkeleyDB)存儲(chǔ)引擎、FEDERATED存儲(chǔ)引擎、ARCHIVE存儲(chǔ)引擎、CSV存儲(chǔ)引擎、BLACKHOLE存儲(chǔ)引擎等,這里就不再詳細(xì)說(shuō)明了。