不過,在這幾年的發展下,MySQL也導入了InnoDB(另一種數據庫引擎),以強化參考完整性與並發違規處理機制,後來就逐漸取代MyISAM。InnoDB,是MySQL的數據庫引擎之一,為MySQL AB發布binary的標準之一。InnoDB由Innobase Oy公司所開發,2006年五月時由甲骨文公司併購。與傳統的ISAM與MyISAM相比,InnoDB的最大特色就是支持了ACID兼容的事務(Transaction)功能,類似於PostgreSQL。目前InnoDB採用雙軌制授權,一是GPL授權,另一是專有軟件授權。
MyISAM與InnoDB的區別是什麼?
1、 存儲結構
MyISAM:每個MyISAM在磁盤上存儲成三個文件。第一個文件的名字以表的名字開始,擴展名指出文件類型。.frm文件存儲表定義。數據文件的擴展名為.MYD (MYData)。索引文件的擴展名是.MYI (MYIndex)。InnoDB:所有的表都保存在同一個數據文件中(也可能是多個文件,或者是獨立的表空間文件),InnoDB表的大小只受限於操作系統文件的大小,一般為2GB。
2、 存儲空間
MyISAM:可被壓縮,存儲空間較小。支持三種不同的存儲格式:靜態表(默認,但是注意數據末尾不能有空格,會被去掉)、動態表、壓縮表。InnoDB:需要更多的內存和存儲,它會在主內存中建立其專用的緩衝池用於高速緩衝數據和索引。
首先以一張圖簡單展示InnoDB 的存儲引擎的體系架構.從圖中可見, InnoDB 存儲引擎有多個內存塊,這些內存塊組成了一個大的內存池,主要負責如下工作:
- 維護所有進程/線程需要訪問的多個內部數據結構
- 緩存磁盤上的數據, 方便快速讀取, 同時在對磁盤文件修改之前進行緩存
- 重做日誌(redo log)緩衝
3、 可移植性、備份及恢復
MyISAM:數據是以文件的形式存儲,所以在跨平台的數據轉移中會很方便。在備份和恢復時可單獨針對某個表進行操作。InnoDB:免費的方案可以是拷貝數據文件、備份binlog,或者用mysqldump,在數據量達到幾十G的時候就相對痛苦了。
Binary Copy (直接複製資料庫檔案) 開門見山的說,非常不建議你這樣子做。MySQL 支援許多種不同的 Storage Engine,但並不是每一種 Storage Engine 都是 Binary Portable,意思就是說不是每一種 Storage Engine 都可以讓你把資料庫檔案直接複製到另外一台 MySQL Server,然後還可以正常運作的。
mysqldump, 這種方式不僅適用於InnoDB,還適用於其它類型的存儲引擎,如MyISAM。備份的時候將數據庫備份成SQL(包含drop,create,insert等語句),恢復的時候直接導入即可。屬於邏輯備份。
利用binary logs, 需要開啟log-bin, 所有的更新操作都會被寫到binary file裡。恢復的時候mysqlbinlog binlog_file | mysql,這種方式基本上可以用在在線備份上。屬於邏輯備份。
4、 事務支持
MyISAM:強調的是性能,每次查詢具有原子性,其執行數度比InnoDB類型更快,但是不提供事務支持。InnoDB:提供事務支持事務,外部鍵等高級數據庫功能。具有事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe (ACID compliant))型表。
- A atomicity 即原子性
- C consistency 即一致性
- I isolation 即隔離性
5、 AUTO_INCREMENT
MyISAM:可以和其他字段一起建立聯合索引。引擎的自動增長列必須是索引,如果是組合索引,自動增長可以不是第一列,他可以根據前面幾列進行排序後遞增。InnoDB:InnoDB中必須包含只有該字段的索引。引擎的自動增長列必須是索引,如果是組合索引也必須是組合索引的第一列。
6、 表鎖差異
MyISAM:只支持表級鎖,用戶在操作myisam表時,select,update,delete,insert語句都會給表自動加鎖,如果加鎖以後的表滿足insert並發的情況下,可以在表的尾部插入新的數據。InnoDB:支持事務和行級鎖,是innodb的最大特色。行鎖大幅度提高了多用戶並發操作的新能。但是InnoDB的行鎖,只是在WHERE的主鍵是有效的,非主鍵的WHERE都會鎖全表的。
InnoDB表的行鎖也不是絕對的,假如在執行一個SQL語句時MySQL不能確定要掃描的範圍,InnoDB表同樣會鎖全表,例如update table set num=1 where name like “%aaa%”
7、 全文索引
MyISAM:舊版的MySQL的全文索引只能用在MyISAM表格的char、varchar和text的字段上。InnoDB:從MySQL5.6版本開始支持InnoDB引擎的全文索引,語法層面上大多數兼容之前MyISAM的全文索引模式。所謂全文索引,是一種通過建立倒排索引,快速匹配文檔的方式。MySQL支持三種模式的全文檢索模式:。
從MySQL 5.7.6開始,MySQL內置了ngram全文檢索插件,用來支持中文分詞,並且對MyISAM和InnoDB引擎有效。在全文索引中,ngram就是一段文字裡面連續的n個字的序列。本文將對MySQL5.7的中文全文索引做簡單測試。
8、 表主鍵
MyISAM:允許沒有任何索引和主鍵的表存在,索引都是保存行的地址。InnoDB:如果沒有設定主鍵或者非空唯一索引,就會自動生成一個6字節的主鍵(用戶不可見),數據是主索引的一部分,附加索引保存的是主索引的值的數據列。
9、 表的具體行數
MyISAM:保存有表的總行數,如果select count( ) from table;會直接取出出該值。InnoDB:沒有保存表的總行數,如果使用select count( ) from table;就會遍歷整個表,消耗相當大,但是在加了wehre條件後,myisam和innodb處理的方式都一樣。
10、 CURD操作
MyISAM:如果執行大量的SELECT,MyISAM是更好的選擇。InnoDB:如果你的數據執行大量的INSERT或UPDATE,出於性能方面的考慮,應該使用InnoDB表。DELETE從性能上InnoDB更優,但DELETE FROM table時,InnoDB不會重新建立表,而是一行一行的刪除,在innodb上如果要清空保存有大量數據的表,最好使用truncate table這個命令。
Mysql的BTree索引使用的是B數中的B Tree,但對於主要的兩種儲存引擎的實現方式是不同的。
MyISAM: B Tree葉節點的data域存放的是資料記錄的地址。在索引檢索的時候,首先按照B Tree搜尋演算法搜尋索引,如果指定的Key存在,則取出其data域的值,然後以data域的值為地址讀取相應的資料記錄。這被稱為“非聚簇索引”。
InnoDB: 其資料檔案本身就是索引檔案。相比MyISAM,索引檔案和資料檔案是分離的,其表資料檔案本身就是按B Tree組織的一個索引結構,樹的葉節點data域儲存了完整的資料記錄。這個索引的key是資料表的主鍵,因此InnoDB表資料檔案本身就是主索引。這被稱為“聚簇索引(或聚集索引)”。而其餘的索引都作為輔助索引,輔助索引的data域儲存相應記錄主鍵的值而不是地址,這也是和MyISAM不同的地方。在根據主索引搜尋時,直接找到key所在的節點即可取出資料;在根據輔助索引查詢時,則需要先取出主鍵的值,在走一遍主索引。 因此,在設計表的時候,不建議使用過長的欄位作為主鍵,也不建議使用非單調的欄位作為主鍵,這樣會造成主索引頻繁分裂。 PS:整理自《Java工程師修煉之道》
11、 外鍵
MyISAM:不支持InnoDB:在InnoDB存儲引擎中,對於一個外鍵列,如果沒有顯示地對這個列加索引,InnoDB存儲引擎會自動對其加一個索引,因為這樣可以避免表鎖。這比Oracle數據庫做得好,Oracle數據庫不會自動添加索引,用戶必須自己手動添加,這也導致了Oracle數據庫中可能產生死鎖。
外鍵具有保持數據完整性和一致性的機制,對業務處理有著很好的校驗作用。
白話簡介
user 表:id 為主鍵
profile 表: uid 為主鍵
簡單來說,若表profile 的uid 列作為表外鍵(外建名稱:user_profile),以表user 做為主表,以其id列做為參照(references),且聯動刪除/更新操作(on delete /update cascade)。則user表中刪除id 為1 的記錄,會聯動刪除profile 中uid 為1 的記錄。user 表中更新id 為1 的記錄至id 為2,則profile 表中uid 為1 的記錄也會被聯動更新至 uid 為2,這樣即保持了數據的完整性和一致性。
沒有留言:
張貼留言