そのため、さまざまな理由から、ポリモーフィック アソシエーションは不適切なデータベース設計と見なされます。たとえば、ポリモーフィック ID 列に外部キーを設定できないため、参照整合性が失われます。
また、サブタイプの動作のみが異なる場合を除き、STI も悪いと見なされます。
したがって、私の質問は、Rails / ActiveRecordについて、次のシナリオで害が少ないものは何ですか:
ユーザーが複数の種類のエンティティのコレクションを手動で作成できるようにする必要があります。
Polymorphic Associations を使用すると、スキーマは次のようになります。
-- collections
id, name, ...
-- exhibits
id, collection_id, exhibitable_type, exhibitable_id, position
-- photographs
id, ...
-- films
id, ...
-- paintings
id, ...
-- songs
id, ...
-- sculptures
id, ...
STI を使用して、次のようなものを使用できます。
-- collections
id, name, ...
-- exhibits
id, collection_id, artwork_id, position
-- artworks
id, type, <photograph columns>, <film columns>, <painting columns>, etc.
しかし、私のアートワークは (動作だけでなく) データが異なるため、アートワーク テーブル全体に NULL が含まれるようになりました。また、以前は存在しなかった継承階層をオブジェクトに導入しましたが、特にデータベース設計を提供することが唯一の目的である場合は、一般的に警戒しています。
STI は、クエリとコーディングが少なくとも簡単になるように思えます。
では、悪が少ないのはどれですか?
次に、他のオプションはマルチテーブル継承です。
-- collections
id, name, ...
-- exhibits
id, collection_id, artwork_id, position
-- artworks
id
-- photographs
artwork_id, <photograph columns>
-- films
artwork_id, <film columns>
これにより、STI の NULL 問題が解消され、テーブル サイズも小さくなります。厳密に必要だとは思わないオブジェクト階層がまだあります。しかし、私が思う最大の問題は、Rails がそれをサポートしていないことです。CITIER gem は非常に見栄えがよく、最近コミットされていますが、それほど広く使用されていないため、アプリの基盤で使用することには慎重です。Sequel や、CTI をサポートする別の ORM を使用することも考えられると思います。
正直なところ、私はマルチテーブル継承ソリューションが一番好きだと思います
位置列が必要ない場合はcollections_photographs
、collections_paintings
、collections_films
、 などの個別の結合テーブルを使用するだけですが、その手動の順序付けが必要です。
したがって、オプションは次のようです。
- PA: 参照整合性の喪失 (データベース アクセスに常に ActiveRecord を使用する場合、実際には問題になりますか?)
- STI: null がたくさんある大きなテーブル
- CTI/MTI: 広く使用されていない gem に依存する
悪が少ないのはどれですか?他に選択肢はありますか? Postgresを使用しています。