こんにちは、かつコーチです。
入門編ではMySQLのインストールとGUIツールの使い方を解説しました。
ここからはアーキテクチャ編として、MySQLの内部の仕組みに踏み込んでいきます。
第1回は、MySQLの心臓部とも言えるストレージエンジン、特にInnoDBとMyISAMの違いを解説します。
ストレージエンジンとは?
データの実際の保存方式を担う仕組み
ストレージエンジンとは、テーブルに保存されたデータを、実際にディスク上でどう管理するかを決める仕組みです。
MySQLは同じSQL文法・同じサーバーの中で、テーブルごとに異なるストレージエンジンを選べるという特徴があります。
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
member_id INT NOT NULL,
status VARCHAR(20) NOT NULL
) ENGINE=InnoDB;
ENGINE=InnoDBのように指定することで、そのテーブルがどのストレージエンジンを使うかを決められます。
省略した場合は、MySQL 8.0系ではデフォルトでInnoDBが使われます。
現在の標準はInnoDB
MySQL 5.5以降、デフォルトのストレージエンジンはMyISAMからInnoDBに変わりました。
つまりMySQL 8.0系では、特別な理由がない限りInnoDBを使うのが基本方針です。
それでも「InnoDBとMyISAM、何が違うのか」を理解しておくことは、古いシステムの保守や設計判断において重要な知識になります。
InnoDBとMyISAMの違い
トランザクション対応の有無
InnoDB最大の特徴は、トランザクションに対応していることです。
トランザクションとは、複数のSQL文を1つのまとまりとして扱い、すべて成功するか、すべて失敗して元に戻すかのどちらかにする仕組みです。
START TRANSACTION;
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
COMMIT;
送金処理のように「片方だけ成功する」ことが許されない処理には、トランザクションに対応したInnoDBが必須です。
一方MyISAMはトランザクションに対応していないため、途中でエラーが起きても処理を巻き戻せません。
外部キー制約の対応
InnoDBはFOREIGN KEY制約による参照整合性(親テーブルに存在しない値を子テーブルに入れさせない制約)をサポートしています。
MyISAMは外部キー制約を認識しないため、SQL文の記述自体は通っても、実際には制約として機能しません。
-- InnoDBなら参照整合性が効くが、MyISAMでは無視される
ALTER TABLE orders ADD CONSTRAINT fk_orders_member
FOREIGN KEY (member_id) REFERENCES members(id);
ロックの粒度の違い
InnoDBは行ロック(更新する行だけをロックする方式)を採用しているのに対し、MyISAMはテーブルロック(テーブル全体をロックする方式)です。
複数人が同時に書き込むアプリケーションでは、テーブルロックだと1件の更新中に他の更新がすべて待たされてしまいます。
同時アクセスが発生するWebサービスにおいて、この違いはパフォーマンスに直結する重要なポイントです。
比較表と選び方の判断軸
機能ごとの比較
| 項目 | InnoDB | MyISAM |
|---|---|---|
| トランザクション | 対応 | 非対応 |
| 外部キー制約 | 対応 | 非対応 |
| ロックの粒度 | 行ロック | テーブルロック |
| クラッシュ耐性 | 高い | 低い |
| 全文検索インデックス | 対応(5.6以降) | 対応 |
| 読み取り速度(単純なSELECT) | 標準的 | やや高速な場合がある |
実務での選び方
現在の実務においては、特別な理由がない限りInnoDBを選ぶのが基本方針です。
MyISAMを検討する余地があるとすれば、「更新がほぼ発生しない、参照専用の大規模ログテーブル」のような、トランザクションも外部キーも不要なケースに限られます。
私が過去に保守したシステムの中には、古いバージョンのMySQLで作られたためテーブルがMyISAMのままになっているものがありました。
ある日、書き込み処理中に予期せぬサーバー再起動が発生し、MyISAMのテーブルが破損してデータの一部が読み取れなくなるという事故を経験しました。
InnoDBであればトランザクションログから復旧できた可能性が高く、以来「新規テーブルは必ずInnoDB」を徹底するようにしています。
つまずきやすいポイント:既存テーブルのエンジン確認
気づかずMyISAMを使い続けているケース
❌ Before:ENGINE指定をせずCREATE TABLEし、確認もしない
CREATE TABLE logs (
id INT PRIMARY KEY AUTO_INCREMENT,
message TEXT
);
古いバージョンからアップグレードしてきたシステムや、他社から引き継いだシステムでは、意図せずMyISAMのテーブルが混在していることがあります。
✅ After:エンジンを明示的に確認・指定する
SHOW TABLE STATUS WHERE Name = 'logs';
SHOW TABLE STATUSの結果にあるEngine列を確認すれば、現在使われているストレージエンジンが分かります。
MyISAMになっていた場合は、以下のように変換できます。
ALTER TABLE logs ENGINE=InnoDB;
保守を引き継いだシステムでは、このSHOW TABLE STATUSを主要テーブルに対して一度実行し、エンジンの棚卸しをしておくことをおすすめします。
まとめ
この記事のポイント
- ストレージエンジンはテーブルごとに選べる、データの保存方式を決める仕組み
- InnoDBはトランザクション・外部キー制約・行ロックに対応し、MySQL 8.0系の標準
- MyISAMはテーブルロックでクラッシュ耐性も低く、現在は積極的に選ぶ理由が少ない
- 既存テーブルは
SHOW TABLE STATUSでエンジンを確認する習慣をつける
次に読むべき記事
ストレージエンジンの違いが分かったところで、次はMySQL全体がどんなレイヤー構造で動いているのかを見ていきましょう。
→ 次の記事:MySQLのアーキテクチャ全体像
タグ: MySQL, 中級者向け, アーキテクチャ