1

モデル化しようとしている多対多の関係に、どちらかまたは両方のタイプの状況があります。

だから私はこれらのテーブルを持っています:

Message
----
*MessageID
MessageText

Employee
----
*EmployeeID
EmployeeName

Team
----
*TeamID
TeamName

MessageTarget
----
MessageID
EmployeeID (nullable)
TeamID (nullable)

したがって、aは、sのリスト、またはsのリストMessageのいずれかをとして持つことができます。私が持っているテーブルは、この関係を実装するための最良の方法を上回っていますか?効果的にどのような制約を課すことができますか?テーブルに主キーを作成するにはどうすればよいですか?EmployeeTeamMessageTargetMessageTargetMessageTargetMessageTarget

問題のデータベースはSQLServer2008です

4

6 に答える 6

3

1 つのメッセージの MessageTargets にすべて employeeID セットまたは teamID を設定し、両方を混在させないようにしたいですか?

RDBMS によっては、マテリアライズド ビューを作成し、それに制約を加えることができる場合があります。ビューは次のようになります

select messageId, count(employeeId), count(teamId) from messageTarget

その上で、カウントの 1 つがゼロであることを保証するチェック制約を配置します。

または、MessageTarget を 2 つのテーブル (EmployeeMessageTarget と TeamMessageTarget) に置き換えることもできます。それぞれのテーブルには、TargetId と、最初のテーブルの EmployeeId と 2 番目のテーブルの TeamId のみが含まれます。

Message テーブルは 2 つの新しいフィールドを取得します: EmployeeMessageTargetId と TeamMessageTargetId に加えて、それらの少なくとも 1 つが null であることを保証するチェック制約です。両方のフィールドを一意にすると、*MessageTarget テーブルから外部キーを取得できます。

于 2012-08-28T04:26:46.630 に答える
3

あなたがこれを提示する方法は、Employee is-a MessageTargetTeam is-a のよう MessageTargetです。
したがって、 aMessageには、または a のTargetいずれかであるa があります。 これは、SQL の継承 (または合成) の問題に似ているように思えます。この「 SQL Server でのテーブル継承の実装 」を確認してください。Anはそれ自体ではありませんが、おそらくこれに関する測定値は、モデリングに役立つ可能性がありますEmployeeTeam

EmployeeMessageTarget

于 2012-08-27T21:55:48.850 に答える
2

従業員とチームが同じメッセージを混在させることはできないため、次のようなことを行う必要があります。

ここに画像の説明を入力してください

  • MessageEmployee.MessageIdForEmployee参照Message.MessageIdForEmployee
  • MessageTeam.MessageIdForTeam参照Message.MessageIdForTeam

Messageまた、テーブルには次の制約があります。

CHECK (
    (MessageIdForEmployee = MessageId AND MessageIdForTeam IS NULL)
    OR
    (MessageIdForEmployee IS NULL AND MessageIdForTeam = MessageId)
)

子テーブルの種類ごとに個別のジャンクションテーブルがあり、ジャンクションテーブルは親のPKを参照しないことに注意してください。代わりに、各ジャンクションテーブルは個別のUNIQUEフィールドを参照します。NULL以外のフィールドは1つだけであるため、特定のメッセージに接続できるのは1種類の子アイテムのみです。

注:またはと一致MessageIdする必要は厳密にはありませんが、クエリが多少簡略化される場合がありますMessageIdForEmployeeMessageIdForTeam

于 2012-08-28T15:50:24.050 に答える
1

is-a 関係は、多くの場合、gen-spec パターンのインスタンスです。クラス テーブルの継承は、gen-spec の場合のテーブルを設計する 1 つの方法です。

http://martinfowler.com/eaaCatalog/classTableInheritance.html

于 2012-08-28T00:59:56.917 に答える
1

あなたも考慮するかもしれません

MessageTarget
----
MessageID
targetID (not nullable)
targetType

次に、タイプを必要な方に設定します...

于 2012-08-27T21:52:16.690 に答える
0

MessageTarget エンティティの「チーム ID」フィールドを削除して、messageId と employeeId のみを取得することを検討してください。チームに対応するために (各従業員がチームのメンバーでなければならないことが要件である場合)、別のエンティティ「チーム メッセージ」を使用できます。このエンティティでは、データベース トリガーにより、そのテーブルへの挿入時に、チーム内の各従業員のメッセージ ターゲット テーブルの行。このようにして、各メッセージから MessageTarget テーブルの従業員にリンクしたり、「チーム メッセージ」テーブルからチームにリンクしたりすることができます。また、従業員エンティティが単純にリストを持ち、チームも同じリストを持つ ORM フレームワークで便利なアクセスを実現します。

于 2012-08-28T04:12:14.397 に答える