MySQL 支援 CREATE TABLE ... ENGINE=InnoDB 或 ALTER TABLE t ENGINE=InnoDB 瞬時切換,**無需重啟、無需遷移數據**(內部複製表、重放變更、切換)。
| 引擎 | 事務 | 鎖粒度 | 外鍵 | 全文索引 | 適用場景 | 缺點 |
|---|---|---|---|---|---|---|
| ISAM | ❌ | 表鎖 | ❌ | ❌ | 唯讀/極少寫、歷史數據歸檔 | 不支援事務、崩潰不可恢復、已廢棄 (5.1 移除) |
| MyISAM | ❌ | 表鎖 | ❌ | ✅ (5.6+) | 讀多寫少、日誌分析、只讀報表、全文搜索 (舊版) | 無事務、無行鎖、崩潰需修復、表鎖並發差 |
| HEAP (MEMORY) | ❌ | 表鎖 | ❌ | ❌ | 臨時表、查詢緩存、中間結果集、會話級數據 | 重啟數據丟失、不支援 BLOB/TEXT、表鎖、定長行 |
| InnoDB | ✅ (ACID) | 行鎖 | ✅ | ✅ (5.6+) | 核心業務、高併發寫入、事務一致性、外鍵約束 | 空間佔用大、全表掃描慢於 MyISAM、無壓縮 (早期版本) |
| BDB (BerkeleyDB) | ✅ | 頁鎖 | ✅ | ❌ | 歷史替代 InnoDB,現已廢棄 (5.1 移除) | 頁鎖並發差、功能弱於 InnoDB、Oracle 收購後停止維護 |
-- 建表指定
CREATE TABLE t (id INT PRIMARY KEY, data VARCHAR(100)) ENGINE=InnoDB;
-- 現有表切換 (線上可執行,5.6+ 支援 Online DDL)
ALTER TABLE t ENGINE=InnoDB;
-- 批量切換腳本
SELECT CONCAT('ALTER TABLE ', TABLE_NAME, ' ENGINE=InnoDB;')
FROM information_schema.TABLES
WHERE TABLE_SCHEMA='mydb' AND ENGINE='MyISAM';
-- 臨時表典型用法
CREATE TEMPORARY TABLE tmp_session ENGINE=MEMORY
SELECT user_id, COUNT(*) AS cnt FROM logs WHERE dt>='2024-01-01' GROUP BY user_id;
-- 用完即刪
DROP TEMPORARY TABLE tmp_session;
-- ⚠️ 重啟前未刪除 = 內存洩漏 + 數據丟失
極客可基於 MySQL++ 編寫自定義存儲引擎 (如接入 Kafka、Redis、HDFS、區塊鏈),但門檻極高,**生產環境極不推薦**,維護成本不可控。
SHOW TABLE STATUS FROM db_name LIKE 't'\G
-- 或
SHOW CREATE TABLE t\G
-- 關鍵字段: Engine=InnoDB
IF 需要事務/外鍵/行鎖/高併發寫入:
ENGINE=InnoDB -- 95% 場景首選
ELIF 純只讀/歸檔/全文搜索 (5.6 前) / 極度省內存:
ENGINE=MyISAM
ELIF 臨時中間結果/會話緩存/極速讀寫/可接受重啟丟失:
ENGINE=MEMORY
ELSE:
ENGINE=InnoDB -- 兜底最安全
ROW_FORMAT=COMPRESSED)金句:引擎是表的屬性,不是庫的屬性。同一個庫裡,訂單表用 InnoDB 保證錢不亂,日誌表用 MyISAM 省空間,Session 表用 MEMORY 追極速。**按業務特性分表選引擎,才是 MySQL 靈活性的正確打開方式**。