如何避免复合实体键和约束(产品、选项、选项组、特殊订单)出现问题



我正在为一家网店建模数据库,遇到了广告问题。基本上,问题是为了简单起见,是否忽略数据库规范化规则。以下是在发布之前我的图表的相关部分。数据库关系图基本上,产品可以有选项(尺寸、口味、颜色),但只能从一个选项组中选择。由于一个选项组可以有许多选项,而使用它的产品可以包含一个子集,因此会创建一个ProductOption表。接下来我们有一张特价优惠表。接下来,一个特价可以有许多产品,并且产品可以属于许多特价,因此形成了SpecialOfferProducts关联表。所有这些都很好,直到特别优惠包括一个有选择的产品。这就是我遇到问题的地方。我有几个想法。

第一个想法:在SpecialOfferProducts和ProductOptions之间创建关联表。我不喜欢这个想法,因为两个表都有复合主键,而创建一个由两个复合主键组成的复合主键表似乎真的很奇怪,我从来没有见过这样的情况

第二个想法:在SpecialOfferProducts和Options之间创建关联表。这似乎是错误的,因为选项并没有直接绑定到产品。尽管如此,这还是可行的,而且主键也会简单一点。

第三个想法:这是我最喜欢的一个,但它违反了一些规则。更改SpecialOfferProducts表。使其拥有自己的主键,并将SpecialOffers、Products和Options作为外键。只需将Options外键设为null即可解决问题。当然,问题是我没有在应该做的地方创建关联表,而是使外键可以为null。这会使我的代码处理所有这些稍微复杂一些,但我仍然觉得这比其他方法简单得多,因为我减少了复合键的数量,而且在特价产品使用选项的情况下,我不必添加另一个表。

我的问题是,这些选项中哪一个最好?还有我没有提到的更好的选择吗?

使用马丁式记法

OptionGroups与Options表具有(0,n)关系。Options和OptionGroups表有(1,1)关系。这些表的目的是存储颜色、大小等信息。例如,OptionGroups条目颜色具有黑色、白色等选项条目。

乘积表与OptionGroups表具有(0,1)关系。OptionGroups与表Product具有(0,n)关系。产品表与选项表具有(o,n)关系。选项表与产品表具有(o,n)关系。多对多关系生成关联表ProductOptions。ProductOptions有一个复合PK ProductID OptionsID。这些表的目的是允许产品具有(但不必具有)某个选项组中的选项,但不需要具有该组中的所有选项。

示例1。产品没有任何选项,因此FK Product_OptionsGroups为null。在这种情况下,产品在ProductOptions表中没有任何条目。

示例2。产品具有选项(比如颜色),因此FK Product_OptionsGroups不为null(具有相应选项组的ID)。选项组颜色可以有多种颜色,并且允许产品使用其中一种或多种颜色。产品使用的颜色是ProductOptions表中的条目。

SpecialOffer表与Products表具有(1,n)关系。Products表与SpecialOffer表具有(0,n)关系。多对多关系创建关联表SpecialOfferProducts。此表有一个PK SpecialOfferID,ProductID。该表具有指示产品数量的"数量"属性。

示例。SpecialOffer A包括一个产品A实例和两个产品B实例。

假设产品A有选项。现在SpecialOfferProducts表必须引用正确的选项。(也许产品可以是蓝色和红色,而特惠仅包括红色产品)。这是当前模式不起作用的地方,必须引入一个附加表(想法1和2)或更改现有表(想法3)。

也许你有一些关系(船)/关联,不能用你的前三个来表示:

-- special offer S offers the pairing of P and option O
SpecialOfferProductOption(S, P, O)
-- PK (S, P, O)
-- FK (S, P) to SpecialOfferProducts, FK (P, O) to ProductOptions

您似乎不了解复合密钥、CK(候选密钥)、FK(外键)&约束。根据可能出现的情况,在您设计了足以清楚描述您的业务情况(用表格表示)的关系/关联后,约束(PKs、UNIQUE、FKs等)就会出现

