MySQLではJSONデータ型なるものが Ver 5.7からあります。
名前のとおりJSONデータ形式を扱うデータ型です。
JSONデータ型を利用すると、RDBでありながらスキーマレスな使い方をすることが可能です。
定義の仕方
データ型にJSONを指定する。
CREATE TABLE person_info ( code varchar(50) NOT NULL, name varchar(255) DEFAULT NULL, details json NOT NULL, PRIMARY KEY (code) );
サンプルデータを投入。
INSERT INTO person_info VALUES ('u0001', 'dcom taro', '{ "age" : 30 , "tel" : "012-0000-1111" }'); INSERT INTO person_info VALUES ('u0002', 'dcom jiro', '{ "age" : 25 , "tel" : "123-0000-1111" }'); INSERT INTO person_info VALUES ('u0003', 'dcom hanako', '{ "tel" : "012-1111-2222" }');
JSONデータ型からageを抽出してSELECT文を実行
関数利用方法:JSON_EXTRACT(col, ‘$.検索キー’
SELECT code, name, JSON_EXTRACT(details, '$.age') AS 'age' FROM person_info;
さらにMySQL 5.7.9 以降では下記のような省略した書き方もできます。
取得結果は同じです。
関数利用方法:col->’$.検索キー’
SELECT code, name, details->'$.age' AS 'age' FROM person_info;
≪取得結果≫
code | name | age |
---|---|---|
u0001 | dcom taro | 30 |
u0002 | dcom jiro | 25 |
u0003 | dcom hanako | NULL |
Generated Columnの利用
このJSONデータ型に対して、Generated Columnを利用してみます。
CREATE TABLE person_info ( code varchar(50) NOT NULL, name varchar(255) DEFAULT NULL, age int(11) AS ( details->'$.age' ) VIRTUAL, details json NOT NULL, PRIMARY KEY (code) );
ALTERであれば…
ALTER TABLE person_info ADD COLUMN age int(11) AS ( details->'$.age' );
取得するときはカラムを指定するだけで可能です。
SELECT code, name, age FROM person_info;
と、Generated Column はJSONデータ型に対しても扱うことができます。
通常のGeneratedColumnと同じく、「VIRTUAL」指定であっても
テーブルエンジンが InnoDB の場合に限りインデックスを張ることが可能です。
使い方次第では便利なデータ型ですね。
おわりに
どういった内容をJSONデータ型として扱うべきなのかは難題です。
JSONデータ型は多くの情報を1カラムに持つため、データ内の更新が遅くなる傾向にあるようです。
そのため、使う際は更新のパフォーマンスに気を使う必要があります。
検索のパフォーマンスでは3万件程度のレコードであれば、
JSONデータ型内を検索する簡易なSELECT程度で0.1秒以内に返ってきました。