1. ホーム
  2. postgresql

[解決済み] Postgres 9.4でJSONB型のカラムに対して更新操作を実行する方法

2022-04-23 15:15:10

質問

Postgres 9.4 データ型 JSONB のドキュメントを見ても、JSONB 列で更新を行う方法はすぐにはわかりません。

JSONBの型と関数に関するドキュメントです。

http://www.postgresql.org/docs/9.4/static/functions-json.html http://www.postgresql.org/docs/9.4/static/datatype-json.html

例として、このような基本的なテーブル構造を持っています。

CREATE TABLE test(id serial, data jsonb);

というように、挿入は簡単です。

INSERT INTO test(data) values ('{"name": "my-name", "tags": ["tag1", "tag2"]}');

さて、'data' カラムをどのように更新すればよいのでしょうか。これは無効な構文です。

UPDATE test SET data->'name' = 'my-other-name' WHERE id = 1;

これは、私が見逃しているどこか明白なドキュメントですか?ありがとうございます。

解決方法は?

理想的には、リレーショナル・データベース内で操作したい構造化された通常のデータには、JSONドキュメントを使用しないことです。JSONドキュメントを使用するには 正規化されたリレーショナルデザイン の代わりに

JSONは主に、RDBMS内部で操作する必要のない文書全体を保存することを目的としています。関連する

Postgresで行を更新すると、常に新しいバージョンの 全体 行です。という基本的な原理です。 PostgresのMVCCモデル . パフォーマンスの観点からは、JSONオブジェクトの中の1つのデータを変更するか、すべてのデータを変更するかはほとんど問題ではありません:新しいバージョンの行が書き込まれなければなりません。

したがって マニュアルにあるアドバイス :

JSONのデータには、以下のような並行処理制御の考慮事項があります。 他のデータ型と同様、テーブルに格納されます。大きな ドキュメントを更新することは可能ですが、更新すると 行レベルのロックが行全体にかかります。JSONドキュメントを以下のように制限することを検討してください。 更新時のロック競合を減らすため、管理可能なサイズにする。 トランザクションがあります。理想的には、JSONドキュメントはそれぞれアトミックなものであるべきです。 ビジネスルール上、これ以上合理的な処理ができないデータは 独立に修正できるような小さなデータムに細分化する。

要点:修正するために 何でも JSONオブジェクトの内部では、変更されたオブジェクトを列に割り当てる必要があります。Postgresは、JSONオブジェクトを構築し、操作するための限られた手段を提供します。 json のデータを保存する機能に加えて、その バージョン9.2以降、新しいリリースが出るたびに、ツールの武器は大幅に増えています。しかし、基本は変わりません。あなたは 常に は完全な修正オブジェクトを列に割り当てなければならず、Postgresは更新時に常に新しいバージョンの行を書き込みます。

Postgres 9.3 以降のツールで動作させるためのいくつかのテクニック。

この回答は、SOの他の回答と同じぐらい多くのダウンボートを集めました。 共に . 正規化されたデザインは通常のデータに対して優れている、という考え方は好まれないようです。Craig Ringerによるこの素晴らしいブログ記事で、より詳しく説明されています。

Laurenz Albe氏のブログ記事、もう一つの Postgresの公式コントリビューター クレイグや僕と同じように。