从ER的角度来看,您没有正确地应用参与实体(类型)、实体(类型,key&关联实体(类型)。

你是不必要的&有点害怕复合CKs。即使您想减少复合键的使用,也应该首先找到一个简单的设计。如果您不想使用复合密钥,请引入id PKs和其他CK。但请注意,当您使用id作为FK时,它不会放弃正确约束它们所出现的表的义务,以便在必要时根据您使用复合CK所需的约束与其他id或列相一致。

第一个想法:在SpecialOfferProducts和ProductOptions之间创建关联表。我不喜欢这个想法,因为两个表都有复合主键,而创建一个由两个复合主键组成的复合主键表似乎真的很奇怪,我从来没有见过这样的情况

不清楚你的意思。也许你的意思是上面的(好的)设计。也许你的意思是有重复的产品栏;但这不是好的设计所暗示的。

从ER的角度来看:你可能会认为这是一种特殊订单的关系(船舶)/关联&产品。但是实体键将不是复合的,它们将识别特殊订单&产品和选项都将参与。或者我们可以使用ER概念来具体化关系(船舶)s/associations SpecialOfferProducts&ProductOffers提供给作为两个参与者的关联实体。这将使用复合键。(如果期权不被视为实体,那么ER将称之为具有特殊订单的弱关系(船舶)/关联实体&产品作为识别实体。)无论如何,特殊订单&产品必须就选项达成一致,如果没有通过FK强制执行,那么它仍然需要约束。

如果你已经阅读了一些关于信息建模的文章;数据库设计(正如您应该看到的那样)您将看到复合键的许多用法。

第二个想法:在SpecialOfferProducts和Options之间创建关联表。这似乎是错误的,因为选项并没有直接绑定到产品。尽管如此,这还是可行的,而且主键也会简单一点。

不清楚你所说的"直接捆绑"、"似乎"或"错误"是什么意思。

关系表-关系(船舶)/关联是值之间的关系,其某些子例程可以标识某些实体。只需使用相关列&声明相关约束。

从ER的角度来看:考虑到你似乎对参与者实体(特别优惠与特别优惠产品)感到困惑,也许这是没有意义的,但是:也许如果你试图只使用技术术语&如果没有混淆,那么你会试图说这个设计需要一个约束,即产品选项对出现在ProductOptions中,并且该约束涉及一个关联实体ProductOption不是参与实体之一的关系(ship)/关联,这很混乱。我同意,但这样的设计并不是"错误的"。

第三个想法:这是我最喜欢的一个,但它违反了一些规则。更改SpecialOfferProducts表。使其拥有自己的主键,并将SpecialOffers、Products和Options作为外键。只需将Options外键设为null即可解决问题。

除了不必要的复杂之外,这种设计也很糟糕。它涉及一个复杂的表,意思是&复杂的约束。当设置表格值时,您需要决定何时使用&不使用null。阅读时,你需要根据一行是否为null来判断它的含义。引入一个或多个null(可能是在删除列时)并不能消除约束剩余列的义务,如果这不由剩余的FK约束处理的话。通常,我们在合并表的同时,在不是每个CK的列中引入null——这不是您的情况。在这里,添加id甚至不需要将产品对和非null选项列值约束在ProductOptions中。当存在NULL选项列值时,ProductOptions中应该仍然存在某些行,有时SpecialOfferProducts中不存在某些行。此外,这种设计必须用于处理NULL存在的复杂查询。(你要解决这个问题。)将其作为ER设计来证明也是有问题的。

PS 1请用比基本上没有意义的"拥有"、"带有"、"使用"、"在"&"属于"——就像你对购买你的产品的客户所做的那样;特别优惠。它们指的是关系(船舶)s/associations&集合,但它们没有解释它们。(类似地,基数是关系/关联的属性,但不解释/表征它们。)

PS 2关于设计的ER推理涉及哪些(可能是关联的)实体参与关系,而在关系模型视图表中,表只捕获任何n的n元关系(船舶)s/关联。因此,ER视图添加了不必要的区别。这就是为什么基于ER的信息建模&数据库设计方法不如基于事实的方法有效:

这会导致不充分的规范化和约束,从而导致冗余和完整性损失。或者,当这些步骤充分完成时,就会导致E-R图实际上并没有描述应用程序,而应用程序实际上是由关系数据库谓词、表和约束来描述的。那么E-R图是模糊的、多余的和错误的。

PS 3如果SpecialOfferProducts包含"special offer S提供p和某些选项的配对"行,则我们不需要SpecialOfferProduct,因为它是select S, P from SpecialOfferProductOption。(情况似乎是这样的,因为您的选项3只包含一个表,您称之为SpecialOfferProducts,但与添加了id的表类似。(在重新决定什么时候某个东西是一个实体时,也会出现类似的情况,例如什么时候应该有一个表"S是一个特殊选项"。)

PS 4

看起来真的很奇怪,我从来没有见过像这样的东西

这是人生的故事。但在技术背景下,如果我们学习并应用明确定义的基本定义、规则和;程序,然后我们"看到"更多,更清楚。(不要含糊地认为我们模糊地看到了不存在的东西。)"奇怪"是一种罕见的情况,我们可以明确地证明我们的工具不适用。

最新更新