MySQL道普請便り

第272回MySQL 9.7でJSON Duality ViewのDMLを再検証してみた

第266回では、MySQL 9.6 Community Editionを用いてJSON Duality Viewを紹介しました。この回はJSON Duality Viewによるデータ参照や実行計画の確認、_metadata.etagの挙動などを検証しましたが、Community EditionではUPDATEやINSERT、DELETEといったDML操作は利用できませんでした。

その後、2026年4月にリリースされたMySQL 9.7では、Community EditionでもJSON Duality Viewに対するDML(INSERT、UPDATE、DELETE文)が利用可能になりました。これにより、JSONドキュメント経由での更新処理も試せるようになっています。

そこで今回は、MySQL 9.7 Community Editionを用いてJSON Duality ViewのDML機能を改めて検証してみます。単に更新できることを確認するだけでなく、前回の記事でも少し触れた eTag に注目し、どのようなタイミングで値が変化するのか、また楽観ロックとしてどのように利用できるのかについても確認していきます。

MySQL 9.7でDMLを試してみる

DMLを利用するため、更新対象となるオブジェクトに適切なDMLタグを付与したJSON Duality Viewを作成します。今回は前回と同じテーブル構成を利用し、MySQL 9.7 Community Edition上でDMLを試してみます。DMLを利用するためには、更新を許可するオブジェクトに対してWITH(INSERT)WITH(UPDATE)といったタグを付与する必要があります。authorWITH(INSERT, UPDATE)commentsWITH(INSERT, UPDATE, DELETE)を指定してJSON Duality Viewを作成しました。

mysql> CREATE JSON RELATIONAL DUALITY VIEW post_detail_dv AS
    -> SELECT JSON_DUALITY_OBJECT(
    ->   WITH(INSERT, UPDATE, DELETE)
    ->   '_id': posts.post_id,
    ->   'title': posts.title,
    ->   'published_at': posts.published_at,
    ->   'author': (
    ->     SELECT JSON_DUALITY_OBJECT(
    ->       WITH(INSERT, UPDATE)
    ->       'author_id': authors.author_id,
    ->       'display_name': authors.display_name
    ->     )
    ->     FROM authors
    ->     WHERE authors.author_id = posts.author_id
    ->   ),
    ->   'comments': (
    ->     SELECT JSON_ARRAYAGG(
    ->       JSON_DUALITY_OBJECT(
    ->         WITH(INSERT, UPDATE, DELETE)
    ->         'comment_id': comments.comment_id,
    ->         'commenter': comments.commenter,
    ->         'body': comments.body,
    ->         'created_at': comments.created_at
    ->       )
    ->     )
    ->     FROM comments
    ->     WHERE comments.post_id = posts.post_id
    ->   )
    -> )
    -> FROM posts;
Query OK, 0 rows affected (0.004 sec)

作成したJSON Duality Viewを確認すると、リレーショナルデータを次のようなJSONドキュメントとして参照できます。

mysql> SELECT JSON_PRETTY(data)
    -> FROM post_detail_dv
    -> WHERE data->>'$._id' = '11';
{
  "_id": 11,
  "title": "...",
  "author": {...},
  "comments": [...]
}

それでは、投稿タイトルを更新してみます。実行結果は以下のとおりです。

mysql> UPDATE post_detail_dv
    -> SET data = JSON_SET(
    ->   data,
    ->   '$.title',
    ->   'MySQL 9.7でJSON Duality Viewを再検証してみた'
    -> )
    -> WHERE data->>'$._id' = '11';
Query OK, 1 row affected (0.004 sec)
Rows affected: 1  Warnings: 0.

更新後にJSON Duality Viewを確認すると、タイトルが変更されていることがわかります。

mysql> SELECT
    ->   data->>'$._id' AS id,
    ->   data->>'$._metadata.etag' AS etag,
    ->   data->>'$.title' AS title
    -> FROM post_detail_dv
    -> WHERE data->>'$._id' = '11';
+------+----------------------------------+-------------------------------------------------------+
| id   | etag                             | title                                                 |
+------+----------------------------------+-------------------------------------------------------+
| 11   | 648d6f9f4418e5af3834ea622e8c6929 | MySQL 9.7でJSON Duality Viewを再検証してみた          |
+------+----------------------------------+-------------------------------------------------------+
1 row in set (0.001 sec)

さらにベーステーブル側も確認してみます。

+---------+-------------------------------------------------------+
| post_id | title                                                 |
+---------+-------------------------------------------------------+
|      11 | MySQL 9.7でJSON Duality Viewを再検証してみた          |
+---------+-------------------------------------------------------+

