MySQL數據庫引擎

剛學習數據庫,本來沒有引擎的概念,書上遇到了,於是網上找了一篇文章充實一下。

出處:http://blog.csdn.net/wangyang1354/article/details/50740041


經常用MySQL數據庫,但是,你在用的時候注意過沒有,數據庫的存儲引擎,可能有注意但是並不清楚什麼意思,可能根本沒注意過這個問題,使用了默認的數據庫引擎,當然我之前屬於後者,後來成了前者,然後就有了這篇博文啦,希望可以幫助部分人瞭解MySQL引擎的一些特性。


存儲引擎概念


MySQL中的數據用各種不同的技術存儲在文件(或者內存)中。這些技術中的每一種技術都使用不同的存儲機制、索引技巧、鎖定水平並且最終提供廣泛的不同的功能和能力。通過選擇不同的技術,你能夠獲得額外的速度或者功能,從而改善你的應用的整體功能。

有哪些存儲引擎


存儲引擎主要有: 1. MyIsam , 2. Mrg_Myisam, 3. Memory, 4. Blackhole, 5. CSV, 6. Performance_Schema, 7. Archive, 8. Federated , 9 InnoDB

[sql] view plain copy
  1. mysql> show engines\G  
  2. *************************** 1. row ***************************  
  3.       Engine: MyISAM  
  4.      Support: YES  
  5.      Comment: MyISAM storage engine  
  6. Transactions: NO  
  7.           XA: NO  
  8.   Savepoints: NO  
  9. *************************** 2. row ***************************  
  10.       Engine: MRG_MYISAM  
  11.      Support: YES  
  12.      Comment: Collection of identical MyISAM tables  
  13. Transactions: NO  
  14.           XA: NO  
  15.   Savepoints: NO  
  16. *************************** 3. row ***************************  
  17.       Engine: MEMORY  
  18.      Support: YES  
  19.      Comment: Hash based, stored in memory, useful for temporary tables  
  20. Transactions: NO  
  21.           XA: NO  
  22.   Savepoints: NO  
  23. *************************** 4. row ***************************  
  24.       Engine: BLACKHOLE  
  25.      Support: YES  
  26.      Comment: /dev/null storage engine (anything you write to it disappears)  
  27. Transactions: NO  
  28.           XA: NO  
  29.   Savepoints: NO  
  30. *************************** 5. row ***************************  
  31.       Engine: CSV  
  32.      Support: YES  
  33.      Comment: CSV storage engine  
  34. Transactions: NO  
  35.           XA: NO  
  36.   Savepoints: NO  
  37. *************************** 6. row ***************************  
  38.       Engine: PERFORMANCE_SCHEMA  
  39.      Support: YES  
  40.      Comment: Performance Schema  
  41. Transactions: NO  
  42.           XA: NO  
  43.   Savepoints: NO  
  44. *************************** 7. row ***************************  
  45.       Engine: ARCHIVE  
  46.      Support: YES  
  47.      Comment: Archive storage engine  
  48. Transactions: NO  
  49.           XA: NO  
  50.   Savepoints: NO  
  51. *************************** 8. row ***************************  
  52.       Engine: FEDERATED  
  53.      Support: NO  
  54.      Comment: Federated MySQL storage engine  
  55. Transactions: NULL  
  56.           XA: NULL  
  57.   Savepoints: NULL  
  58. *************************** 9. row ***************************  
  59.       Engine: InnoDB  
  60.      Support: DEFAULT  
  61.      Comment: Supports transactions, row-level locking, and foreign keys  
  62. Transactions: YES  
  63.           XA: YES  
  64.   Savepoints: YES  
  65. rows in set (0.00 sec)  



存儲引擎的主要特性


1. MyIsam


MyIsam 存儲引擎獨立於操作系統,也就是可以在windows上使用,也可以比較簡單的將數據轉移到linux操作系統上去。這種存儲引擎在創建表的時候,會創建三個文件,一個是.frm文件用於存儲表的定義,一個是.MYD文件用於存儲表的數據,另一個是.MYI文件,存儲的是索引。操作系統對大文件的操作是比較慢的,這樣將表分爲三個文件,那麼.MYD這個文件單獨來存放數據自然可以優化數據庫的查詢等操作。

1.  不支持事務,但是並不代表着有事務操作的項目不能用MyIsam存儲引擎,可以在service層進行根據自己的業務需求進行相應的控制。
2.  不支持外鍵。
3.  查詢速度很快,如果數據庫insert和update的操作比較多的話比較適用。
4.  對錶進行加鎖。


2. Mrg_Myisam



Merge存儲引擎,是一組MyIsam的組合,也就是說,他將MyIsam引擎的多個表聚合起來,但是他的內部沒有數據,真正的數據依然是MyIsam引擎的表中,但是可以直接進行查詢、刪除更新等操作。

