MySQLのENUM列に数値を格納してはいけない理由
MySQLはENUM値を内部的に整数キー(インデックス番号)として保存し、その番号を使ってENUMメンバーを参照しています。ENUM列に生の数値を格納しないほうがよい主な理由は、MySQLが入力された数値を「値」ではなく「インデックス」として解釈してしまうため、値とインデックスが混同され、意図しないデータが登録される危険があるからです。
ENUMの内部的な仕組み
ENUM型の列では、定義された各メンバーに1から始まるインデックス番号が割り当てられます。たとえば ENUM('0','1','2') と定義した場合、「0」には1、「1」には2、「2」には3という番号が対応します。また、無効な値が挿入された際に使用される空文字列には0が割り当てられます。この内部構造こそが、数値入力時の予期せぬ動作の原因となります。
具体例
次の例で動作を確認してみましょう。
mysql> Create table enmtest(Val ENUM('0','1','2'));
Query OK, 0 rows affected (0.18 sec)
mysql> Insert into enmtest values('1'),(1);
Query OK, 2 rows affected (0.19 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> Select * from enmtest;
+-----+
| Val |
+-----+
| 1 |
| 0 |
+-----+
2 rows in set (0.00 sec)
この例では、最初のレコードには「1」を文字列として挿入し、2番目のレコードには同じ「1」をうっかり数値(引用符なし)で挿入しました。その結果、文字列の「1」はそのまま「1」として保存されましたが、数値の1はメンバーの値ではなくインデックス番号として解釈されています。つまり、MySQLは数値1を「メンバーリストの先頭要素への参照」とみなし、結果として「0」が格納されてしまったのです。
まとめとベストプラクティス
ENUM列に数値を格納したい場合は、必ず引用符を付けて文字列として挿入してください。数値リテラルをそのまま渡すと、MySQLはそれをインデックスとして扱うため、まったく別の値が保存されてしまいます。これはバグではなく、MySQLの仕様上の動作です。アプリケーション側でプレースホルダやORMを通じて値を渡す場合も、ENUM列に対しては必ず文字列型として扱うよう注意しましょう。
-
MySQLで列にENUM型を設定する方法
```html MySQLでは、テーブルを作成する際に、あらかじめ決められた文字列のリストから値を選ばせたい列に対してENUM型を設定できます。ENUMは、指定した候補値以外のデータが登録されるのを防ぎたい場合に便利なデータ型です。ここでは、実際にテーブルを作成しながら基本的な使い方を見ていきましょう。ENUM型を含むテーブルを作成するまず、学生の点数と合否ステータスを管理するテーブルを作成します。「StudentStatus」列には「First」「Second」「Fail」の3つの値のみを許可するENUM型を設定しています。mysql> create table DemoTable20
-
MySQLストアドプロシージャでカラムの値を変数に格納する方法
MySQLのストアドプロシージャ内で変数を宣言するには、DECLARE文を使用します。さらにSELECT ~ INTO構文を組み合わせることで、テーブルのカラム値を変数に格納することができます。ここでは、実際にサンプルテーブルを作成し、ストアドプロシージャ経由でカラムの値を変数に取得する手順を解説します。1. サンプルテーブルの作成まず、以下のようにテーブルを作成します。mysql> create table DemoTable2034-> (-> StudentId int NOT NULL AUTO_INCREMENT PRIMARY KEY,-> StudentN