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

时间:2017-08-29 16:02:44

标签: database database-design constraints entity-relationship composite-primary-key

我正在为网店建模数据库并遇到了广告问题。基本上问题是,为简单起见,是否忽略数据库规范化规则。 以下是问题发布前我的图表的相关部分。 Database diagram 基本上,产品可以有选项(大小,味道,颜色),但只有一个选项组。由于选项组可以有许多选项,并且使用它的产品可以使用子集,因此会创建ProductOption表。接下来我们有一个SpecialOffers表。接下来,特价可以有很多产品和产品可以属于许多特别优惠,因此关联表SpecialOfferProducts。所有这一切都很好,直到特别优惠包括一个有选项的产品。这是我遇到问题的地方。我有几点想法。

第一个想法: 在SpecialOfferProducts和ProductOptions之间创建关联表。我不喜欢这个想法,因为两个表都有复合主键,并且创建一个具有由两个复合主键组成的复合主键的表似乎很奇怪,我从未见过类似的东西。

第二个想法: 在SpecialOfferProducts和Options之间创建关联表。这似乎是错误的,因为Options不直接与Product绑定。这仍然可行,主键会更简单一些。

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

我的问题是,哪种选择最好?我还没有提到更好的选择吗?

使用Martin样式表示法

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

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

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

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

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

实施例。 SpecialOffer A包含一个产品A实例和两个实例产品B.

让我们说产品A有选择权。现在,SpecialOfferProducts表必须引用正确的选项。(也许产品可以是蓝色和红色,特别优惠只包括红色产品)。这是当前模式不起作用的地方,必须引入附加表(想法1和2)或更改现有表(想法3)。

1 个答案:

答案 0 :(得分:0)

也许你的前三个关系(船舶)/关联无法代表:

-- 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(外键)和&限制。 设计关系(船舶)s /关联后足以明确描述您的业务情况(由表格表示),根据可能出现的情况,出现 。 p>

从ER的角度来看,您没有正确应用参与实体(类型),实体(类型)密钥和&的概念。关联实体(类型)。

你是不必要的&模糊地害怕复合CKs。即使您想减少复合键的使用,您也应该首先找到一个简单的设计。如果您不想使用复合键,请引入id PK和其他CK。但是请注意,当您使用ID作为FK时,如果您使用了复合CK,那么根据您所需要的约束,在没有必要时使用其他ID或列的情况下放弃正确限制它们出现的表的义务。代替。

  

第一个想法:   在SpecialOfferProducts和ProductOptions之间创建关联表。我不喜欢这个想法,因为两个表都有复合主键,并且创建一个由两个复合主键组成的复合主键的表看起来很奇怪,我从未见过类似的东西。

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

从ER角度来看:您可能会将此视为特殊订单上的关系(发货)/关联&产品。但是实体密钥不是复合的,它们会识别特殊订单和产品,以及选项也参与。或者我们可以使用ER概念来实现关系(船舶)/协会SpecialOfferProducts& ProductOffers作为两个参与者的关联实体。那将使用复合键。 (如果选项不被认为是实体,则ER会将此称为弱关系(船舶)/关联实体,其中特殊订单和产品作为标识实体。)无论如何,特殊订单&产品必须就选项达成一致,如果没有通过FK强制执行,那么它仍然需要约束。

如果您(已)阅读了一些有关信息建模和发布的文本。数据库设计(你应该),你会看到复合键的许多用途。

  

第二个想法:   在SpecialOfferProducts和Options之间创建关联表。这似乎是错误的,因为Options不直接与Product绑定。这仍然可行,主键会更简单一些。

不清楚你的意思是"直接捆绑",""似乎"或"错误"。

关系表关系(船)s /关联是值之间的值,其某些子行可以标识某些实体。只需使用相关栏目&声明相关的约束。

从ER的角度来看:考虑到你似乎对参与实体(特价与SpecialOfferProduct)感到困惑,也许这是没有实际意义的,但是:如果你试图仅使用技​​术术语和如果没有混淆,那么你会试图说这个设计需要一个约束,产品选项对出现在ProductOptions中,并且约束涉及一个关系(船)/关联,其关联实体ProductOption不是&#39 ; t参与实体之一。我同意,但这样的设计不是错误的#34;

  

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

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

PS 1 请解释您的业务关系(船舶)s /协会的通用术语不是基本无意义的"有","",& #34;使用","" &安培; "属于" - 就像客户购买产品一样。特别优惠。他们指的是关系(船舶)/协会&设置,但他们不会解释他们。 (同样,基数是关系(船舶)/关联的属性,但不能解释/表征它们。)

PS 2 关于设计的ER推理涉及什么(可能是关联的)实体参与关系,而在关系模型中,视图表只捕获任意n的n元关系(船)s /关联。所以ER视图正在增加不必要的区别。这就是ER-based information modeling & database design approaches are not as effective as fact-based approaches

的原因
  

这导致标准化和约束不充分,因此冗余和完整性丧失。或者当这些步骤充分完成时,它会导致E-R图实际上没有描述应用程序,这实际上是由关系数据库谓词,表和约束描述的。然后,E-R图表既含糊又多余,而且是错误的。

PS 3 我们不需要SpecialOfferProducts,如果它包含"特别优惠S提供P和某些选项"的配对,因为它是{{1 }}。 (这似乎是这种情况,因为你的选项3只涉及一个你称之为SpecialOfferProducts的表,但就像这个表添加了id。)但是如果它保持行表示"特价商品S提供产品P&#34 ;如果不是所有的S< s"产品 - 选项对都被记录下来就可以了,那么你需要它。 (类似的东西会在决定什么东西是一个实体时出现,例如什么时候应该有一张桌子" S是一个特殊选项"。)

PS 4

  

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

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