JSON Duality View経由で実行した更新は、対応するベーステーブルにも正しく反映されていることが確認できました。このように、MySQL 9.7ではCommunity EditionでもJSON Duality Viewに対するDMLが利用できるようになっています。

eTagを観察してみる

前回の記事でも少し触れましたが、JSON Duality Viewには _metadata.etag というメタデータが含まれています。

JSON Duality Viewを参照すると、以下のようにeTagを確認できます。

mysql> SELECT
    ->   data->>'$._id' AS id,
    ->   data->>'$._metadata.etag' AS etag,
    ->   data->>'$.title' AS title
    -> FROM post_detail_dv
    -> WHERE data->>'$._id' = '11';
+------+----------------------------------+------------------------------------------------------------+
| id   | etag                             | title                                                      |
+------+----------------------------------+------------------------------------------------------------+
| 11   | 683c8b29b965fa95b4b1624d974ad607 | MySQL9.4に追加されたJSON Duality Viewってなに?            |
+------+----------------------------------+------------------------------------------------------------+

ドキュメントによると、eTagはドキュメントの状態を表す識別子として利用できます。しかし、どの範囲の変更がeTagの変化として検知されるのかは気になるところです。

そこで今回は、

  • JSON Duality View経由の更新
  • 同じ値へのUPDATE
  • 関連テーブルの更新

を試し、eTagの変化を確認してみましょう。

投稿タイトルを更新してみる

まずはJSON Duality View経由で投稿タイトルを変更します。

UPDATE post_detail_dv
SET data = JSON_SET(
  data,
  '$.title',
  'MySQL 9.7でJSON Duality Viewを再検証してみた'
)
WHERE data->>'$._id' = '11';

更新後のeTagは以下のようになりました。

+------+----------------------------------+-------------------------------------------------------+
| id   | etag                             | title                                                 |
+------+----------------------------------+-------------------------------------------------------+
| 11   | 648d6f9f4418e5af3834ea622e8c6929 | MySQL 9.7でJSON Duality Viewを再検証してみた          |
+------+----------------------------------+-------------------------------------------------------+

更新前と比較すると、eTagが変化していることがわかります。

同じ値でUPDATEしてみる

続いて、同じ値でUPDATEを実行します。

UPDATE post_detail_dv
SET data = JSON_SET(
  data,
  '$.title',
  'MySQL 9.7でJSON Duality Viewを再検証してみた'
)
WHERE data->>'$._id' = '11';

再度eTagを確認すると、値は変化していません。

+------+----------------------------------+-------------------------------------------------------+
| id   | etag                             | title                                                 |
+------+----------------------------------+-------------------------------------------------------+
| 11   | 648d6f9f4418e5af3834ea622e8c6929 | MySQL 9.7でJSON Duality Viewを再検証してみた          |
+------+----------------------------------+-------------------------------------------------------+

少なくとも今回の検証では、eTagはUPDATE文の実行有無ではなく、実際にドキュメントの内容が変化したかどうかを基準に更新されているようです。

関連テーブルを更新してみる

次に、JSON Duality Viewを経由せず、ベーステーブル側を直接更新してみます。

まずは投稿者名を変更します。

UPDATE authors
SET display_name = 'Fukamachi_v97'
WHERE author_id = 1;

更新後に再度JSON Duality Viewを確認すると、投稿者名だけでなくeTagも変化していました。

+------+----------------------------------+---------------+
| id   | etag                             | author_name   |
+------+----------------------------------+---------------+
| 11   | 082555f119b4087a59fb80e57e07a0d2 | Fukamachi_v97 |
+------+----------------------------------+---------------+

続いてコメント本文も変更してみます。

UPDATE comments
SET body = 'CommunityでもDMLできるようになったか知りたい'
WHERE comment_id = 100;

結果は以下のとおりです。

+------+----------------------------------+--------------------------------------------------------------+
| id   | etag                             | first_comment                                                |
+------+----------------------------------+--------------------------------------------------------------+
| 11   | 1d95b60370e02be3641631d09237525d | CommunityでもDMLできるようになったか知りたい                 |
+------+----------------------------------+--------------------------------------------------------------+

コメント本文の変更でもeTagが変化していることが確認できました。

今回の結果をまとめると、以下のようになります。

操作 eTag変化
JSON Duality View経由でtitle更新
同値UPDATE ×
authors.display_name更新
comments.body更新

