MySQL8のJSON部分更新を確認してみた。

 

最初こんなテーブルを作り、データを更新する。

> create database hoge;
> use hoge;
> create table fuga (id integer not null, body json not null, primary key(id));
> insert into fuga values (1, '{"x":10, "y":20}');
> update fuga set body = json_replace(body, '$.y', 50);

この状態でバイナリログを見ると、以下のようになっている。

### UPDATE `hoge`.`fuga`
### WHERE
### @1=1
### @2='{"x": 10, "y": 20}'
### SET
### @1=1
### @2='{"x": 10, "y": 50}'

部分更新じゃなくね?と思ったが、

my.cnfに以下を記載する。

binlog_row_image=minimal
binlog_row_value_options=partial_json

再起動完了後、以下のようなSQLを実行する。

> update fuga set body = json_replace(body, '$.y', 12);

この時、バイナリログは、

### UPDATE `hoge`.`fuga`
### WHERE
### @1=1
### SET
### @2=JSON_REPLACE(@2, '$.y', 12)

となる。

もともと、binlog_row_imageはバイナリログに変更分しか記載しないもので、
5.6から導入されていたが、8ではbinlog_row_value_optionsというパラメータが追加された。
これにより、JSONの部分更新がバイナリログ上でも明示される。

とはいえ、JSONの部分更新を成立させるには、
以下のJSON関数を使う必要がある。

  • JSON_SET()
  • JSON_REPLACE()
  • JSON_REMOVE()

MariaDB10.3でも、binlog_row_value_optionsがないため、

JSONの部分更新はできない。

おまけに、JSONはlongtextのエイリアスのため、

「JSONの正しさ」は保証しない。

JSONを使うなら、virtual columnもあるMSQL8が現時点では良いと思う。

 

(2018年11月1日追記)

> おまけに、JSONはlongtextのエイリアスのため、

> 「JSONの正しさ」は保証しない。

大変申し訳ありません。

上記は間違っていました。

https://mariadb.com/kb/en/library/json-data-type/

にcheck制約を使うことで、「JSONの正しさ」を保証することが可能でした。

 

以上

コメントがあればどうぞ


CAPTCHA Image
Reload Image