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