使用复合键识别行的指南


8

使用一组4列将行标识为唯一的(一种是前键,另一种是float数据类型)是一种好习惯(或者会产生不利影响)吗?我正在尝试构建一个表(链接了4个键),该表将描述表中的唯一条目。我很好奇这是一个好的进攻计划还是有更好的方法。

出于视觉目的,请绘制下表。我们的库存项目的组织方式如下表所示:([K]是主键的象征,线是关系)

    Sheet_Class        Sheet_Type         Sheet_Size
    ===========        ==========         ==========
[K] Sheet_Class-.  [K] Sheet_Type--.  [K] Sheet_Size
                 '---- Sheet_Class  '---- Sheet_Type
                                          Length
                                          Width
                                          Thickness

数据可以通过以下方式呈现,但是为了简洁起见,我不介绍链接的列:

 Sheet_Class    Sheet_Type    Sheet_Size                        (Tables)
[Sheet_Class]  [Sheet_Type]  [Length], [Width], [Thickness]     (Column Values)
=============  ============  ==============================

Aluminum
               5052-H32
                             48, 96, 0.032
                             48, 96, 0.040
                             48, 96, 0.063

               6061-T6
                             60, 120,0.032
                             60, 120,0.040
                             60, 120,0.063

Steel
               1018-CRS
                             48, 96, 0.018
                             48, 96, 0.023
                             48, 96, 0.031

就目前而言(我在上面的“模式”中已显示),我在Sheet_Size表中的条目中使用了一个简单的(自动递增)整数主键。但是,我想知道最好使用Sheet_TypeLengthWidthThickness列的组合来代替吗?鉴于Sheet_Size中的每个条目都应该共享所有这些独特的特质,并且自动递增字段不能充分说明这一点,这是最好的方法吗?

如果我对这种情况的解释不够充分,请告诉我。我发现自己需要分解库存材料的这些部分(类别vs.类型vs.实际库存大小)以用于其他逻辑目的,但是我可以接受任何其他类型的反馈。

任何指导将不胜感激。

更新(08-12-2011)

发布答案后,我决定将Mark的答案X-Zero的答案结合起来。我认为在长度,宽​​度和厚度列上设置唯一的约束是一个好主意,但我也喜欢将材料尺寸分成唯一的行并将它们与关系链接的想法。

不幸的是,我不能同时接受这两个答案,因此我将接受X-Zeros(以我的看法)对问题进行更严格的评估并提供模式调整。

谢谢大家的回答。

Answers:


6

考虑了这一点之后,我将稍微修改一下您的表结构。
首先,修改您的图纸尺寸表:

Sheet_size
===========
Id
Length
Width
Thickness

其次,创建一个图纸尺寸/类型关系表:

Sheet_size_type
================
Sheet_Type_Id
Sheet_Size_Id

然后,创建以下约束:

  1. 的主键(和索引)Sheet_size应为id列
  2. 应该在中的维度上实施某种唯一键(和索引)Sheet_size。考虑一下,两张尺寸为(48、96,.5)和(96、48,.5)的纸张是否相等(也就是说,尺寸的方向重要吗?)?如果通过将列用作主键的一部分,这种问题可能很难实施,但是在使用约束和存储过程时,这种问题变得更加易于管理。
  3. 的主键(和索引)Sheet_size_type应该使用两个外键,从基数较低的外键开始(可能是sheet_type您的示例)。您可能需要另一个方向的附加索引,但是可能没有必要。

此修订版将节省您的数据库空间(使用相同大小的图纸类型的数量之比),并且不会对开销造成太大影响。


如果您使用的是float数据类型,则还存在其他有关相等性/唯一性的潜在问题,因为不精确性可能会使您意外崩溃。您应该考虑是否一定精度的定点类型会更合适。


我打算将“长度”和“宽度”限制为单个(可能是两个)小数点,并且厚度(最多)会扩展到三个。除此之外,我们变得太有限了(无论如何,股票本身永远不会出现在描述的数字上)。除此之外,我喜欢打破纸张尺寸的想法,但是我面临的问题是涉及的其他列(我已经排除在外)。(需要更多空间,请参阅下一篇文章)
布拉德·克里斯蒂

