我应该何时将两个外键组合为一个外键?

时间:2010-11-21 23:40:44

标签: sql-server tsql primary-key

我的教导说我应该将两个外键组合成一个主键。但我的思维过程是只允许每个外键的一个组合。

想象一下,我有一个产品,购买,购买详细信息。

在PurchaseDetail中我有两个外键,一个用于产品,一个用于购买。我的老师说我应该将这两个外键组合成一个。但是,产品不能在许多不同的购买中?很多购买都有很多产品?

我很困惑。

谢谢!

编辑:这是我老师看到的SQL,然后给出了反馈。感谢指导人员。 (我将基本改为英语)

create table Purchase
(
    ID int primary key identity(1,1),
    IDCliente int foreign key references Cliente(ID),
    IDEmpleado int foreign key references Empleado(ID),
    Fecha datetime not null,
    Hora datetime not null,
    Amount float not null,
)

create table PurchaseDetail
(
    ID int primary key identity(1,1),
    IDPurchase int foreign key references Purchase(ID),
    IDProductOffering int foreign key references ProductOffering(ID),
    Quantity int not null
)

create table Product
(
    ID int primary key identity(1,1),
    IDProveedor int foreign key references Proveedor(ID),
    Nombre nvarchar(256) not null,
    IDSubcategoria int foreign key references Subcategoria(ID),
    IDMarca int foreign key references Marca(ID),
    Fotografia nvarchar(1024) not null
)

create table ProductOffering
(
    ID int primary key identity(1,1),
    IDProduct int foreign key references Product(ID),
    Price float not null,
    OfferDate datetime not null,
)

也许我对良好的数据库架构设计感到困惑。再次感谢!

5 个答案:

答案 0 :(得分:1)

我想他正在暗示:

  • 产品 - 一个主键(产品ID),表示唯一的产品ID
  • 购买 - 一个主键(购买ID),表示唯一的购买ID
  • PurchaseDetail - 两个外键(产品ID),(购买ID),以及(产品ID +购买ID)上的一个唯一约束

另外有些人认为所有表都应该有自己的主键,而不依赖于其他任何东西(购买明细ID)。有些DBMS强制要求这样做。

这意味着您不能在PurchaseDetail中拥有两行具有相同产品和购买的行。这是有道理的,假设在PurchaseDetail上还有一个数量列,这样一次购买就可以有多个产品。

请注意,唯一约束外键之间存在差异。外键仅表示在父表中应该有一个具有该id的项 - 它将允许您在子表中创建所需数量的项。如果要避免重复,则需要指定列或列组合是唯一的。另一方面,主键意味着唯一约束。

定义所有这些的确切语法因语言而异,但这些都是原则。

答案 1 :(得分:0)

我不同意单键,但它们可能是复合键(我倾向于不喜欢)。它们可以是两个不同的字段,每个字段都限制在相应表中的ID。

不确定为什么同一产品iD需要在一次购买时多次列出?这不是你说明数量的原因吗?也许需要为购买和折扣单独订购项目?

答案 2 :(得分:0)

我相信thelem已正确回答。但还有另一种选择。您可以在详细信息表中添加新的主键列,如下所示:

detail_id   int (PK)
product_id  int (FK)
purchsae_id int (FK)

这不是必需的,但是如果您需要将详细信息表作为外键引用 - 有一个主键字段用于较小的索引和外键引用(它们有点),它可能很有用更容易打字。)

答案 3 :(得分:0)

也许他建议使用多对多表,其中主键由映射表的外键组成:

PurchaseDetail:

ProductId          int (FK) 
PurchaseId         int (FK) 
PK(ProductId, PurchaseId)  

这也可以建模为

PurchaseDetail:

PurchaseDetailId   int (PK, Identity)
ProductId          int (FK) 
PurchaseId         int (FK) 

如果你想在你的模型中的其他地方引用购买细节,那么第二种形式很有用,而且在某些RDBMS中,在一个单音增加的整数上使用PK是有益的。

答案 4 :(得分:0)

这取决于您需要表示的数据。

如果您使用两个外键作为购买详细信息的主键,则每次购买时只能出现一次产品。但是,购买可能仍然包含许多产品,并且许多购买产品仍可能出现。

如果购买详情包含更多信息,您可能需要在购买时多次使用产品。例如,如果购买细节包含尺寸和颜色,并且您想要穿红色T恤尺码XL和蓝色T恤尺码S.