在此示例中是否应该使用复合主键?

时间:2018-08-14 07:09:50

标签: sql composite-primary-key

我不是SQL专家,所以我请见识更多的人。所以这是我的问题。我设计了一个数据库,其中每个表都有一个Id列(自动递增)作为主键。而且我使用这种设计没有任何问题-对我而言,我很简单地通过此简单的主键来实现引用完整性,因为所有表的ID列均唯一标识每一行。

一些同事建议我使用复合主键,但这样做没有任何价值。主键的目的是启用引用完整性,这就是它的作用。

例如,这是一个玩具示例,但它演示了我的设计:

tbl_Customers
-------------
Id (PK)
Code (VARCHAR)
Name (VARCHAR)
Surname (VARCHAR)

tbl_CustomerDetails
-----------------
Id (PK)
CustomerId (FK to tbl_Customers)
SomeDetails (VARCHAR)

这不使用单独的“链接”表,但这没关系,它演示了我的设计。

一些同事指出,我应该在composite primary key上使用tbl_Customers,不仅要像现在一样包含ID,还应包含Code。他们说这将提高性能,并且将确保代码不会重复。

我的反对论点是,如果我不想重复代码,则可以在UNIQUE INDEX上创建一个Code。而且,由于我的前端只能与Ids一起使用,并且决不允许通过代码进行搜索(选择),因此无法提高性能。在我的表示层上,如果我显示例如“客户”,并且允许用户选择一个以查看关联的“客户详细信息”,则将在“客户ID”上选择对应的tbl_CustomerDetails行,该行与单击的客户的所选ID匹配。

您有什么建议?我是对还是错?我一直乐于学习,如果我错了,我很乐于学习。但是目前,我认为他们的论点无效。这就是为什么我要问社区。

谢谢!

3 个答案:

答案 0 :(得分:1)

阅读完您的问题和论据后,我想说您没看错。 由于您具有自动递增的ID,因此将始终为您的行提供唯一性。 现在讨论code列,然后,如果code应该是唯一的,那么您始终可以对列具有UNIQUE约束,因为该约束不允许code的重复值,并且您是从前端开始进行操作的因此无需添加带有(ID,Code)的复合主键,但请确保为UNIQUE constraint列添加code。 您已经给哥们解释了,我相信您完全正确

如果要制作复合主键,则必须在此处考虑两件事:

  
      
  1. (ID,Code)上的复合PK将允许重复的ID和重复的代码,但不允许    允许重复的组合。

  2.   
  3. 如果要访问,还必须在tbl_CustomerDetails表中添加 code 列    链接两个表。

  4.   

总之,我想说我不认为在这种情况下不需要复合主键。

答案 1 :(得分:1)

如果您的问题是,是否应在示例中使用复合键,答案是肯定的!您的同事建议添加代码作为组合键不仅是不必要的,而且很可能会给您带来麻烦。让我举例说明:

假设您要按代码区分客户:所有成员的代码都为MEMB加ID号,所有供应商的代码都为VEND加ID号,所有客户的代码都为CUST加ID。 在“客户”中,是捐献者,他们什么都不买,只捐钱。您决定区分捐助者和客户。

这意味着您必须将一些客户的代码从CUST更改为DONOR plus Id。要进行更改,您将必须更新CUST的每个实例,这是DONOR的捐助者。至少可以说是一场噩梦,因为您需要找出所有以该ID作为参考的表。

在当前设置下,您所需要做的就是在一个位置上更新代码,而无需进行任何更改。因此,您的实施正确。

答案 2 :(得分:1)

我建议使用单列主键,而不要使用复合键。复合键的最大缺点是,您需要多个值/每个列来标识一行。如果您的应用程序使用O / RM(对象/关系映射)层,则适合用编程语言将这些数据库行映射到对象。当每个表具有单个列主键时,O / RM的设置最容易。

除了编程之外,通常,复合键(尤其是需要这么多列的复合键)的主要缺点是,所有这些数据都需要指定并复制到子表中,以便在浪费的表之间建立适当的关系。空间,并且也增加了不必要的复杂性。

我对开发人员最大的头痛是他们认为“数据唯一性”等同于“标识数据库中的一行”。这种情况很少发生。我发现应用程序和数据库通过默认为单列主键,并使用复合键作为规则的例外,然后通过在这些列上使用唯一的约束或索引来强制数据唯一性,从而更易于维护和构建。 / p>