この「マッピング」テーブルには別のId列が必要ですか?


9

の表Producersとの表がありProducts、どちらも次の形式です。

  • Id -int、主キー
  • Name -nvarchar

プロデューサーは複数の製品を運ぶことができるため、次のようなテーブルを作成しましたProducerDetails

  • ProducerId -int、外部キー Producers.Id
  • ProductId -int、外部キー Products.Id

それから自分に問いかけ始めたので、専門家に聞いてみようと思いました。テーブルに追加のId(int、主キー)列がある方がデータベース設計が優れてProducerDetailsいるでしょうか?それとも不要ですか?

SQL-Server 2008 R2を使用しています。

編集 -これらのテーブル間の関係は多対多だと思います。申し訳ありませんが、明確にしていません。生産者は複数のタイプの製品を運ぶことができ、同じ製品が複数の異なる生産者によって生産される可能性があります。

この質問が非常に単純である場合はお詫び申し上げます。参照整合性/データベース設計は私の強みではありません(私はそれを改善しようとしていますが)。

回答:


6

プロデューサーと製品の間に1対多の関係がある場合(つまり、製品は1つのプロデューサーにのみ属することができます)、Productsテーブルに直接外部キー参照を置くだけでは意味がありません。

1対多

create table Producer
(
    id int identity(1, 1) not null primary key clustered,
    Name varchar(100) not null
)
go

create table Product
(
    id int identity(1, 1) not null,
    Name varchar(100) not null,
    ProducerId int not null foreign key references Producer(id)
)
go

ただし、これが多対多の関係になる可能性がある場合は、結合テーブルを使用することをお勧めします。

多対多

create table Producer
(
    id int identity(1, 1) not null primary key clustered,
    Name varchar(100) not null
)
go

create table Product
(
    id int identity(1, 1) not null primary key clustered,
    Name varchar(100) not null
)
go

create table ProductProducer
(
    ProductId int not null foreign key references Product(id),
    ProducerId int not null foreign key references Producer(id)
)
go

-- adding the primary key also ensures uniqueness
alter table ProductProducer
add constraint PK_ProductProducer 
primary key (ProductId, ProducerId)
go

結合テーブルを使用する場合は、組み合わせProductId/ProducerIdが最終的に一意になるため、追加のキーを用意する必要はありません それらを複合キーとして使用できるため、にその追加のIdフィールドは必要ありませんProductProducer


1
しかし、実際の質問には答えません-彼はid関係テーブルにフィールドがあることに何か価値があるのか​​と尋ねています。
JNK、2012年

@JNK質問を編集しました。ProductId, ProducerIdが一意の組み合わせである場合、Joinテーブルに別の人工キーを追加する必要はありません。同意する?そして、私が質問を誤解していない限り、OPはこの使用例では結合テーブルを使用する必要すらありません。
トーマス・ストリンガー、2012年

@ jadarnel27わかりました、説明をありがとうございます。私は私の回答のその部分に取り消し線を引いています(後で参照するための足跡を残しておくことは賢明だと思いますが)。
トーマス・ストリンガー

7

いいえ、このテーブルに「主キー」を追加しても意味がありません。あなたの加入は今までを参照しようとしているProducerIDProductIDそれだけで自重で、。私見では。

@Sharkに同意しますが、既存のテーブルのスキーマを変更しないようにしていない限り、ここでは結合テーブルは必要ないようです。

余談ですが、スキーマ全体で一貫して識別子に名前が付けられるように、プライマリ識別子に(たとえばのProducts.ProductID代わりにProducts.ID)完全な名前を付けることも価値があると思います。


@ jadarnel27:他のすべての列については、はい、それは悪い習慣と見なされます。PK列では、多くの人がこのスタイル(ProductID)を使用することを好みます。1つの利点は、を表示するとSometableID、それが参照しているテーブルがすぐにわかることです。もう一つは、あなたが使用できることであるProduct JOIN ProducerDetail USING(ProductID)代わりに長いのは、次の構文をProduct JOIN ProducerDetail ON Product.ID = ProducerDetail.ProductID
ypercubeᵀᴹ

申し訳ありませんが、これUSING(ProductID)はSQL-Serverでは利用できないので、その点は当てはまりません。
ypercubeᵀᴹ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.