web-dev-qa-db-ja.com

Postgres 9.4+:EAVの代わりにJSONB

私は新しいpostgresqlデータベースを構築する方法を考えています。エンティティのプロパティを格納するためにEAVモデルの代わりにJSONB列を使用できるかどうか知りたいです。これは、これらの種類のものを格納するための柔軟な方法のように見えます。

EAVの場合、テーブルマテリアル(mat_id、mat_name、mat_descr)、テーブルmaterial_properties(prop_id、prop_name、prop_desc)、およびテーブルmaterial_property_values(mat_id、prop_id、val)があります。各マテリアルは、異なるプロパティセットを持つことができます。

単にmat_props JSONB列をマテリアルテーブルに追加し、そこにすべてのプロパティを{"name":value}として保存するべきではない理由はありますか?このように、列としてプロパティをクエリするのは、次のように簡単です。

SELECT mat_name, mat_props->'name' as propval FROM materials

結合または副選択の代わりに。

また、この列を材料テーブルに追加できますか、それとも、material_properties(mat_id、properties JSONB)テーブルに保持する方がはるかにパフォーマンスが高くなりますか?

6
coussej

JSONBは読みやすいかもしれませんが、書き込むのは複雑で非効率的です。

たとえば、次の質問を参照してください: PostgreSQLはJSONB列からプロパティを削除および削除します 。これは、従来のEAVテーブルを使用した更新/削除よりもはるかに困難です。

おそらく、キー/値のペアを追加/マージ/削除するパーツを作成した場合、そのJSONベースのデザインの優雅さやシンプルさは、それほど明白ではないように見えるでしょう。パフォーマンスに関しては、もっと悪いことに賭けています。

ストレージレベルでは、JSON構造内の1つのプロパティへの書き込みには、すべてのプロパティが変更された場合と同じコストで、列全体(実際には格納されている行)の書き換えが必要になります。これは、I/Oサイズと真空への圧力に関して最適ではありません。

この問題は、いくつかのリンクと参照を含む別の質問でS.Oで言及されています。

Postgres 9.4でJSONBタイプの列に対して更新操作を実行する方法

プログラマーのJSONB更新を容易にするための作業が進行中です。 jsonbx は、9.4に役立つ関数と演算子を提供します。おそらくこれらは将来のバージョンでPostgreSQLコアに統合されるでしょう。ただし、大きなJSONオブジェクト内の小さな更新による大きなI/Oコストは残ります。

jsonbxは最近のPGカンファレンスでデモされました(youtubeリンク):

jsonbの更新および削除操作(1/2)
jsonbの更新および削除操作(2/2)

5
Daniel Vérité