比如:我們可能會遇到這樣的問題,同一種類的數據會根據數據的時間分爲多個表,如果這時候進行查詢的話,就會比較麻煩,Merge可以直接將多個表聚合成一個表統一查詢,然後再刪除Merge表(刪除的是定義),原來的數據不會影響。


3. Memory


Memory採用的邏輯介質是內存,響應速度應該是很快的,但是當mysqld守護進程崩潰的時候數據會丟失,另外,要求存儲的數據是數據長度不變的格式,比如,Blob和Text類型的數據不可用(長度不固定的)。

使用Memory存儲引擎情況:
  1. 目標數據比較小,而且非常頻繁的進行訪問,在內存中存放數據,如果太大的數據會造成內存溢出。可以通過參數max_heap_table_size控制Memory表的大小,限制Memory表的最大的大小。
  2. 如果數據是臨時的,而且必須立即可用得到,那麼就可以放在內存中。
  3. 存儲在Memory表中的數據如果突然間丟失的話也沒有太大的關係。
  【注】 Memory同時支持散列索引和B樹索引,B樹索引可以使用部分查詢和通配查詢,也可以使用<,>和>=等操作符方便數據挖掘,散列索引相等的比較快但是對於範圍的比較慢很多。


4. Blackhole


“黑洞”存儲引擎,他會丟棄所有的插入的數據,服務器會記錄下Blackhole表的日誌,所以可以用於複製數據到備份數據庫。看其他的一些資料說:可以用來充當dummy master,利用blackHole充當一個“dummy master”來減輕master的負載,對於master來說“dummy master” 還是一個slave的角色,還有充當日誌服務器等等。


5. CSV


可以將scv文件作爲MySql的表來使用,但是不支持索引。CSV引擎表所有的字段都必須爲非空的,創建的表有兩個一個是CSV文件和CSM文件。


6. Performance_Schema


MySQL5.5以後新增了一個存儲引擎,就是Performance_Schema,他主要是用來收集數據庫服務器的性能參數。MySQL用戶不能創建存儲該類型的表。

他提供了以下的功能:
1. 提供進程等待的詳細信息,包括鎖、互斥變量、文件信息。
2. 保存歷史的事件彙總信息,爲Mysql服務器的性能做出詳細的判斷。
3. 對於新增和刪除監控時間點都非常容易,並可以隨意的改變Mysql服務器的監控週期

需要在配置文件my.cnf中進行配置才能開啓。



7.  Archive


archive是歸檔的意思,僅僅支持插入和查詢兩種功能,在MySQL5.5以後支持索引功能,他擁有很好的壓縮機制,使用zlib壓縮庫,在記錄請求的時候實時的進行壓縮,經常被用來作爲倉庫使用。適合存儲大量的獨立的作爲歷史記錄的數據。擁有很高的插入速度但是對查詢的支持較差。


8. Federated


Federated存儲引擎是訪問MySQL服務器的一個代理,儘管該引擎看起來提供了一個很好的跨服務器的靈活性,但是經常帶來問題,默認是禁用的。


9. InnoDB


InnoDB是一個事務型的存儲引擎,有行級鎖定和外鍵約束,適用於以下的場合:

1. 更新多的表,適合處理多重併發的更新請求。
2. 支持事務。
3. 可以從災難中恢復(通過bin-log日誌等)。
4. 外鍵約束。只有他支持外鍵。
5. 支持自動增加列屬性auto_increment。



MyISam和InnoDB實例比較



這裏我選擇兩個比較重點的存儲引擎實驗下速度之類的性能,對比一下看看。


1. 創建兩張表分別以MyIsam和InnoDB作爲存儲引擎。

[sql] view plain copy
  1. create table testMyIsam(  
  2.     -> id int unsigned primary key auto_increment,  
  3.     -> name varchar(20) not null  
  4.     -> )engine=myisam;  

[sql] view plain copy
  1. create table testInnoDB( id int unsigned primary key auto_increment, name varchar(20) not null )engine=innodb;  

兩張表內容是一致的但是存儲引擎不一樣,下面我們從插入數據開始進行測試比較。


2.插入一百萬數據


