ZSON:透過的なJSONB圧縮のためのPostgreSQL拡張





最近、GitHub ZSONに投稿しました 。 ZSONは、JSONBドキュメントを透過的に圧縮するためのPostgreSQLの拡張機能です。 圧縮は、ドキュメントで最も頻繁に見られる行を強調表示し、これらの行を使用して辞書を作成することにより行われます。 さらに、文字列はドキュメントのキーだけでなく、値、またはネストされた配列の文字列にすることもできます。 場合によっては、ZSONはデータベースのサイズを最大2倍に減らし、1秒あたりのトランザクション数を10%増やすことができます。 共有バッファでは、ドキュメントも圧縮された形式で保存されるため、メモリも保存されます。



面白い? 読んでください、そしてあなたは実際にこのすべての経済を使う方法を学びます。



備考



記事のメインコンテンツに進む前に、いくつかの点に注意します。





設置



ソースからのZSONのアセンブリとそのインストールは、次のように実行されます。



git clone https://github.com/afiskon/zson.git cd zson sudo make install
      
      





インストール後、テストを実行します。



 make installcheck
      
      





データベースでZSONを有効にします。



 create extension zson;
      
      





おめでとうございます、ZSONがインストールされました!



削除する



ZSONを削除する場合は、オフにします。



 drop extension zson;
      
      





そして、PostgreSQLから完全に切り取ります。



 sudo make uninstall
      
      





ZSON、テーブルなどによって作成されたすべてのタイプは、自動的にクリーンアップされます。



使用する



まず第一に、あなたは典型的な文書でZSONを訓練する必要があります。 トレーニングの結果として、ドキュメントで最も頻繁に見られる行で辞書が構築され、その後圧縮に使用されます。 トレーニングは、次の手順を使用して行われます。



 zson_learn( tables_and_columns text[][], max_examples int default 10000, min_length int default 2, max_length int default 128, min_count int default 2 )
      
      





例:



 select zson_learn('{{"table1", "col1"}, {"table2", "col2"}}');
      
      





結果の辞書は次のように表示できます。



 select * from zson_dict;
      
      





これで、透過的なJSONB型の置換としてZSONを使用できます。



 zson_test=# create table zson_example(x zson); CREATE TABLE zson_test=# insert into zson_example values ('{"aaa": 123}'); INSERT 0 1 zson_test=# select x -> 'aaa' from zson_example; -[ RECORD 1 ]- ?column? | 123
      
      





すべてのステートメントと手順は、JSONBと同様にZSONで機能します。



新しい辞書への移行



ドキュメントのレイアウトが変更されると、一部の行が消えて他の行が表示されるため、圧縮が無効になる場合があります。 この場合、新しいデータでZSONを再トレーニングできます。



 select zson_learn('{{"table1", "col1"}, {"table2", "col2"}}');
      
      





これにより、辞書の新しいバージョンが作成されます。 新しいドキュメントを更新および作成するとき、それらはその助けによって圧縮されます。 古いドキュメントは、圧縮されたバージョンの辞書を使用して解凍されます。 辞書はメモリにキャッシュされることに注意してください。 したがって、ZSONは新しい辞書についてすぐに学習するのではなく、作成してから約1分後に学習します。



特定のドキュメントがどのバージョンの辞書で圧縮されているかを判断するには、zson_infoプロシージャを使用します。



 zson_test=# select zson_info(x) from test_compress where id = 1; -[ RECORD 1 ]--------------------------------------------------- zson_info | zson version = 0, dict version = 1, ... zson_test=# select zson_info(x) from test_compress where id = 2; -[ RECORD 1 ]--------------------------------------------------- zson_info | zson version = 0, dict version = 0, ...
      
      





データベース内のすべてのドキュメントが新しい辞書バージョンを使用して圧縮されていることが確実な場合、古い辞書を安全に削除できます。



 delete from zson_dict where dict_id = 0;
      
      





ただし、実際には、これはほとんど意味がありません。 わずか数キロバイトのディスク容量しか節約できません。 私の中の妄想は、少し不注意でデータを失うリスクはそれだけの価値がないと信じています。



辞書を更新する必要があることをどのように理解しますか?



残念ながら、普遍的なアプローチを推奨することは困難です。 たとえば、データベース内のドキュメントの平均サイズを随時確認できます。



 select pg_table_size('tt') / (select count(*) from tt)
      
      





増加し始めたら、辞書を更新します。 また、ZSONを時々、たとえば1年に1回だけ再トレーニングすることもできます。



最後に、アプリケーション開発者自身がドキュメントのレイアウトを大幅に変更したことを知っています。 ZSON再トレーニングは、移行スクリプトまたはアプリケーションの更新手順で有効にできます。



強い欲求があれば、他のアプローチを思いつくことができます。 一般に、それはすべて状況に依存します。



おわりに



ご覧のとおり、ZSONのおかげで、両方の長所を活用できます。データスキーマレスの柔軟性とリレーショナルモデルのコンパクトさを組み合わせたものです。 同時に、アプリケーション側で何もする必要はなく、DBMS自体の側ですべてが透過的に行われます。



ご質問があれば、コメントでお答えします。 フィードバックやプルリクエストは大歓迎です。



All Articles