我应该在这个例子中使用复合主键吗?

Should I use composite primary keys in this example?

我不是 SQL 专家,所以我尊重知识渊博的人。所以这是我的问题。我设计了一个数据库,其中每个 table 都有一个作为主键的 Id 列(自动递增)。我使用这个设计没有任何问题——这对我来说很有意义我只是通过这个简单的主键来实现参照完整性,因为所有 tables 的 Id 列唯一标识每一行。

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

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

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

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

这里没有使用单独的'linking' table,不过没关系,它展示了我的设计。

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

我的反驳论点是,如果我希望代码不重复,我可以在 Code 上创建一个 UNIQUE INDEX。而且,由于我的前端只使用 ID,并且不允许通过代码进行搜索(选择),因此不会有性能改进。在我的表示层上,如果我显示例如 Customers 并且我允许用户 select 一个查看关联的 CustomerDetails,我将 select CustomerId 上匹配的相应 tbl_CustomerDetails 行select点击客户的 id。

你有什么建议?我是对还是错?我总是愿意学习,如果我在这里错了,我很乐意学习。但目前,我觉得他们的论点是站不住脚的。这就是我问社区的原因。

谢谢!

看完你的问题和论点后我想说你没有错。 由于您的 ID 自动递增,这将始终为您的行提供唯一性。 现在谈论 code 列,然后如果 code 应该是唯一的,那么你总是可以对列有 UNIQUE 约束,这将不允许 code 的重复值,因为你是从前端做的因此无需添加带有(ID,代码)的复合主键,但请确保为 code 列添加 UNIQUE constraint 。 哥们你已经解释过了我相信你是完全正确的.

如果你要制作复合主键,那么你必须在这里考虑两件事:

  1. Composite PK on (ID,Code) will allow duplicate ID's and duplicate codes, it will not allow duplicate combinations.

  2. you have to add code column in tbl_CustomerDetails table as well if you are going to link both tables.

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

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

假设您希望通过代码区分客户:所有成员的代码都是 MEMB 加上 Id,所有供应商的代码都是 VEND 加上 Id,所有客户的代码都是 CUST 加上 Id。 "customers" 中有捐助者,他们不购买任何东西,只提供捐款。您决定区分捐赠者和客户。

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

根据您当前的设置,您只需在一处更新代码,无需进行更多更改。所以您的实施是正确的。

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

撇开编程不谈,复合键的主要缺点,尤其是需要这么多列的复合键,是需要指定所有这些数据并将其复制到子 table 以便设置table 之间的正确关系是 space 的浪费,它也增加了不必要的复杂性。

开发人员 运行 让我最头疼的是他们假设 "uniqueness of data" 等同于 "identifying a row in the database"。这种情况很少见。我发现应用程序和数据库更易于维护和易于构建,方法是默认使用单列主键,并使用复合键作为规则的例外,然后通过在这些列上使用唯一约束或索引来强制执行数据唯一性。