先日、MySQLを5.7から8.0にアップグレードした際にクエリが突然動かなくなり、冷や汗をかく事態に直面しました。
原因を調べたところ、テーブル名に予約語を使っていたため、構文エラーが発生していました...
同じようなトラブルを防ぐためにも、識別子と予約語の基本について整理することにしました。
識別子って何?
簡単に言うと、識別子はデータベースの中でテーブルやカラムなどに付ける名前のこと。
以下のようなデータベースオブジェクトの名前を指します。
・データベース名
・テーブル名
・カラム名
・インデックス名
・ビュー名
・ストアドプロシージャやトリガー名
予約語って何?
予約語とは、MySQLが「これだけは特別な意味だから使わないでね」と決めているキーワードです。
クエリの動作を制御する重要な言葉なので、普通はテーブル名やカラム名などに使えません。
予約語の確認方法
「何が予約語か分からないよ」という方は、公式ドキュメントをチェックするのが一番。
特にバージョンアップで新しい予約語が増えることもあるので、最新情報を見ておきましょう。(今回のエラーもそのパターンだった)
MySQL 8.0で新たに追加された予約語の例
・CUBE
→複数の列に対してすべての組み合わせの集計結果を返す。
・ROLLUP
→階層的に集計し、親グループの集計結果も返す。
・WINDOW
→ウィンドウ関数を使って、行ごとの集計結果を他の行と比較する。
公式ドキュメントには常に最新の予約語リストが掲載されているので、バージョンアップ時は要確認です。
予約語を使うときの対処法
それでもどうしても予約語を名前に使いたいときや使わざるを得ない時があると思います。
その時はバッククォートで囲みましょう。
例えばこんな感じです。
・エラー例
CREATE TABLE user (
id INT
);
エラー内容:
ERROR 1064 (42000): You have an error in your SQL syntax...
・解決策
CREATE TABLE `user` (
id INT
);
この例では、予約語のuserをテーブル名として使っています。
バッククォートで囲めばエラーになりません。
実務での注意点
・直接SQLを書く場合
予約語は避けるか、バッククォートでしっかりエスケープ。
・ORMを使う場合
ORMの設定で自動エスケープが効いているか確認しておくと安心です。
最後に
MySQLで予約語に引っかかると地味にハマるので、事前に気をつけたいところ。
すべての予約語を覚える必要はないものの、「あ、これ予約語かも?」ってピンとくる感覚を持っておくと、余計なトラブルを減らせると思います。
公式ドキュメントをさらっと見て、どんな感じかだけでもつかんでおくといいかもしれません。