web-dev-qa-db-ja.com

ジャンクションテーブルで多対多のリレーションを作成するMS SQL

Microsoft SQL Server Management Studioを使用していますが、ジャンクションテーブルを作成するときにジャンクションテーブルのID列を作成する必要があります。それとも、多対多のリレーションで参加しているテーブル用に2列を保持するだけですか?

たとえば、これが多対多のテーブルの場合:

MOVIE
Movie_ID
Name
etc...

CATEGORY
Category_ID
Name
etc...

ジャンクションテーブルを作成する必要があります。

MOVIE_CATEGORY_JUNCTION
Movie_ID
Category_ID
Movie_Category_Junction_ID

[そしてMovie_Category_Junction_ID私の主キーであり、ID列として使用します]?

または:

MOVIE_CATEGORY_JUNCTION
Movie_ID
Category_ID

[そして、主キーもIDテーブルもないままにしておきます]?

29
sc00ctbr

2番目のジャンクションテーブルを使用します。

MOVIE_CATEGORY_JUNCTION
Movie_ID
Category_ID

主キーは、両方の列の組み合わせになります。また、各列からMovieおよびCategoryテーブルへの外部キーがあります。

ジャンクションテーブルは次のようになります。

create table movie_category_junction
(
  movie_id int,
  category_id int,
  CONSTRAINT movie_cat_pk PRIMARY KEY (movie_id, category_id),
  CONSTRAINT FK_movie 
      FOREIGN KEY (movie_id) REFERENCES movie (movie_id),
  CONSTRAINT FK_category 
      FOREIGN KEY (category_id) REFERENCES category (category_id)
);

SQL Fiddle with Demo を参照してください。

これら2つのフィールドをPRIMARY KEYとして使用すると、重複する映画/カテゴリの組み合わせがテーブルに追加されなくなります。

49
Taryn

これについてはさまざまな考え方があります。ある学校では、主キーを含め、リンクテーブルに、リンクしている2つのテーブルよりも重要な名前を付けることを好みます。その理由は、テーブルは単なるリンクテーブルのように見えても、重要なデータを持つ独自のテーブルになる可能性があるためです。

例は、雑誌と購読者の間の多対多です。本当にそのリンクは、有効期限、支払いステータスなどの独自の属性を持つサブスクリプションです。

ただし、リンクテーブルは単なるリンクテーブルであると思います。カテゴリとの多対多の関係は、この良い例です。

そのため、この場合、個別の1フィールドの主キーは必要ありません。自動割り当てキーを使用することもできますが、これは何も傷つけず、特定のレコードの削除を容易にします。一般的な慣行としては良いかもしれませんので、後でテーブルが(サブスクリプションとして)独自の重要なデータを持つ重要なテーブルに発展する場合、すでに自動割り当て主キーがあります。

重複を避けるために、2つのフィールドに一意のインデックスを配置できます。これにより、別の自動割り当てキーがある場合、重複を防ぐこともできます。両方のフィールドを主キー(一意のインデックスでもある)として使用できます。

そのため、ある考え方では、整数の自動割り当て主キーを使用して、複合主キーを回避できます。これはそれを行う唯一の方法ではなく、おそらく最善ではないかもしれませんが、あなたが本当に後悔する問題にあなたを間違って導くことはありません。

しかし、あなたがやっていることのようなものについては、たぶん2つのフィールドで大丈夫でしょう。 2つのフィールドを複合主キーにするか、少なくとも2つのフィールドに一意のインデックスを置くことをお勧めします。

17
Marlin Pierce

私は2番目のジャンクションテーブルに行きます。ただし、これらの2つのフィールドを主キーとして作成します。これにより、重複エントリが制限されます。

2
higgs_boson