期待どおり、JSON Duality View経由でドキュメントを更新した場合はeTagが変化しました。一方で、同じ値へのUPDATEでは変化せず、関連テーブルを直接更新した場合でもeTagが変化していることがわかります。

今回の検証結果を見る限り、eTagは`posts`テーブルだけでなく、ネストされた`author`や`comments`を含めたドキュメント全体の状態を表しているようです。また、UPDATE文の実行有無ではなく、実際にドキュメント内容が変化した場合にのみeTagが更新されることも確認できました。

eTagを利用した楽観ロック

前節の検証から、eTagはJSON Duality Viewが表現するドキュメント全体の状態を表していることがわかりました。

続いて、このeTagを利用した更新競合の検知を試してみます。

mysql> SELECT
    ->   data->>'$._metadata.etag' AS etag
    -> FROM post_detail_dv
    -> WHERE data->>'$._id' = '11';
+----------------------------------+
| etag                             |
+----------------------------------+
| 1d95b60370e02be3641631d09237525d |
+----------------------------------+

ここで、過去のeTagを利用して更新を試してみます。今回は、投稿者情報を更新する前のeTagである082555f119b4087a59fb80e57e07a0d2を指定してみます。

mysql> UPDATE post_detail_dv
    -> SET data = JSON_SET(
    ->   data,
    ->   '$.title',
    ->   '古いeTagで更新してみる',
    ->   '$._metadata.etag',
    ->   '082555f119b4087a59fb80e57e07a0d2'
    -> )
    -> WHERE data->>'$._id' = '11';
ERROR 6494 (HY000): Cannot update JSON duality view. The ETAG of the document in the database did not match the ETAG '"082555f119b4087a59fb80e57e07a0d2"' passed in.

更新は失敗しました。

続いて、現在のeTagを利用して同じ更新を試してみます。

mysql> UPDATE post_detail_dv
    -> SET data = JSON_SET(
    ->   data,
    ->   '$.title',
    ->   'eTagを指定して更新してみる',
    ->   '$._metadata.etag',
    ->   '1d95b60370e02be3641631d09237525d'
    -> )
    -> WHERE data->>'$._id' = '11';
Query OK, 1 row affected (0.003 sec)

更新後の状態を確認すると、タイトルが変更されていることがわかります。

+------+----------------------------------+---------------------------------------+
| id   | etag                             | title                                 |
+------+----------------------------------+---------------------------------------+
| 11   | 22eb0d3b95bc472443515ee24354a13b | eTagを指定して更新してみる            |
+------+----------------------------------+---------------------------------------+

更新後にはeTagも新しい値へ変化しています。このように、JSON Duality ViewではeTagを利用した楽観ロックを実現できます。

一般的なversionカラムによる楽観ロックでは、関連テーブルの変更を検知するためには追加の実装が必要になります。一方、今回の検証結果を見る限り、JSON Duality ViewのeTagはドキュメント全体の状態を基に生成されているため、authorやcommentsを含めた変更も検知できるようです。

JSON Duality Viewを利用する場合、eTagは単なるメタデータではなく、更新競合を検知するための重要な仕組みとして利用できそうです。

まとめ

今回はMySQL 9.7 Community Editionで利用可能になったJSON Duality ViewのDML機能を検証してみました。前回の記事ではCommunity Editionでは参照のみ利用可能でしたが、MySQL 9.7ではDMLを実行できるようになり、JSON Duality View経由での更新がベーステーブルへ反映されることを確認できました。

また、eTagの挙動についても改めて確認してみました。今回の検証では、ルートオブジェクトである posts の変更だけでなく、ネストされた author や comments の変更でもeTagが変化することがわかりました。一方で、同じ値へのUPDATEではeTagは変化せず、JSON Duality Viewが表現するドキュメント全体の状態を基に生成されているようです。

特に興味深かったのは、eTagを利用した楽観ロックです。一般的なversionカラムによる実装では関連テーブルの変更を検知するために追加の実装が必要になりますが、今回の検証結果を見る限り、JSON Duality ViewではeTagによってそれらの変更も検知できる可能性があります。

前回の記事を書いた時点では、JSON Duality Viewは「リレーショナルデータをJSONで参照できる機能」という印象が強かったのですが、Community EditionでもDMLが利用できるようになったことで、実際のアプリケーションでどのように利用できるのかが少し見えてきました。

本稿で紹介した内容以外にも、DMLタグの詳細や更新可能なオブジェクトに関する制約などが存在します。興味のある方は公式ドキュメントも参照してみてください。

おすすめ記事

記事・ニュース一覧