12

我正在考虑更改一些表以使用 nvarchar(50) 作为主键而不是 int 主键。对键使用 int ID 确实是不相关的数据,它是我感兴趣的字符串。会发生什么样的性能损失,或者你在哪里研究这个?除了削减和尝试是。

4

5 回答 5

26

您遇到了数据库设计的主要“圣战”之一。您所指的辩论是“代理与自然键”的争论,只要有 RDBMS(据我所知),它就一直在肆虐。

争论本质上归结为是否应该使用代表性键(代理,例如 IDENTITY 列)与使用唯一描述记录的实际数据(自然键)。

我会说没有“正确”的答案。性能度量是平台的产物,应该通过实验来评估,但性能不太可能是主要关注点。

我认为代理键的主要论点是主键的不变性。如果您选择使用自然密钥,您将放弃在该密钥建立后更改该密钥的选项。你也放弃了它在未来某个时候可能变得非唯一的可能性。由于这些原因,我通常(并非总是)对我的大多数表使用代理键。

然而,正如我所提到的,如果你愿意的话,有一个长期存在的争论,充满了关于索引策略和范式遵守的讨论。

我会谷歌“代理与自然键”。以下是一些帮助您入门的链接:

系统工程和 RDBMS

技术共和国

托尼·罗杰森的博客

希望这可以帮助。

于 2008-10-22T05:54:42.100 回答
5

考虑使用代理键(int 主键)作为主键/聚集索引键。使用 nvarchar(50) 作为主键/聚集索引键的问题在于,您的表将按该键排序,这意味着它可能会变得高度碎片化,并且任何其他索引都会有引用这个沉重的负担首要的关键。

另一个问题是,您可能需要通过这种类型的值在其他表上 JOIN,随着键大小的增长,这是一个更昂贵的操作。

我认为很少有 nvarchar(50) 主键有意义的情况。

通常,主键应该是代理项,除非您有一个小的自然不可变键。可以说,例如,SSN 可以被视为天然的不可变密钥。

于 2008-10-22T05:48:11.050 回答
1

对于性能,我通常会问以下问题:

  • 多少行?1,000 或 1,000,000 或 1,0000,000 ??

  • 它坐在什么服务器上?(内存,磁盘空间)

我会分析它然后看看。通常对我来说,瓶颈不是数据库,而是写得不好的代码,糟糕的部署等等……

于 2008-10-22T05:49:47.007 回答
0

为了彻底消除自然键解决方案(cf surrogate vs natural key war)的领导者提出的所有论点,并简而言之,我应该说代理键总是有效,而自然键有一个松散的倾向遇到问题和沮丧,通常是在意想不到的时候。

我并不是说它们是每种情况的最佳解决方案,但是为了避免在创建表时浪费您(和其他人)的时间来考虑最佳自然键的适当参数,只需选择代理,就可以了。如果您的表似乎有一个适当的自然键,只需将其添加为具有(唯一?)索引的字段。

为了方便开发人员,始终将您的第一个字段作为主键,第二个字段是假定/伪自然键。你的表应该是这样的:

Tbl_whatever
     id_whatever, unique identifier, primary key
     code_whatever, nvarchar(your favorite length), indexed
     .....

其中 id_ 是主键的前缀,而 code_ 用于“自然”索引字段

于 2008-10-22T11:41:21.633 回答
-2

为什么选择 UNICODE?例如,如果我将一个英文单词翻译成中文汉字,它们会被认为是重复的吗?

为什么是可变的?固定宽度是键的良好物理特性。

为什么是 50 个字符?这对用户来说是很多键控(我同意“密钥的 int ID 确实是不相关的数据”,并认为这种所谓的“代理键”永远不应该暴露给最终用户,顺便说一句)。

另外,对我NVARCHAR(50)来说有点“味道”:微软的默认设置,也许是 MS Access 的直接端口?这并不意味着您没有对您的密钥给予应有的考虑和考虑,当然,这只是其中一项可能需要审查的事情。

哦,等等:你的意思是专门的 PRIMARY KEY,对吧?假设您明确使用一个(每个表)聚集索引,AFAIK PRIMARY KEY 指定在 SQL Server 领域没有物理意义。当然,你所有的候选键都应该被 NOT NULL UNIQUE 约束所覆盖;您选择提升为 PRIMARY 键的那个是任意的。

于 2008-10-22T10:42:20.490 回答