在 MySQL 中,表的存儲引擎決定了數據的存儲方式、索引結構、鎖粒度、事務支持等核心特性。常見場景如:歷史表默認 MyISAM 需遷移至 InnoDB 獲得事務支持;或全文搜索表需轉為 MyISAM 利用原生全文索引。本文詳述修改方法、引擎差異與操作注意事項。
-- 轉為 MyISAM
ALTER TABLE `table_name` ENGINE = MyISAM;
-- 轉為 InnoDB
ALTER TABLE `table_name` ENGINE = InnoDB;
-- 查看當前引擎
SHOW TABLE STATUS LIKE 'table_name'\G
-- 或
SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'db_name';
| 特性 | MyISAM | InnoDB |
|---|---|---|
| 事務支持 | ❌ 不支持 | ✅ ACID 完整支持 |
| 鎖粒度 | 表級鎖 | 行級鎖(含間隙鎖、Next-Key Lock) |
| 外鍵約束 | ❌ 不支持 | ✅ 支持 |
| 崩潰恢復 | 需人工修復 | 自動恢復 |
| 全文索引 | 5.6+ 原生支持 | 5.6+ 原生支持 |
| 空間索引 | ✅ | 5.7+ 支持 |
| 主鍵查詢 | 需回表 | 聚簇索引,極快 |
| 計數優化 | COUNT(*) 極快(存儲行數) | 需全表掃描或輔助表維護 |
| 適用場景 | 只讀/多讀少寫、全文搜索、日志歸檔 | 高併發寫入、事務業務、關鍵業務數據 |
ALTER TABLE `orders` ENGINE = InnoDB;
使用 pt-online-schema-change(Percona Toolkit)或 gh-ost 進行在線無鎖轉換:
pt-online-schema-change --alter "ENGINE=InnoDB" D=db_name,t=big_table --execute --max-load "Threads_running=50" --critical-load "Threads_running=100"
#!/bin/bash
DB="your_db"
for tbl in $(mysql -N -e "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='$DB' AND ENGINE='MyISAM';"); do
echo "Converting $tbl ..."
mysql -e "ALTER TABLE \`$DB\`.\`$tbl\` ENGINE=InnoDB;"
done
ALTER TABLE 會重建表,持有排他鎖,大表會導致業務長時間不可寫入。ALTER TABLE t AUTO_INCREMENT=1 重置,InnoDB 不允許小於當前最大值。innodb_buffer_pool_size(物理內存 60-80%)、innodb_log_file_size(1-4GB)、innodb_flush_log_at_trx_commit=1、sync_binlog=1。INSERT、關閉 autocommit、調大 innodb_log_buffer_size。ARCHIVE 引擎(高壓縮、僅支持插入/查詢),節省存儲成本。引擎選型無絕對優劣,關鍵在於業務特徵匹配。現代 MySQL(5.7/8.0)InnoDB 已成唯一通用首選,MyISAM 僅保留於特定只讀/全文/歸檔場景。轉換操作務必在低峰期、備份驗證後、配合在線工具執行,確保業務零感知遷移。