MySQL 5.7.6以降で利用可能なGenerated Column

Oracleの仮想列に近いものがMySQLでもあるようなので書いてみました。
MySQL 5.7.6以降で使えるGenerated Columnという列定義です。

利用用途

Generated Columnはデータの保存用途ではなく、他の列情報から計算式によって値を生成することです。

データの持ち方

Generated Columnには、「VIRTUAL」 or 「STORED」が指定できます。
「VIRTUAL」は実データを持たず、読み込むタイミングで計算します。
「STORED」は計算結果を記憶領域に保存し、通常の列情報のように読み取ります。
既定値は「VIRTUAL」です。

「STORED」は記憶領域に保存するため、もちろんインデックスが使えます。
MySQL 5.7.8以降では、テーブルエンジンが InnoDB の場合に限り、
「VIRTUAL」であっても二次インデックスが可能となりました。

ALTER TABLE t1 ADD INDEX(full_name);

下記のようなテーブル構造のものがあるとします。
この場合、full_name には値を登録しなくても AS 以降の計算に基づいた値が取得できます。

CREATE TABLE t1 (  
  first_name VARCHAR(10),  
  last_name VARCHAR(10),  
  full_name VARCHAR(255) AS (CONCAT(last_name,' ',first_name))  
);
INSERT INTO t1 (first_name, last_name) VALUES ('taro', 'dcom');

表示例

first_name last_name full_name
taro dcom dcom taro

≪Insertエラー≫

列を書かないタイプのINSERT文だと列数不一致でエラーになりました…
列として扱われるため Generated Column とした列も指定が必要です。

INSERT INTO t1 VALUES ('taro', 'dcom');
Error Code: 1136. Column count doesn't match value count at row 1

ただ、Generated Columnであるfull_nameは値を持たないためセットしようとしてもエラーになります。

INSERT INTO t1 VALUES ('taro', 'dcom', '');
Error Code: 3105. The value specified for generated column 'full_name' in table 't1' is not allowed.

回避方法

Generated Columnには”DEFAULT“を指定することで正しく登録できます。

INSERT INTO t1 VALUES ('taro', 'dcom', DEFAULT);

次回はjsonデータ型でのGenerated Column利用について書きたいと思います。

MySQLの公式ページ
MySQL CREATE TABLE and Generated Columns

おすすめ

TOP
TOP