什么时候应该将两个外键合并为一个外键?

发布于 2024-10-03 19:59:27 字数 1298 浏览 7 评论 0原文

我的老师说我应该将两个外键组合成一个主键。但我的思考过程是,这将只允许每个外键的一种组合。

假设我有一个产品、购买、购买详细信息。

在PurchaseDetail 中,我有两个外键,一个用于产品,一个用于购买。我的老师说我应该将这两个外键合并为一个。但同一种产品不能被多次不同的购买吗?而且多次采购有很多产品?

我很困惑。

谢谢!

编辑:这是我老师看到的 SQL,然后给出了反馈。谢谢各位的指导。 (我将essential改为英语)

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,
)

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

My teach said I should combine two foreign keys into a single primary key. But my thought process is that that would allow for only one combination of each foreign key.

Imagine I have a Product, Purchase, PurchaseDetail.

In PurchaseDetail I have two foreign keys, one for product and one for purchase. My teacher said that I should combine these two foreign keys into a single one. But can't a product be in many different purchases? And many purchases have many products?

I'm confused.

Thanks!

Edit: This is the SQL my teacher saw and then gave feedback upon. Thanks for the guidance guys. (I changed the essential to English)

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,
)

Maybe I'm confused about good database schema design. Thanks again!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

静若繁花 2024-10-10 19:59:27

我想他是在建议:

  • 产品 - 一个主键(产品 id),这意味着一个唯一的产品 id
  • 购买 - 一个主键(购买 id),这意味着一个唯一的购买 id
  • 购买详细信息 - 两个外键(产品 id),(购买 id ),加上(产品 id + 购买 id)上的一个唯一约束,

加上一些人认为所有表都应该有自己的主键,不依赖于其他任何东西(购买详细信息 id)。一些 DBMS 强制执行此操作。

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

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

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

I imagine he's suggesting:

  • Product - one primary key (product id), which implies a unique product id
  • Purchase - one primary key (purchase id), which implies a unique purchase id
  • PurchaseDetail - two foreign keys (product id),(purchase id), plus one unique constraint on (product id + purchase id)

Plus some people argue that all tables should have their own primary key that doesn't depend on anything else (purchase detail id). Some DBMS make this mandatory.

This means that you can't have two rows in PurchaseDetail that have the same product and purchase. That makes sense, assuming there is also a quantity column on PurchaseDetail, so that one purchase can have more than one of each product.

Note that there is a difference between a unique constraint and a foreign key. A foreign key merely says that there should be an item with that id in the parent table - it will let you create as many references to that item as you want in the child table. You need to specify that the column or combination of columns are unique if you want to avoid duplicates. A primary key on the other hand implies a unique constraint.

Exact syntax for defining all of this varies by language, but those are the principles.

饭团 2024-10-10 19:59:27

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

不确定为什么同一个产品 ID 需要在单次购买中多次列出?这不是你注明数量的原因吗?也许需要为购买和折扣做一个单独的行项目?

I don't agree with the single key, but they could be a compound key (which I tend to dislike). They can be two different fields each restricted to the ID in the corresponding tables.

Not sure why the same product iD would need to be listed more than once for a single purchase? Isn't that why you indicate quantity? Maybe the need to do a separate line item for a purchase and a discount?

枕花眠 2024-10-10 19:59:27

我相信他们的答案是正确的。但还有另一种选择。您可以向详细信息表添加一个新的主键列,因此它看起来像这样:

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

这并不是真正必要的,但如果您需要将详细信息表作为外键引用 - 有一个主键,那么它可能会很有用键字段使得索引和外键引用更小(并且它们更容易输入)。

I believe thelem has answered correctly. But there is another option. You could add a new primary key column to the details table, so it looks like this:

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

This is not really necessary, but it could be useful if you need to ever need to reference the details table as a foreign key - having a single primary key field makes for smaller indexes and foreign key reference (and they are a little easier to type).

遇见了你 2024-10-10 19:59:27

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

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

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

That depends on what data you need to represent.

If you use the two foreign keys as the primary key for the purchase detail, a product may only occur once in each purchase. A purchase may however still contain many products, and a product may still occur in many purchases.

If the purchase detail contains more information, you may need to be able to use a product more than once in a purchase. For example if the purchase detail contains size and color, and you want to by a red T-shirt size XL and a blue T-shirt size S.

糖粟与秋泊 2024-10-10 19:59:27

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

PurchaseDetail:

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

这也可以建模为

PurchaseDetail:

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

如果您想在模型中的其他地方引用购买详细信息,第二种形式很有用,而且在某些 RDBMS 中,对单调递增的整数进行 PK 也是有益的。

Perhaps he is suggesting a many-to-many table where it's Primary Key is comprised of the Foreign Keys to the mapped tables:

PurchaseDetail:

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

This can also be modelled as

PurchaseDetail:

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

The second form is useful if you want to refer to Purchase details elsewhere in your model, and also in some RDBMS's it is beneficial to have a PK on a montonically increasing integer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文