8

そのため、さまざまな理由から、ポリモーフィック アソシエーションは不適切なデータベース設計と見なされます。たとえば、ポリモーフィック 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_photographscollections_paintingscollections_films、 などの個別の結合テーブルを使用するだけですが、その手動の順序付けが必要です。

したがって、オプションは次のようです。

  • PA: 参照整合性の喪失 (データベース アクセスに常に ActiveRecord を使用する場合、実際には問題になりますか?)
  • STI: null がたくさんある大きなテーブル
  • CTI/MTI: 広く使用されていない gem に依存する

悪が少ないのはどれですか?他に選択肢はありますか? Postgresを使用しています。

4

2 に答える 2

2

もう1つのオプションは、データベース構造を完全に正規化し、データをクエリにより適した形式に変換するためのビューを用意することです。これがさまざまなORMでどの程度うまく機能するかはわかりません。そのため、マイレージは異なる場合があります。一般に、データモデルは、データが実際にどのように構造化されているかに基づいていることが最善であることがわかりました。これは、保守が容易になる傾向があるためです。データが適切にモデル化されたら、ビューとストアドプロシージャを作成して、データにアクセスして操作することができます。

于 2012-11-08T13:41:10.700 に答える
0

Postgres でパーティション分割されたテーブルを使用する場合、多態性と外部キーの両方を実装できます。異なるパーティションを表すテーブルはそれぞれ異なるサブタイプを表し、それぞれ異なる制約セットを持つことができるためです。

于 2012-11-08T18:21:06.743 に答える