SQL:要主键还是不要主键?

时间:2009-05-06 08:26:15

标签: sql indexing primary-key

我有一个包含用户设置的表格,它包含以下列:

UserID INT
Set VARCHAR(50)
Key VARCHAR(50)
Value NVARCHAR(MAX)
TimeStamp DATETIME

UserID与Set和Key一起是唯一的。因此,特定用户在特定设置集中不能具有两个相同的键。设置按集检索,因此如果用户从某个集合请求某个密钥,则会下载整个集合,以便下次需要来自同一集合的密钥时,不必转到数据库

我应该在所有三列(userid,set和key)上创建一个主键,还是应该创建一个具有主键的额外字段(例如,一个名为SettingID的自动增量整数,我猜是坏主意),或者不是创建主键,只创建一个唯一索引?

-----更新-----

只是为了清理:这是行表的一个结尾,它无论如何都没有加入。 UserID是Users表的FK。套装不是FK。它几乎是我GUI的帮助表。 举个例子:用户第一次访问网站的部分内容,这是一个帮助气球,他们可以根据需要关闭。一旦他们点击它,我将添加一些设置到“GettingStarted”设置,该设置将声明他们的helpballoon X已被禁用。下次当用户访问同一页面时,该设置将指出不再显示帮助气球X.

8 个答案:

答案 0 :(得分:7)

拥有复合唯一键通常不是一个好主意。

将任何业务相关数据作为主键也可能会给您带来麻烦。例如,如果您需要更改值。如果应用程序无法更改该值,则可能是将来,或者必须在升级脚本中更改。

最好创建一个代理密钥,一个没有任何商业含义的自动编号。

更新后

修改

在这种情况下,您可以考虑使用概念上没有主键,并将这三列作为复合唯一键的主键(以使其可更改)。

答案 1 :(得分:2)

  

我应该在所有三列(userid, set, and key)

上创建主键

制作这个。

使用代理主键将导致额外的列不会用于其他目的。

创建UNIQUE INDEX以及代理主键与创建非群集PRIMARY KEY相同,并且会导致额外的KEY lookup,这会对性能造成影响。

在没有UNIQUE INDEX的情况下创建PRIMARY KEY会导致HEAP-organized表格需要额外的RID lookup才能访问这些值:也不是很好。

答案 2 :(得分:1)

你有多少钥匙和套装?这些需要是varchar(50)还是指向查找表?如果您可以将此Set和Key转换为SetId和KeyId,那么您可以在3个整数值上创建主键,这将更快。

答案 3 :(得分:0)

我可能会尝试确保UserID是唯一标识符,而不是在整个代码中都有UserID的副本。复合键往往会在代码的生命周期中变得混乱。

我假设这是某种配置值的查找字段,因此如果是这种情况,您可能会使用复合键。数据已经存在。您可以使用主键保证它的唯一性。如果您改变主意并稍后决定它不适合您,您可以轻松添加SettingId并使原始复合键成为唯一索引。

答案 4 :(得分:0)

创建一个单独的主键。无论bussines逻辑如何改变,都必须将新规则应用于Key VARCHAR(50)字段 - 拥有一个主键将使您完全独立于bussines逻辑。

答案 5 :(得分:0)

根据我的经验,这一切都取决于有多少表将此表用作FK信息。你想在你的其他表中增加3个额外的列来进行FK吗?

就个人而言,我会创建另一个FK列,并在其他三列上放置一个唯一约束。这使得此表的外键更容易吞下。

答案 6 :(得分:0)

最好将UserID作为32位newid()或唯一标识符,因为UserID as int会向用户提供可能UserID的提示。这也将解决您的复合键问题。

答案 7 :(得分:0)

我不是复合键的支持者,但在这种情况下作为行表的一端,它可能有意义。但是,如果在这三个字段中的任何一个字段中允许空值,因为在插入时未知一个或多个值,则可能存在困难,并且唯一索引可能更好。