這裏當然不能手動的插入,創建一個存儲過程插入一百萬的數據。
[sql] view plain copy
  1. mysql> create procedure insertMyIsam()  
  2.     -> begin  
  3.     -> set @i = 1;  
  4.     -> while @i <= 1000000  
  5.     -> do  
  6.     -> insert into testMyIsam(namevalues(concat("wy", @i));  
  7.     -> set @i = @i + 1;  
  8.     -> end while;  
  9.     -> end//  
[sql] view plain copy
  1. mysql> create procedure insertInnoDB()  
  2.     -> begin  
  3.     -> set @i = 1;  
  4.     -> while @i <= 1000000  
  5.     -> do  
  6.     -> insert into testInnoDB(namevalues(concat("wy", @i));  
  7.     -> set @i = @i + 1;  
  8.     -> end while;  
  9.     -> end//  


插入(一百萬條)MyIsam存儲引擎的表中的時間如下:
[sql] view plain copy
  1. mysql> call insertMyIsam;  
  2.     -> //  
  3. Query OK, 0 rows affected (49.69 sec)  


插入(一百萬條)InnoDB存儲引擎的表中的時間如下:
[sql] view plain copy
  1. mysql> create procedure insertInnoDB()  
  2.     -> begin  
  3.     -> set @i = 1;  
  4.     -> while @i <= 1000000  
  5.     -> do   
  6.     -> insert into testInnoDB(namevalues(concat("wy", @i));  
  7.     -> set @i = @i + 1;  
  8.     -> end while;  
  9.     -> end//  
  10. Query OK, 0 rows affected (0.00 sec)  
  11.   
  12. mysql> call insertInnoDB;  
  13.     -> //  
  14. Query OK, 0 rows affected (1 hour 38 min 14.12 sec)  

我的心情是複雜的,這裏當時默認的是開啓了自動提交事務了,所以執行速度很慢,可以先將自動提交關閉,然後再調用存儲過程插入一百萬的數據,執行完成之後再開啓自動提交,這樣會快很多。
[sql] view plain copy
  1. mysql> set autocommit = 0;  
  2. Query OK, 0 rows affected (0.00 sec)  
  3.   
  4. mysql> call insertInnoDB;  
  5. Query OK, 0 rows affected (36.52 sec)  
  6.   
  7. mysql> set autocommit = 1;  
  8. Query OK, 0 rows affected (5.72 sec)  




3. 查詢數據總數目



下面是InnoDB的SQL語句的分析:
[sql] view plain copy
  1. mysql> desc select count(*) from testInnoDB\G;  
  2. *************************** 1. row ***************************  
  3.            id: 1  
  4.   select_type: SIMPLE  
  5.         table: testInnoDB  
  6.          type: index  
  7. possible_keys: NULL  
  8.           keyPRIMARY  
  9.       key_len: 4  
  10.           ref: NULL  
  11.          rows: 997134  
  12.         Extra: Using index  
  13. 1 row in set (0.03 sec)  

下面是MyIsam(他的數據總數存儲在其他的表中所以這裏是沒有影響行數的)的SQL語句的分析:
[sql] view plain copy
  1. mysql> desc select count(*) from testMyIsam\G;  
  2. *************************** 1. row ***************************  
  3.            id: 1  
  4.   select_type: SIMPLE  
  5.         tableNULL  
  6.          type: NULL  
  7. possible_keys: NULL  
  8.           keyNULL  
  9.       key_len: NULL  
  10.           ref: NULL  
  11.          rowsNULL  
  12.         Extra: Select tables optimized away  
  13. 1 row in set (0.00 sec)  



4. 查詢某一範圍的數據



4.1 沒有索引的列

[sql] view plain copy
  1. mysql> select * from testMyIsam where name > "wy100" and name < "wy100000";+-------+---------+  
  2. | id    | name    |  
  3. +-------+---------+  
  4. |  1000 | wy1000  |  
  5. | 10000 | wy10000 |  
  6. +-------+---------+  
  7. rows in set (0.43 sec)  
  8.   
  9. mysql> select * from testInnoDB where name > "wy100" and name < "wy100000";+-------+---------+  
  10. | id    | name    |  
  11. +-------+---------+  
  12. |  1000 | wy1000  |  
  13. | 10000 | wy10000 |  
  14. +-------+---------+  

4.2 有索引的列

對於使用MyIsam存儲引擎的表:
[sql] view plain copy
  1. <pre name="code" class="sql">select * from testMyIsam where id > 10 and id < 999999;  

執行時間:
[sql] view plain copy
  1. <pre name="code" class="sql">999988 rows in set (0.91 sec)  

對於使用了InnoDB存儲引擎的表:
[sql] view plain copy
  1. select * from testInnoDB where id > 10 and id < 999999;  
[sql] view plain copy
  1. 999988 rows in set (0.69 sec)  

但是好像我沒看出來多大的差距,可能是數據太少的原因吧。

[sql] view plain copy
  1. mysql> select * from testInnoDB where name = "wy999999";  
  2. +--------+----------+  
  3. | id     | name     |  
  4. +--------+----------+  
  5. | 999999 | wy999999 |  
  6. +--------+----------+  
  7. 1 row in set (0.20 sec)  
  8.   
  9. mysql> select * from testMyIsam where name = "wy999999";  
  10. +--------+----------+  
  11. | id     | name     |  
  12. +--------+----------+  
  13. | 999999 | wy999999 |  
  14. +--------+----------+  
  15. 1 row in set (0.16 sec) 

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