LoginSignup
7
7

More than 3 years have passed since last update.

MySQLとmariaDBにおけるJSON関連の差異

Last updated at Posted at 2020-04-09

mariaDBでJSON型のカラムを扱ってはまったのでメモ

環境

Mysql : 5.7.29
mariaDB : 10.5.2

データ準備

create table sample (id int,item json);
insert into sample values(1,'{"kanagawa":"yokohama"}');
insert into sample values(2,'{"yamanashi":"kofu"}');

itemはkey:県名、value:県庁所在地のJSON。

単純な抽出

まずは単純にselect。差は全くない。

MySQL
select * from sample;
+------+--------------------------+
| id   | item                     |
+------+--------------------------+
|    1 | {"kanagawa": "yokohama"} |
|    2 | {"yamanashi": "kofu"}    |
+------+--------------------------+
MariaDB
select * from sample;
+------+--------------------------+
| id   | item                     |
+------+--------------------------+
|    1 | {"kanagawa": "yokohama"} |
|    2 | {"yamanashi": "kofu"}    |
+------+--------------------------+

集約

 1.GROUP_CONCAT

区切り文字を指定しなければいずれも,(カンマ)で結合される。

MySQL
select GROUP_CONCAT(item) from sample;
+------------------------------------------------+
| GROUP_CONCAT(item)                             |
+------------------------------------------------+
| {"kanagawa": "yokohama"},{"yamanashi": "kofu"} |
+------------------------------------------------+
MariaDB
select GROUP_CONCAT(item) from sample;
+----------------------------------------------+
| GROUP_CONCAT(item)                           |
+----------------------------------------------+
| {"kanagawa":"yokohama"},{"yamanashi":"kofu"} |
+----------------------------------------------+

 2.JSON_ARRAYAGG

ここがハマったポイント。MySQLはJSON型のカラムをそのまま配列として返すが、MariaDBはエスケープシーケンスされた文字列の配列として返す。
原因は推測だがMariaDB上では「JSON型はLONGTEXT型のエイリアス」1であることと思われる。

MySQL
select JSON_ARRAYAGG(item) from sample;
+---------------------------------------------------+
| JSON_ARRAYAGG(item)                               |
+---------------------------------------------------+
| [{"kanagawa": "yokohama"}, {"yamanashi": "kofu"}] |
+---------------------------------------------------+
MariaDB
select JSON_ARRAYAGG(item) from sample;
+------------------------------------------------------------+
| JSON_ARRAYAGG(item)                                        |
+------------------------------------------------------------+
| ["{\"kanagawa\":\"yokohama\"}","{\"yamanashi\":\"kofu\"}"] |
+------------------------------------------------------------+

 3.JSON_OBJECTAGG

JSON_OBJECTAGGもJSON_ARRAYAGGと同様

MySQL
select json_objectagg(id,item) from sample;
+-------------------------------------------------------------+
| json_objectagg(id,item)                                     |
+-------------------------------------------------------------+
| {"1": {"kanagawa": "yokohama"}, "2": {"yamanashi": "kofu"}} |
+-------------------------------------------------------------+
MariaDB
select json_objectagg(id,item) from sample;
+---------------------------------------------------------------------+
| json_objectagg(id,item)                                             |
+---------------------------------------------------------------------+
| {"1":"{\"kanagawa\":\"yokohama\"}", "2":"{\"yamanashi\":\"kofu\"}"} |
+---------------------------------------------------------------------+

MariaDBでMySQL同等の結果を取得するためには

一応、SQLを工夫すればMariaDBでもMySQL同等の結果が取得できる。但し、項目値によってはkeyが重複するなどするため、JSONとしての正しさは保証されない。

JSON_ARRAYAGG

MariaDB
select CONCAT('[',GROUP_CONCAT(item),']') from yukisaki_database.sample;
+------------------------------------------------+
| CONCAT('[',GROUP_CONCAT(item),']')             |
+------------------------------------------------+
| [{"kanagawa":"yokohama"},{"yamanashi":"kofu"}] |
+------------------------------------------------+

JSON_OBJECTAGG

MariaDB
select CONCAT('{',GROUP_CONCAT(CONCAT('"',id,'":',item)),'}') from sample;
+--------------------------------------------------------+
| CONCAT('{',GROUP_CONCAT(CONCAT('"',id,'":',item)),'}') |
+--------------------------------------------------------+
| {"1":{"kanagawa":"yokohama"},"2":{"yamanashi":"kofu"}} |
+--------------------------------------------------------+
7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7