1、存儲引擎的概述:
基於此博客MySQL數據庫引擎去擴展,不過每一個我都會用例子去驗證,並寫出的看法。
(1)爲何要合理選擇數據庫存儲引擎:
MySQL中的數據用各類不一樣的技術存儲在文件(或者內存)中。這些技術中的每一種技術都使用不一樣的存儲機制、索引技巧、鎖定水平而且最終提供普遍的不一樣的功能和能力。經過選擇不一樣的技術,你可以得到額外的速度或者功能,從而改善你的應用的總體功能。
這些不一樣的技術以及配套的相關功能在MySQL中被稱做存儲引擎(也稱做表類型)。MySQL默認配置了許多不一樣的存儲引擎,能夠預先設置或者在MySQL服務器中啓用。你能夠選擇適用於服務器、數據庫和表格的存儲引擎,以便在選擇如何存儲你的信息、如何檢索這些信息以及你須要你的數據結合什麼性能和功能的時候爲你提供最大的靈活性。
(2)定義:
數據庫引擎是用於存儲、處理和保護數據的核心服務。利用數據庫引擎可控制訪問權限並快速處理事務,從而知足企業內大多數須要處理大量數據的應用程序的要求。 使用數據庫引擎建立用於聯機事務處理或聯機分析處理數據的關係數據庫。這包括建立用於存儲數據的表和用於查看、管理和保護數據安全的數據庫對象(如索引、視圖和存儲過程)。
(3)存儲引擎做用:
1)設計並建立數據庫以保存系統所需的關係或XML文檔。
2)實現系統以訪問和更改數據庫中存儲的數據。包括實現網站或使用數據的應用程序,還包括生成使用SQL Server工具和實用工具以使用數據的過程。
3)爲單位或客戶部署實現的系統。
4)提供平常管理支持以優化數據庫的性能。
(4)如何修改數據庫引擎:
方式一:
修改配置文件my.ini
將mysql.ini另存爲my.ini,在[mysqld]後面添加default-storage-engine=InnoDB,重啓服務,數據庫默認的引擎修改成InnoDB
方式二:
在建表的時候指定
create table mytbl( id int primary key, name varchar(50) )type=MyISAM;
方式三:
建表後更改
alter table table_name type = InnoDB;
(5)怎麼查看修改爲功?
方式一:
show table status from table_name;
方式二:
show create table table_name
方式三:
使用數據庫管理工具啊。
2、MySQL各大存儲引擎:
最好先看下你下的MySQL支持什麼數據庫引擎
存儲引擎主要有: 1. MyIsam , 2. InnoDB, 3. Memory, 4. Blackhole, 5. CSV, 6. Performance_Schema, 7. Archive, 8. Federated , 9 Mrg_Myisam
可是咱們主要分析使用MyIsam 和InnoDB。其他略微帶過,詳情請分別百度。
(1)InnoDB:
定義:(默認的存儲引擎)
InnoDB是一個事務型的存儲引擎,有行級鎖定和外鍵約束。
Innodb引擎提供了對數據庫ACID事務的支持,而且實現了SQL標準的四種隔離級別,關於數據庫事務與其隔離級別的內容請見數據庫事務與其隔離級別這類型的文章。該引擎還提供了行級鎖和外鍵約束,它的設計目標是處理大容量數據庫系統,它自己其實就是基於MySQL後臺的完整數據庫系統,MySQL運行時Innodb會在內存中創建緩衝池,用於緩衝數據和索引。可是該引擎不支持FULLTEXT類型的索引,並且它沒有保存表的行數,當SELECT COUNT(*) FROM TABLE時須要掃描全表。當須要使用數據庫事務時,該引擎固然是首選。因爲鎖的粒度更小,寫操做不會鎖定全表,因此在併發較高時,使用Innodb引擎會提高效率。可是使用行級鎖也不是絕對的,若是在執行一個SQL語句時MySQL不能肯定要掃描的範圍,InnoDB表一樣會鎖全表。
//這個就是select鎖表的一種,不明確主鍵。增刪改查均可能會致使鎖全表,在之後咱們會詳細列出。 SELECT * FROM products WHERE name='Mouse' FOR UPDATE;
適用場景:
1)常常更新的表,適合處理多重併發的更新請求。
2)支持事務。
3)能夠從災難中恢復(經過bin-log日誌等)。
4)外鍵約束。只有他支持外鍵。
5)支持自動增長列屬性auto_increment。
MySQL官方對InnoDB的講解:
1)InnoDB給MySQL提供了具備提交、回滾和崩潰恢復能力的事務安全(ACID兼容)存儲引擎。
2)InnoDB鎖定在行級而且也在SELECT語句提供一個Oracle風格一致的非鎖定讀,這些特點增長了多用戶部署和性能。沒有在InnoDB中擴大鎖定的須要,由於在InnoDB中行級鎖定適合很是小的空間。
3)InnoDB也支持FOREIGN KEY強制。在SQL查詢中,你能夠自由地將InnoDB類型的表與其它MySQL的表的類型混合起來,甚至在同一個查詢中也能夠混合。
4)InnoDB是爲處理巨大數據量時的最大性能設計,它的CPU效率多是任何其它基於磁盤的關係數據庫引擎所不能匹敵的。
5) InnoDB被用來在衆多須要高性能的大型數據庫站點上產生。
補充:什麼叫事務?簡稱ACID
A 事務的原子性(Atomicity):指一個事務要麼所有執行,要麼不執行.也就是說一個事務不可能只執行了一半就中止了.好比你從取款機取錢,這個事務能夠分紅兩個步驟:1劃卡,2出錢.不可能劃了卡,而錢卻沒出來.這兩步必須同時完成.要麼就不完成.
C 事務的一致性(Consistency):指事務的運行並不改變數據庫中數據的一致性.例如,完整性約束了a+b=10,一個事務改變了a,那麼b也應該隨之改變.
I 獨立性(Isolation):事務的獨立性也有稱做隔離性,是指兩個以上的事務不會出現交錯執行的狀態.由於這樣可能會致使數據不一致.
D 持久性(Durability):事務的持久性是指事務執行成功之後,該事務所對數據庫所做的更改即是持久的保存在數據庫之中,不會平白無故的回滾.
(2)MyIsam:
定義:
MyIASM是MySQL默認的引擎,可是它沒有提供對數據庫事務的支持,也不支持行級鎖和外鍵,所以當INSERT(插入)或UPDATE(更新)數據時即寫操做須要鎖定整個表,效率便會低一些。
MyIsam 存儲引擎獨立於操做系統,也就是能夠在windows上使用,也能夠比較簡單的將數據轉移到linux操做系統上去。
意味着:引擎在建立表的時候,會建立三個文件,一個是.frm文件用於存儲表的定義,一個是.MYD文件用於存儲表的數據,另外一個是.MYI文件,存儲的是索引。操做系統對大文件的操做是比較慢的,這樣將表分爲三個文件,那麼.MYD這個文件單獨來存放數據天然能夠優化數據庫的查詢等操做。有索引管理和字段管理。MyISAM還使用一種表格鎖定的機制,來優化多個併發的讀寫操做,其代價是你須要常常運行OPTIMIZE TABLE命令,來恢復被更新機制所浪費的空間。
適用場景:
1)不支持事務的設計,可是並不表明着有事務操做的項目不能用MyIsam存儲引擎,能夠在service層進行根據本身的業務需求進行相應的控制。
2)不支持外鍵的表設計。
3)查詢速度很快,若是數據庫insert和update的操做比較多的話比較適用。
4)成天 對錶進行加鎖的場景。
5)MyISAM極度強調快速讀取操做。
6)MyIASM中存儲了表的行數,因而SELECT COUNT(*) FROM TABLE時只須要直接讀取已經保存好的值而不須要進行全表掃描。若是表的讀操做遠遠多於寫操做且不須要數據庫事務的支持,那麼MyIASM也是很好的選擇。
缺點:
就是不能在表損壞後恢復數據。(是不能主動恢復)
補充:ISAM索引方法–索引順序存取方法
定義:
是一個定義明確且歷經時間考驗的數據表格管理方法,它在設計之時就考慮到 數據庫被查詢的次數要遠大於更新的次數。
特性:
ISAM執行讀取操做的速度很快,並且不佔用大量的內存和存儲資源。
在設計之初就預想數據組織成有固定長度的記錄,按順序存儲的。—ISAM是一種靜態索引結構。
缺點:
1.它不 支持事務處理
2.也不可以容錯。若是你的硬盤崩潰了,那麼數據文件就沒法恢復了。若是你正在把ISAM用在關鍵任務應用程序裏,那就必須常常備份你全部的實 時數據,經過其複製特性,MYSQL可以支持這樣的備份應用程序。
(3)Memory(也叫HEAP)堆內存嘛:
定義:
使用存在內存中的內容來建立表。每一個MEMORY表只實際對應一個磁盤文件。MEMORY類型的表訪問很是得快,由於它的數據是放在內存中的,而且默認使用HASH索引。
可是一旦服務關閉,表中的數據就會丟失掉。 HEAP容許只駐留在內存裏的臨時表格。駐留在內存裏讓HEAP要比ISAM和MYISAM都快,可是它所管理的數據是不穩定的,並且若是在關機以前沒有進行保存,那麼全部的數據都會丟失。在數據行被刪除的時候,HEAP也不會浪費大量的空間。HEAP表格在你須要使用SELECT表達式來選擇和操控數據的時候很是有用。
適用場景:
1)那些內容變化不頻繁的代碼表,或者做爲統計操做的中間結果表,便於高效地堆中間結果進行分析並獲得最終的統計結果。
2)目標數據比較小,並且很是頻繁的進行訪問,在內存中存放數據,若是太大的數據會形成內存溢出。能夠經過參數max_heap_table_size控制Memory表的大小,限制Memory表的最大的大小。
3)數據是臨時的,並且必須當即可用獲得,那麼就能夠放在內存中。
4)存儲在Memory表中的數據若是忽然間丟失的話也沒有太大的關係。
注意: Memory同時支持散列索引和B樹索引,B樹索引可使用部分查詢和通配查詢,也可使用<,>和>=等操做符方便數據挖掘,散列索引相等的比較快可是對於範圍的比較慢不少。
特性要求:
1)要求存儲的數據是數據長度不變的格式,好比,Blob和Text類型的數據不可用(長度不固定的)。
2)要記住,在用完表格以後就刪除表格。
(4)Mrg_Myisam:(分表的一種方式–水平分表)
定義:
是一個相同的能夠被看成一個來用的MyISAM表的集合。「相同」意味着全部表一樣的列和索引信息。
也就是說,他將MyIsam引擎的多個表聚合起來,可是他的內部沒有數據,真正的數據依然是MyIsam引擎的表中,可是能夠直接進行查詢、刪除更新等操做。
好比:咱們可能會遇到這樣的問題,同一種類的數據會根據數據的時間分爲多個表,若是這時候進行查詢的話,就會比較麻煩,Merge能夠直接將多個表聚合成一個表統一查詢,而後再刪除Merge表(刪除的是定義),原來的數據不會影響。
(5)Blackhole(黑洞引擎)
定義
任何寫入到此引擎的數據均會被丟棄掉, 不作實際存儲;Select語句的內容永遠是空。
他會丟棄全部的插入的數據,服務器會記錄下Blackhole表的日誌,因此能夠用於複製數據到備份數據庫。
使用場景:
1)驗證dump file語法的正確性
2)以使用blackhole引擎來檢測binlog功能所須要的額外負載
3)充當日誌服務器
其他引擎,你們感興趣就各自先百度吧。本文主要是對比引擎使用以及其原理。
3、InnoDB和MyIsam使用及其原理對比:
(1)使用的效果與區別展現:
(一)在一個普通數據庫中建立兩張分別以MyIsam和InnoDB做爲存儲引擎的表。
create table testMyIsam( id int unsigned primary key auto_increment, name varchar(20) not null )engine=myisam;
create table testInnoDB( id int unsigned primary key auto_increment, name varchar(20) not null )engine=innodb;
嘿嘿嘿,,效果如圖,一會總結。
(二)對比插入效率(百萬級插入):(雖然速度上MyISAM快,可是增刪改是涉及事務安全的,因此用InnoDB相對好不少)
爲了更好地對比,咱們可使用函數的方式或者存儲過程的方式。博主採用存儲過程。(存儲過程在日後的章節會講到)
//建立存儲過程 delimiter $$ drop procedure if exists ptestmyisam; create procedure ptestmyisam() begin declare pid int ; set pid = 1000000; while pid>0 do insert into testmyisam(name) values(concat("fuzhu", pid)); set pid = pid-1; end while; end $$ //使用存儲過程: call ptestmyisam();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
//建立存儲過程(儘可能把Innodb的數量級壓低,否則,,卡在那裏半天也不奇怪) delimiter $$ drop procedure if exists ptestInndb; create procedure ptestInndb() begin declare pid int ; set pid = 1000000; while pid>0 do insert into testinnodb(name) values(concat("fuzhu", pid)); set pid = pid-1; end while; end $$ //使用存儲過程: call ptestInndb();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
本博主在幾回innodb測試百萬插入的時候,數據庫炸了(笑哭)。最終只成功插入1W條。可見效率對比。
固然innodb默認是開啓事務的,若是咱們把事務給停了,會快不少。
//停掉事務
set autocommit = 0; //調用存儲過程 call ptestInndb; //重啓事務 set autocommit = 1;
(三)對比更新:(雖然速度上MyISAM快,可是增刪改是涉及事務安全的,因此InnoDB相對好不少)
//耗時3秒多
update testinnodb set name = 'fuzhu' where id>0 and id<10000; //耗時0.171秒 update testmyisam set name = 'fuzhu' where id>0 and id<13525;
(四)查詢對比:
1)查詢總數目
select count(*) from testInnoDB; select count(*) from testMyIsam;
這就是innodb查一萬跟myisam查一百萬的區別??效果對比馬上出現。
2)查詢無索引的列:(這些都本身拿我給出或者本身寫的數據庫去體驗下吧,,差距很明顯)
select * from testMyIsam where name > "fuzhu100" ; select * from testInnoDB where name > "fuzhu100" ;
3)查詢有索引的列:
select * from testMyIsam where id > 10 ; select * from testinnodb where id > 10 ;
4)存儲大小:
testMyIsam 存了一百萬。testinnodb 存了兩萬。
(2)效果對比總述:
1)事務。MyISAM類型不支持事務處理等高級處理,而InnoDB類型支持,提供事務支持已經外部鍵等高級數據庫功能。
InnoDB表的行鎖也不是絕對的,假如在執行一個SQL語句時MySQL不能肯定要掃描的範圍,InnoDB表一樣會鎖全表,例如updatetable set num=1 where name like 「a%」
就是說在不肯定的範圍時,InnoDB仍是會鎖表的。
2)性能主題。MyISAM類型的表強調的是性能,其執行數度比InnoDB類型更快。
3)行數保存。InnoDB 中不保存表的具體行數,也就是說,執行select count() fromtable時,InnoDB要掃描一遍整個表來計算有多少行,可是MyISAM只要簡單的讀出保存好的行數便可。注意的是,當count()語句包含where條件時,兩種表的操做是同樣的。
4)索引存儲。對於AUTO_INCREMENT類型的字段,InnoDB中必須包含只有該字段的索引,可是在MyISAM表中,能夠和其餘字段一塊兒創建聯合索引。
MyISAM支持全文索引(FULLTEXT)、壓縮索引,InnoDB不支持
MyISAM的索引和數據是分開的,而且索引是有壓縮的,內存使用率就對應提升了很多。能加載更多索引,而Innodb是索引和數據是緊密捆綁的,沒有使用壓縮從而會形成Innodb比MyISAM體積龐大不小。
InnoDB存儲引擎被徹底與MySQL服務器整合,InnoDB存儲引擎爲在主內存中緩存數據和索引而維持它本身的緩衝池。InnoDB存儲它的表&索引在一個表空間中,表空間能夠包含數個文件(或原始磁盤分區)。這與MyISAM表不一樣,好比在MyISAM表中每一個表被存在分離的文件中。InnoDB 表能夠是任何尺寸,即便在文件尺寸被限制爲2GB的操做系統上。
5)服務器數據備份。InnoDB必須導出SQL來備份,LOAD TABLE FROM MASTER操做對InnoDB是不起做用的,解決方法是首先把InnoDB表改爲MyISAM表,導入數據後再改爲InnoDB表,可是對於使用的額外的InnoDB特性(例如外鍵)的表不適用。
並且MyISAM應對錯誤編碼致使的數據恢復速度快。MyISAM的數據是以文件的形式存儲,因此在跨平臺的數據轉移中會很方便。在備份和恢復時可單獨針對某個表進行操做。
InnoDB是拷貝數據文件、備份 binlog,或者用 mysqldump,在數據量達到幾十G的時候就相對痛苦了。
**6)鎖的支持。**MyISAM只支持表鎖。InnoDB支持表鎖、行鎖 行鎖大幅度提升了多用戶併發操做的新能。可是InnoDB的行鎖,只是在WHERE的主鍵是有效的,非主鍵的WHERE都會鎖全表的
//用於把表的拷貝從主服務器轉移到從屬服務器。 LOAD TABLE tbl_name FROM MASTER
(3)使用建議:
如下兩點必須使用 InnoDB:
1)可靠性高或者要求事務處理,則使用InnoDB。這個是必須的。
2)表更新和查詢都至關的頻繁,而且表鎖定的機會比較大的狀況指定InnoDB數據引擎的建立。
對比之下,MyISAM的使用場景:
1)作不少count的計算的。如一些日誌,調查的業務表。
2)插入修改不頻繁,查詢很是頻繁的。
MySQL可以容許你在表這一層應用數據庫引擎,因此你能夠只對須要事務處理的表格來進行性能優化,而把不須要事務處理的表格交給更加輕便的MyISAM引擎。對於 MySQL而言,靈活性纔是關鍵。
4、InnoDB和MyIsam引擎原理:
在此以前,先去理解什麼是聚簇和非聚簇索引。
(1)MyIASM引擎的索引結構:
MyISAM索引結構: MyISAM索引用的B+ tree來儲存數據,MyISAM索引的指針指向的是鍵值的地址,地址存儲的是數據。
B+Tree的數據域存儲的內容爲實際數據的地址,也就是說它的索引和實際的數據是分開的,只不過是用索引指向了實際的數據,這種索引就是所謂的非彙集索引。
所以,過程爲: MyISAM中索引檢索的算法爲首先按照B+Tree搜索算法搜索索引,若是指定的Key存在,則取出其data域的值,而後以data域的值爲地址,根據data域的值去讀取相應數據記錄。
(2)InnoDB引擎的索引結構:
也是B+Treee索引結構。Innodb的索引文件自己就是數據文件,即B+Tree的數據域存儲的就是實際的數據,這種索引就是彙集索引。這個索引的key就是數據表的主鍵,所以InnoDB表數據文件自己就是主索引。
InnoDB的輔助索引數據域存儲的也是相應記錄主鍵的值而不是地址,因此當以輔助索引查找時,會先根據輔助索引找到主鍵,再根據主鍵索引找到實際的數據。因此Innodb不建議使用過長的主鍵,不然會使輔助索引變得過大。
建議使用自增的字段做爲主鍵,這樣B+Tree的每個結點都會被順序的填滿,而不會頻繁的分裂調整,會有效的提高插入數據的效率。
上圖,能夠看到葉節點包含了完整的數據記錄。這種索引叫作彙集索引。由於InnoDB的數據文件自己要按主鍵彙集,因此InnoDB要求表必須有主鍵(MyISAM能夠沒有),若是沒有顯式指定,則MySQL系統會自動選擇一個能夠惟一標識數據記錄的列做爲主鍵,若是不存在這種列,則MySQL自動爲InnoDB表生成一個隱含字段做爲主鍵,這個字段長度爲6個字節,類型爲長整形。
並且,與MyISAM索引的不一樣是InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。換句話說,InnoDB的全部輔助索引都引用主鍵做爲data域。
所以,過程爲:將主鍵組織到一棵B+樹中,而行數據就儲存在葉子節點上,若使用」where id = 13」這樣的條件查找主鍵,則按照B+樹的檢索算法便可查找到對應的葉節點,以後得到行數據。若對Name列進行條件搜索,則須要兩個步驟:第一步在輔助索引B+樹中檢索Name,到達其葉子節點獲取對應的主鍵。第二步使用主鍵在主索引B+樹種再執行一次B+樹檢索操做,最終到達葉子節點便可獲取整行數據。
5、剩餘引擎的使用DEMO(主要是Mrg_Myisam分表)
Memory(Heap):
CREATE TABLE tbHeap ( id int unsigned primary key auto_increment, name varchar(20) not null ) TYPE=Heap
(1)Mrg_Myisam引擎分表:
(一)先建立兩張user表,也就是說我要把用戶表進行水平分表(由於用戶太多啦,10億)
//用戶表一
CREATE TABLE IF NOT EXISTS `user1` ( `id` int(11) NOT NULL , `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; //用戶表二 CREATE TABLE IF NOT EXISTS `user2` ( `id` int(11) NOT NULL , `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; //分別插入兩條測試數據先 INSERT INTO `user1` (`name`) VALUES('輔助'); INSERT INTO `user2` (`name`) VALUES('JackFrost');
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
分表的要求:
1)分表必須使用MyISAM存儲引擎;
2)每一個分表的表結構必須相同;
3)MySQL必須具備存儲分表數據文件和索引文件的目錄的讀寫權限;
4)必須啓用MySQL的符號連接支持功能。
文件存儲:
1)MYD文件是MyISAM表的數據文件;
2)MYI文件是MyISAM表的索引文件;
3)frm文件用於存儲MyISAM表的表結構。
(二)最後建立一個MERGE表,做爲一個分發做用的總表。
CREATE TABLE IF NOT EXISTS `alluser` ( `id` int(11) NOT NULL , `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MRG_MYISAM DEFAULT CHARSET=utf8 UNION=(user1,user2) ;
(三)測試:
1. 查詢:
select id,name from alluser;
可見根據總表把全部數據都查出來了
2. 然而,當你測試插入的時候:
你會發現,總表只有只讀權限
3. 可是咱們又想在總表去插入,怎麼辦呢??
容許經過總表插入數據,數據存儲在MRG文件列出的第一個分表之中。例如,執行如下SQL語句,將總表的INSERT_METHOD修改成FIRST,而後經過總表插入一條數據:
//就是插入總表的時候,其實也是插入到第一個分表。
ALTER TABLE `test_engine`.`alluser` INSERT_METHOD = FIRST; INSERT INTO `alluser` (id,`name`) VALUES(2,'插入到第一個分表');
而,容許經過總表插入數據,數據存儲在MRG文件列出的最後一個分表之中。例如,執行如下SQL語句,將總表的INSERT_METHOD修改成LAST,而後經過總表插入一條數據:
//就是插入總表的時候,其實也是插入到最後一個分表。
ALTER TABLE `test_engine`.`alluser` INSERT_METHOD = LAST;
注意INSERT_METHOD :
INSERT_METHOD選項只會影響經過總表插入(INSERT)數據的行爲,經過總表對數據進行刪除(DELETE)、查詢(SELECT)、修改(UPDATE)、清空(TRUNCATE)都不會受影響。
(2)項目中如何使用MRG_MYISAM總表:
(一)插入(INSERT)數據時,須要根據給定的路由策略將新數據分別插入不一樣的子表,此處採用對id進行模3計算(可能結果爲0、一、2)來決定插入哪一個子表。
因此咱們須要建立一張表專門去建立id。
CREATE TABLE `create_id` ( `id` INT(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=MyISAM ;
(二)ORM框架的時候使用上面這個表生成id
insert into create_id () values();
(三)真正插入的時候:
先獲取ID,而後根據拿到的建立ID去插入到分表。
INSERT INTO {$table_name} (id, name) VALUES ('{$id}');
(四)獲取表名和ID:
這個就須要咱們自定義本身的規則了。好比取餘、好比範圍預判斷。
其餘的刪除(DELETE)、查詢(SELECT)、修改(UPDATE)、清空(TRUNCATE)等操做均可以經過總表alluser完成。
基於MRG_MYISAM存儲引擎實現的分表機制,比較適用於插入和查詢頻率較高的場景。因爲MyISAM具備表級別的鎖機制,因此不適用於更新頻率較高的場景。
(3)MRG_MYISAM分表的優勢:
(一)適用於存儲日誌數據。例如,能夠將不一樣月份的數據存入不一樣的表,而後使用一些工具壓縮數據,最後經過一張MRG_MYISAM表來查詢這些數據。
(二)能夠得到更快的速度。能夠根據某種指標,將一張只讀的大表分割成若干張小表,而後將這些小表分別放在不一樣的磁盤上存儲。當須要讀取數據時,MERGE表能夠將這些小表的數據組織起來,就好像使用先前的大表同樣,可是速度會快不少。
(三)能夠提升搜索效率。能夠根據某種指標將一張只讀的大數據表分割爲若干個小表,而後根據不一樣的查詢維度,能夠獲得若干種小表的組合,而後再爲這些組合分別建立不一樣的MERGE表。例如,有一張只讀的大數據表T,分割爲T一、T二、T三、T4,共4張小表,有兩種查詢維度A和B,A能夠獲得小表組合T一、T2和T3,B能夠獲得小表組合T二、T3和T4,分別爲A和B建立兩個MERGE表,也就是M1和M2,這兩個MERGE表分別關聯的小表是存在交疊的。
(四)能夠更加有效的修復表。修復單個的小表要比修復大數據表更加容易。
(五)多個子表映射至一個總表的速度極快。由於MERGE表自己不會存儲和維護任何索引,索引都是由各個關聯的子表存儲和維護的,因此建立和從新映射MERGE表的速度很是快。
(六)不受操做系統的文件大小限制。單個表會受到文件大小的限制,可是拆分紅多個表,則能夠無限擴容。
(七)MERGE表還能夠用來給單個表建立別名,而且幾乎不會影響性能。
(4)使用MRG_MyISAM分表的必須思考問題:(針對總表)
(一)總表(MERGE表)必須使用MRG_MyISAM存儲引擎,子表必須使用MyISAM存儲引擎,不可避免會受到MyISAM存儲引擎的限制。(好比不支持事務)
(二)MERGE表不能使用某些MyISAM特性。例如,雖然能夠爲子表建立全文索引,可是卻不能使用全文索引,只能經過MERGE表查詢數據。
(三)若使用ALTER TABLE語句修改總表的存儲引擎,那麼會當即丟失總表和子表的映射關係,而且會將全部子表的數據拷貝至修改後的新表。
(四)總表和子表的主鍵都不能使用自動增加(auto increment)。
(五)子表之間不能保證惟一鍵約束,只能保證單個子表內部的惟一性約束。也就是說,直接查總表所有,id可能會重複。
(六)因爲不能保證惟一鍵約束,致使REPLACE語句的行爲會不可預期,INSERT … ON DUPLICATE KEY UPDATE語句也有相似問題。所以,只能使用路由策略,對子表使用這些語句,而不能對總表使用。
(七)當正在使用總表時,不能對任何子表執行ANALYZE TABLE、REPAIR TABLE、OPTIMIZE TABLE、ALTER TABLE、DROP TABLE、DELETE或TRUNCATE TABLE語句,不然會致使不可預期的結果。
(八)總表和子表的表結構必須徹底一致。
(九)總表能夠映射的全部子表的總行數上限爲 2的64次方 行。
(十)不支持INSERT DELAYED語句。