此“映射”表是否需要单独的Id列?


10

我有Producers和的表Products,两者的形式均为:

  • Id -int,主键
  • Name -nvarchar

一个生产者可以携带多个产品,所以我要创建一个表ProducerDetails,该表将具有:

  • ProducerId -int,外键 Producers.Id
  • ProductId -int,外键 Products.Id

然后我开始质疑自己,所以我想问专家。IdProducerDetails表中增加一个附加列(int,主键)会更好吗?还是那是不必要的?

如果这有任何区别,我正在使用SQL-Server 2008 R2。

编辑 -我相信这些表之间的关系将是多对多的,抱歉,我没有说清楚。一个生产者可以携带多种类型的产品,并且同一产品可以由多个不同的生产者生产。

如果这个问题过于简单,我很抱歉,参照完整性/数据库设计不是我的强项(尽管我正在努力改善这一点)。

Answers:


6

如果您在生产者和产品之间存在一对多关系(换句话说,一个产品只能属于一个生产者),那么直接在Products表中放置一个外键引用是有意义的:

一对多

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

但是,如果有可能会发生多对多关系,那么最好的选择就是使用Join表。

多对多

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

如果决定使用Join表,则不需要额外的键,因为的组合ProductId/ProducerId最终将是唯一的。 您可以将它们用作组合键,因此不需要中的其他Id字段ProductProducer


1
但是,您没有回答实际的问题-他在问id他的关系表中是否有任何值?
JNK 2012年

@JNK我已经编辑了我的问题。如果ProductId, ProducerId是一个唯一的组合,我看不到需要向Join表添加另一个人工键。同意吗 而且我认为,除非我对这个问题有误解,否则OP甚至不需要为此用例使用Join表。
Thomas Stringer 2012年

@ jadarnel27好,谢谢您的澄清。我已经把答案的那一部分删掉了(尽管我认为谨慎一点,以便进一步参考)。
Thomas Stringer 2012年

7

不,在此表中添加其他“主键”没有任何价值。您的联接仅会引用ProducerIDProductID,因此它只是无谓的。恕我直言。

尽管我同意@Shark的观点,但这里似乎甚至不需要联接表,除非您不遗余力不以任何方式更改现有表的架构。

顺便说一句,我还认为有必要完整地命名您的主要标识符(例如Products.ProductID而不是Products.ID),以便在整个架构中一致地命名标识符。


@ jadarnel27:对其他所有列,是的,这被认为是不好的做法。对于PK列,许多人喜欢使用此样式(ProductID)。一个优点是,当您看到时SometableID,您会立即知道它所引用的表。另一个原因是,你可以使用Product JOIN ProducerDetail USING(ProductID)语法,而不是更长Product JOIN ProducerDetail ON Product.ID = ProducerDetail.ProductID
ypercubeᵀᴹ

抱歉,我认为USING(ProductID)SQL Server中不提供,因此这一点不适用。
ypercubeᵀᴹ
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.