2015年3月3日 星期二

MySQL 中MyISAM 與 InnoDB 的差異


MyISAM與InnoDB這兩個 engine 是在 MySQL 中最常用到的兩個 engine。
MyISAM 是在 MySQL 5.1 之前的 default engine,InnoDB 則是 MySQL 5.5 之後的 default engine。
大多數不換 InnoDB 有幾個原因:
1. InnoDB 佔用的空間比較大 - 延伸閱讀( Mobile01-現在SSD硬碟可以拿來跑資料庫嗎? )
2. InnoDB 不好備份
3. MyISAM 效能比較好(只讀)

MYISAM:
1. MYISAM supports Table-level Locking - MyISAM支援Table-level的鎖定
2. MyISAM designed for need of speed - 速度較快
3. MyISAM does not support foreign keys hence we call MySQL with MYISAM is DBMS - 不支援外鍵
4. MyISAM stores its tables, data and indexes in diskspace using separate three different files. (tablename.FRM, tablename.MYD, tablename.MYI) - 儲存資料表、資料、indexes在硬碟空間的三個不同檔案上( *.FRM, *.MYD, *.MYI )
5. MYISAM not supports transaction. You cannot commit and rollback with MYISAM. Once you issue a command it’s done. - 不支援交易。不能commit和rollback
6. MYISAM supports fulltext search - 支援全文搜索(Innodb要到5.6.4以上才支援)
註:
MySQL 5.6.21,在innodb新增fulltext index後,在/var/lib/mysql/db_name/ 下會產生 FTS_0000000000000780_BEING_DELETED.ibd ... 等類似檔案,刪除fulltext index後要執行 mysql> OPTIMIZE TABLE innodb_table_name; 才會刪掉他們
7. You can use MyISAM, if the table is more static with lots of select and less update and delete. - 選擇MyISAM,如果資料表select很多且update和delete很少

INNODB:
1. InnoDB supports Row-level Locking (multi processing on single table) - 支援Row-level 鎖定
2. InnoDB designed for maximum performance when processing high volume of data - 處理大量資料時效能較好
3. InnoDB support foreign keys hence we call MySQL with InnoDB is RDBMS - 支援外鍵
4. InnoDB stores its tables and indexes in a tablespace - 儲存資料表和indexes在tablespace
5. InnoDB supports transaction. You can commit and rollback with InnoDB - 支援交易,可以commit和rollback

總結:
最大的差別在於"referential integrity"( 引用完整性,foreign key )和"transactions"( 交易,commit and rollback )
Frequent reading, almost no writing( 頻繁的讀,幾乎沒寫 )              => MyISAM
Full-text search in MySQL <= 5.5 ( 當MySQL版本<=5.5需要全文搜索時 ) => MyISAM
其他情況,用Innodb會比較好

正規化
有可能會因為 MyISAM 卡 query 的問題而設計出非正規化的 schema。用 InnoDB 可能可以正規化,用適當的設備成本 (像是適當使用 JOIN) 降低人力維護成本。

有嚴格資料正確性需求的 Query 使用 Transaction
像是金流相關系統,一筆購買紀錄可能要修改好幾個表格。用 MyISAM 時必須對好幾個表格使用 TABLE LOCK (仍然有 atomic 問題),現在可以用 transaction 解決。

檢查表是Innodb還是MyISAM
mysql> SHOW TABLE STATUS FROM `database`; #檢查資料庫
or
mysql> SHOW TABLE STATUS FROM `database` LIKE 'tablename'; #指定資料表

轉換 MyISAM tabe 成 InnoDB
(先備份 - 備份InnoDB只需要備份 /var/lib/mysql 目錄即可)
方法一、使用ALTER TABLE
mysql> ALTER TABLE salary_myisam ENGINE = InnoDB;
轉回MyISAM
mysql> ALTER TABLE salary_myisam ENGINE = MyISAM;
用ALTER TABLE特點:
a、適合所有儲存引擎。
b、轉換過程會耗費大量時間。
c、轉換時候源表會被讀加鎖。
方法二、使用mysqldump,然後修改sql的CREATE TALBE 語句

參考資料:
https://blog.gslin.org/archives/2012/11/24/3034/mysql-%E4%B8%AD%EF%BC%8Cmyisam-%E8%88%87-innodb-%E5%B8%B6%E4%BE%86%E7%9A%84%E5%B7%AE%E7%95%B0/ MySQL 中,MyISAM 與 InnoDB 帶來的差異...[中文]
http://stackoverflow.com/questions/20148/myisam-versus-innodb MyISAM versus InnoDB
http://stackoverflow.com/questions/12614541/whats-the-difference-between-myisam-and-innodb What's the difference between MyISAM and InnoDB?
http://stackoverflow.com/questions/4515490/how-do-i-know-if-a-mysql-table-is-using-myisam-or-innodb-engine 檢查資料表engine是innodb還是myisam
http://fecbob.pixnet.net/blog/post/43281382-mysql%E8%B3%87%E6%96%99%E5%BA%AB%E8%BD%89%E6%8F%9B%E8%A1%A8%E7%9A%84%E5%84%B2%E5%AD%98%E5%BC%95%E6%93%8E%E7%9A%84%E6%96%B9%E6%B3%95 MySQL資料庫轉換表的儲存引擎的方法

1 則留言: