
大きな文字列データやJSONデータなどをDBに保存しようとすると、DBへの負荷が大きくなります。
少しでもその負荷を取り除くためには、データを圧縮して容量を削減する必要があります。
Railsでは「 zstd-ruby 」というzstdによるデータ圧縮gemが用意されています。
今回はこの「 zstd-ruby 」の使い方について紹介します。
ちなみに、zstdというのはFacebookに所属しているYann Colletによって開発された可逆圧縮アルゴリズムだそうです。(Wikipediaより)
<前提>
Rails6.0.1(5.2系でも同内容で確認済み)
MySQL 5.7
zstd-rubyの使い方
Gemの登録
1 2 |
# データ圧縮 gem 'zstd-ruby' |
テーブルの設定
圧縮したデータを通常のtext型カラムに保存することは出来ません。
圧縮後のバイナリデータを格納することが出来る「BLOB型」の大容量格納可能な「LONGBLOB型」を採用します。
保存させる先のカラムの型は「LONGBLOB型」として作成しておきます。
データの圧縮と解凍
基本的には下のようにして圧縮と解凍を行います。
1 2 3 4 5 6 7 8 |
# 圧縮 item # 圧縮させたいデータ compressed_data = Zstd.compress(item) # 解凍 item # 解凍したいデータ thawing_item = Zstd.decompress(item) |
ただ、このままだと圧縮データの文字コードがUTF-8ではないので(たしかascii-8bitになってしまう)、UTF-8に切り替える必要があります。解凍時も同じです。
それを考慮して私は下のような圧縮・解凍用関数を作りました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# 圧縮して返す関数 # 引数:圧縮するデータ # 戻り値:圧縮後データ private def zstd_compress(item) compressed_data = Zstd.compress(item) compressed_data = compressed_data.force_encoding("utf-8") return compressed_data end # 圧縮データを解凍して返す関数 # 引数:圧縮データ # 戻り値:解凍データ private def zstd_decompress(item) thawing_item = Zstd.decompress(item) thawing_item = thawing_item.force_encoding("utf-8") return thawing_item end ######################################################### # 使用例 # 圧縮 item = zstd_compress(val) # 解凍 item = zstd_decompress(val) |
こちらの関数ではzstdの圧縮・解凍とUTF-8化をセットで行い戻り値を返すようになっています。
関数は「application_controller.rb」などに記述しておくと全てのコントローラーから使えるのでいいでしょう。
まとめ
ざっくりとした説明で申し訳ありません。
どれくらい容量が削減されるかは、もともとのデータ量にもよりますが、私の場合はJSONデータを圧縮かけて使っていて、およそ30%程度削減される感じでした。
使い方も上記した関数を使えばシンプルなので、ご参考にしてみてください。