因为这是库存清单,所以我必须包括其他信息,例如密度和成本/磅(很大程度上取决于类型(甚至厚度)。例如,“钢” /“ 1018”可能是$ 0.55 /磅厚度为0.018-0.125英寸,但一旦厚度超过0.125英寸,则为$ 0.65 /磅。(而且,尺寸为1018的48“ x96” x0.250“相对于5052-H32的尺寸也可能有所不同)。在您的示例中,我只有一个条目用于48“ x96” x0.125“(尽管我认为关系表可以包含这些附加指标)
Brad Christie

如果只需要少量小数位,则可以,请使用固定的精度。是的,在这里(在这种情况下)您将放置类似的信息(例如,成本取决于图纸类型和尺寸),尽管您可能希望生成可以引用的其他表。您可能还需要考虑创建自定义数据类型(例如密度),以便人们不要试图以意外的方式查询数据。
Clockwork-Muse

6

看起来像一个天然 VS 代理关键的决定,认为在其范围从考虑和实践,以学术,近乎教条。根据RDBMS,对物理模型有一些考虑因素,这些因素可能会对性能产生重大影响,例如SQL Server中的群集键选择。

就个人而言,如果我有一个狭窄的单一属性候选键,我很想使用它。宽键和/或组合键,默认情况下,我向模型添加了一个替代项。在您的情况下,我将对Sheet_Size上的identity列进行投票,将其作为主要的群集键,并对类型/长度/宽度/厚度进行唯一约束。


但是,假设您现在已为行指定了“任意”键,那么唯一性如何强制列(组合时)不能具有重复值?据我了解,唯一属性与键有关。你是说Sheet_Size INT PRIMARY KEYLength UNIQUEWidth UNIQUEThickness UNIQUE?我仍然不明白如何防止在表中重复(不对插入接口应用逻辑)。(也许我想念什么吗?)
布拉德·克里斯蒂

这三列的唯一约束:ALTER TABLE dbo.Sheet_Size ADD CONSTRAINT UC_LengthWidthThickness唯一([Length],[Width],[Thickness])
Mark Storey-Smith

感谢您的反馈。我确实同意在列上设置唯一约束将是一个很好的解决方案,但是我也喜欢X-Zero的建议,将大小分成一个新表(与一个新表链接)。因此,为了综合考虑,我将对“精简”尺寸表应用唯一约束,同时删除密度和成本/磅信息并将其放置在关系表中。
布拉德·克里斯蒂

4

我会重定向你有点这个答案前面的问题

Quote:“关于设计该主键的方式,有两种思路:

  • 使PK成为通常由自己生成的单独列,例如GUID或自动递增INT(在您的情况下为单独的uniqueidentifier列);
  • 使PK成为表内部的一列(或一组列)的PK(在您的情况下将是用户名,电子邮件或SSN,无论使该用户具有唯一性)都可以唯一地标识一条记录。

您坚持哪种路线,只取决于口味。”

任何选择的解决方案的副作用可能是:

  • 在各处使用复合键将可能:

    • 增加所有涉及表的存储;
    • 增加/使用常用FK的索引;
    • 使所有连接语句的编写变得有些复杂
    • Joe Celko先生高兴:-)(关于他对自然或人造钥匙的看法的参考可以在这里这里找到,并且几乎到他被问到这个问题的任何地方)
  • 使用生成的密钥可能会:

    • 简化前3个步骤
    • 使具有身份PK的表复制的情况变得复杂(此处此处此处引用)

我个人更喜欢生成的INT IDENTITY密钥,但是适合您的应该没问题。


2

复合键非常合理。实施该密钥可确保业务属性不能重复。这是一件好事,因为多次记录相同的数据会导致模棱两可,令人不快的依赖关系,并使用户错误和不正确的数据更有可能出现。

单靠自动递增密钥就无法保护您的业务数据的完整性。如果自动递增键没有特殊用途(例如,作为另一个表中外键引用的目标),则可以安全地将其删除。


...除了将自动增量作为外键删除之外,还需要将所有维度列用作外键的一部分(即,包括类型在内的所有四列)。不是我想要的东西,我的外键,句点-请只输入单列。我同意在尺寸(和类型,取决于表设计)上放置唯一键(和/或检查约束)是个好主意。
Clockwork-Muse

@ X-Zero,我在第二段中确实提到了外键引用。在我阅读本文时,问题是是否要实现复合键,而不是是否还要具有自动增量。
nvogel
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.