数据库主键 - >身份字段和名称字段?

时间:2009-04-14 01:43:15

标签: database-design primary-key

我的所有表都有某个类型的Id字段(UserId, PostId, FooId等)。我通常将其设为主键

我的表名为Countries。它有

CountryId SMALLINT
Name VARCHAR(100)  -- Yes, english country names only, in this column.
AndSomeOtherFields.

现在,我知道Name必须是唯一的。所有国家/地区名称都是唯如果我制作PrimaryKey == CountryId ASC Name ASC,这是好/坏/茹?

如果它很好,有人可以解释为什么它比PK {?{}更好吗?它只是确保数据完整性(例如,表中没有两个国家名称)。如果这很糟糕......为什么?

非常感谢。

6 个答案:

答案 0 :(得分:6)

使主键CountryId Name不能确保名称是唯一的。它只是确保每个CountryId - Name 都是唯一的,显然CountryId已经是唯一的,是一个“ID”。因此,您仍然可以使用1-US19-US,因为这些对是唯一的。

使它们成为主键的唯一原因是,如果您经常执行在Where子句中使用CountryId和Name的查询。主键默认情况下创建一个聚簇索引,它对表进行物理排序,因此它可以非常快速地查找针对这些谓词的行。

另一个要提出的要点是,在您的特定示例中,您要存储的国家/地区列表a)非常短且b)变化不大。无论你做什么,针对这个表的查找都将非常快。即使SQL Server每次都必须进行全表扫描,您甚至可能都不会注意到。您不必担心页面碎片。您可以跳过ID列并使用Name作为主键。

或者,如果您想保留ID但仅强制使用国家/地区名称的唯一性,则可以在“名称”列上put a Unique Constraint

在一个答案中,很难涵盖主键,聚簇索引和索引的问题。以下是一些很好的入门资源:

答案 1 :(得分:1)

将名称变为PK并不总是最佳解决方案,我相信CountryId足以作为您桌面的PK,但是如果Name是一个您将使用很多字段来查询的字段,即:选择,加入,您应该以这种方式索引此字段,通过此字段筛选的查询将提高其速度

祝你好运:)

答案 2 :(得分:1)

在列Name上创建唯一索引

答案 3 :(得分:0)

我唯一能想到的就是非常明显:你的指数会更大一些。话虽如此,这并不是一件大事,因为你的桌子只会存储国家。但是,你为什么要这样的指数?如果按 CountryId 排序,则按名称排序为第二个字段是没有意义的。您将始终获得相同的订单。

真正糟糕的一件事是将外键指向一个大的主键,因此,请确保如果使用该主键,指向 Countries 的外键仍然使用只有 CountryId 列。

答案 4 :(得分:0)

众所周知,国名不会改变国家的身份。这表明该名称不应该是PK的一部分。

答案 5 :(得分:0)

如果您需要强制执行唯一性,请使用约束。