データのシリアライズ

要約:シリアライズされたデータをデータベースに格納しないでください。これには、カンマ区切りの値を文字列として格納することも含まれます。

Railsでは、シリアライズされたデータをJSONやYAMLなどの形式で格納することができます。このようなフィールドは次のように定義できます:

class Issue < ActiveRecord::Model
  serialize :custom_fields
end

シリアライズされたデータをデータベースに格納したくなるかもしれませんが、これには多くの問題があります。このドキュメントではこれらの問題を概説し、代替案を提供します。

シリアライズされたデータは強力ではありません

リレーショナルデータベースを使用する場合、個々のフィールドをクエリしたり、スキーマを変更したり、インデックスを作成したりすることができます。シリアル化されたデータを使用する場合、そのようなことはすべて非常に困難か、まったく不可能になります。PostgreSQLはJSONフィールドをクエリする機能を提供していますが、そのほとんどは非常に特殊な使用例を想定しており、より一般的な使用には向いていません。YAMLを使用する場合、データをクエリする方法はありません。

スペースの無駄

JSON や YAML のようなシリアライズされたデータを保存することは多くのスペースを浪費することになります。これらのフォーマットは保存するデータ以外に追加文字 (たとえば、二重引用符や改行) を含むことが多いからです。

管理が難しい

シリアライズされたデータに新しいフィールドを追加したり、既存のフィールドを変更しなければならない場合があります。シリアライズされたデータを使用する場合、保存されている値をすべて書き直すしかないため、これは難しく、非常に時間がかかります。そのためには次のようなことが必要です:

  1. データの取得
  2. Ruby構造体にパースします。
  3. 変異させる
  4. 文字列へのシリアライズ
  5. データベースに格納

一方、通常のカラムを使用する場合、カラムを追加することは次のようになります:

ALTER TABLE table_name ADD COLUMN column_name type;

このようなクエリはほとんど時間がかからず、大きなJSONもしくはYAML構造を書き直すことなく、すべての行に適用されます。

最後に、JSON や YAML 構造がもはや十分ではなく、マイグレーションしなければならないときが来ます。数行しか保存しない場合は問題ありませんが、数百万行を保存する場合はマイグレーションに数時間から数日かかることもあります。

リレーショナルデータベースはドキュメントストアではありません

JSON や YAML としてデータを保存する場合、基本的に、データベースをドキュメントストア (たとえば MongoDB) のように使っていることになります。つまり、もったいないのです。

一貫性のあるフィールド

時々シリアライズされたデータを支持する議論として、大きく異なるフィールドや値を保存しなければならないというものがあります。このような場合、シリアライズされたデータを使用することは理にかなっているかもしれません。しかし、99%の場合、格納されるフィールドや型はどの行も同じになる傾向があります。多少の違いがあっても、別々のカラムを使用し、不要なカラムを設定しないようにすればよいのです。

解決策

解決策は、別々のカラムや別々のテーブルを使用することです。これにより、データベースが提供するすべての機能を使用できるようになり、データの管理やマイグレーションが容易になります。