1

プロジェクトでここで説明されているようなテーブルを使用するように誰かが私に提案しました。理由はわかりませんが、それは良い考えではないと思います。

MyTable(MyTableId PK、タイプINT NOT NULL、MyForeignKey INT NOT NULL)

MyForeignKeyは、Typeの値に応じて、さまざまなテーブルのデータを指すことができます。もちろん、そのようなモデルを使用してFKの整合性を強制することはできませんが、この議論はそれを使用しないのに十分ですか?

これを使用できる場所の例を示します。さまざまなオブジェクトに関するNotesを保存するためのNotesテーブルがシステムにあるとします。ユーザー、ドキュメントなどに関するメモ。通常、私はこれを次のようにモデル化します。

メモ(NoteId PK、Text VARCHAR(4000)、UserId INT NULL、DocumentId INT NULL、...)

私の同僚が提案しているのは、代わりにそのようなテーブルを用意することです。

メモ(NoteId PK、Text VARCHAR(4000)、ObjectType、ObjectId)

2番目の実装では、ObjectTypeは、ObjectIdがUsersテーブルまたはDocumentsテーブルの行を指しているかどうかを示します。別のタイプのオブジェクトを追加する場合は、データベース構造とコードの変更が少なくて済むという利点があります。

各ソリューションの長所と短所は何ですか?

注:無数のオブジェクトタイプが存在することはありません。10未満のままにする必要があります。

実際、私たちの実際のシナリオはもう少し複雑です。これは、ユーザーがさまざまなタイプのオブジェクト(ドキュメント、メモ、イベントなど)にアクセスできる場合とできない場合がある許可システムと関係があります。

したがって、今のところ私のデータベースモデルには、これらのオブジェクトのテーブルと、オブジェクトとユーザー(UserDocuments、UserNotes、UserEventsなど)との関係を作成するための追加のテーブルがあります。アクセス許可は、これらのリンクテーブルの属性を介して設定されます。

私の同僚は、代わりにこのような単一のパーミッションテーブルを持つことを提案しています

パーミッション(PermissionId PK、UserId INT、ObjectType、ObjectId、...その他のパーミッションフィールド...)

これは良い考えですか?

また、これをEAVまたはOpen Schemaと呼ぶことはできますか?それは私がそれらのトピックについて読んだものとまったく同じではありません。

4

2 に答える 2

2

それは悪い考えです。同じ列に複数のタイプのデータを混在させ、隣接するタイプの列を追加して曖昧さを解消すると、ほとんどの場合、結果を後悔することになります。

結合を正しく行うと、結合条件がより複雑になり、結合の実行が遅くなります。結合を間違って行うと、バグが発生します。また、タイプ列の確認を忘れることは、バグの原因となることがよくあります。

異なるテーブルへのポインタを異なる列に配置することをお勧めします。しかし、さらにうまく機能する非常に異なるデザインがあるかもしれません。

複数のタイプのオブジェクトのコレクションは、「クラステーブル階層」と呼ばれる設計手法に適しているようです。この手法では、基本的に、共有主キーを使用して、クラスとサブクラスに別々のテーブルを使用します。共有主キーには、クラステーブルからサブクラステーブルに主キーを伝播するためのアプリケーション内のコードが必要です。しかし、それは努力する価値があります。

クラステーブルとサブクラステーブルを結合すると、別のクラスに関連する行が自動的に削除されるため、別のタイプの列は不要です。それは滑らかで、簡単で、速いです。

ここSOでサブクラスのクラステーブル継承またはリレーショナルモデリングの例を探すと、有益なQ&Aが多数得られます。


「クラステーブル階層」を「クラステーブル継承」に変更するために編集されました。

于 2012-09-14T08:43:48.237 に答える
0

私の正直な意見では、ボットソリューションは正しいですが、目的は異なります。あなたが言ったように、そのようなタイプの数は重要です、そしてこれは通常決定を動かす唯一のものです。

OLTPシステムについて話していると思います。したがって、タイプの数が比較的少なく、それが変わらないと確信している場合(特に成長しない場合)は、タイプごとに別々の列を持つソリューションを選択する必要があります。

タイプの数が多い場合(私の意見では10はすでに大きい数です)、タイプとキー列を使用したソリューションを選択する必要があります。

一般に、複数列のバリアントの方が優れています。DBMSメカニズムを使用してデータの整合性を維持できるためですが、タイプ/キー列のバリアントを選択する場合は、これらのメカニズム(トリガーとプロシージャ)を独自に開発する必要があります。開発と保守の労力は構造変更の労力ほど大きくないため、タイプ/キー列のバリアントを選択する方がよい場合があります。システムの実稼働での使用中にテーブルへのFK列の追加または削除に問題がない場合は、マルチカラムバリアントを選択することもできます(その場合はストレージコストのみです)。

于 2012-09-14T15:25:14.650 に答える