SQL主键 - 具有串联的复杂主键或字符串?

时间:2009-10-18 01:33:00

标签: sql sql-server sql-server-2008 optimization web-applications

我有一个包含16列的表格。它将是Web应用程序中最常用的表,它将包含大约几十万行。数据库是在sql server 2008上创建的。

我的问题是选择主键。什么更快?我可以使用两个bigint-s的复杂主键,或者我可以使用一个varchar值,但我需要在之后连接它?

8 个答案:

答案 0 :(得分:5)

还有许多因素需要考虑:

  • 数据访问流行模式,您打算如何访问该表?
  • 有多少非聚集索引?
  • 更新频率
  • 更新模式(顺序插入,随机)
  • 删除模式

所有这些因素,特别是前两个因素,应该推动您选择群集密钥。请注意,主键和聚簇键是不同的概念,经常混淆。阅读我在Should I design a table with a primary key of varchar or int?上的答案,以便对推动群集密钥选择的标准进行更长时间的讨论。

如果没有关于您的访问模式的任何信息,我可以非常简短地回答,并且实际上是正确的:较窄的密钥总是更快(出于IO的原因)。但是,这种反应绝对没有价值。使您的应用程序更快的唯一方法是选择查询执行计划将要使用的密钥。

答案 1 :(得分:2)

不依赖任何基础值(称为surrogate key)的主键是一个不错的选择。这样,如果行更改,则ID不必,并且引用它的任何表(Foriegn Keys)将不需要更改。我会为主键列选择一个自动编号(即IDENTITY)列。

就性能而言,最好使用基于整数的较短主键。

您仍然可以在多个列上创建聚簇索引。

答案 2 :(得分:1)

为什么不只是一个INT自动生成的主键? INT是32位,因此它可以处理超过40亿条记录。

CREATE TABLE Records (
   recordId INT NOT NULL PRIMARY KEY,
   ...
);

答案 3 :(得分:1)

如果此表上存在外键关系,则代理键可能是个好主意。使用代理将保存引用它的表,不必复制其表中的所有列。

另一个重要的考虑因素是您将在WHERE子句中使用的列的索引。如果你不这样做,你的表现会受到影响。确保在主键之上添加适当的索引,以避免表扫描。

答案 4 :(得分:0)

该决定依赖于其使用。如果您使用该表来保存数据而不是检索它,那么就是一个简单的密钥。如果您主要查询数据并且主要是静态数据,其中键值不会更改,则索引策略需要将数据优化为将使用的最常见查询。就个人而言,我喜欢使用GUID作为主键,使用int作为聚簇索引。这样可以轻松导入数据。但是,这实际上取决于您的需求。

答案 5 :(得分:0)

你的意思更快?如果需要更快地搜索,可以为任何列创建索引或创建全文搜索。主键只是确保您没有重复的记录。

答案 6 :(得分:0)

你没有提到的很多变量;两列中的数据是否“自然”并且通过逻辑ID识别记录有好处,如果通过UI公开密钥会带来风险,性能有多重要(几十万行非常小)

如果您不是太挑剔,请转到自动编号路径以获得速度和简单性。另请查看网站上有关SQL primary key types的所有帖子。这里有很多信息。

答案 7 :(得分:0)

是ER模型还是维度模型。在ER模型中,它们应该是分开的,不应该被代理。整个记录可以有一个代理,用于在URL等中轻松引用。这可以是复合密钥的所有部分或标识的散列。

在维度模型中,它们也必须是分开的,它们都应该被代理。