SQL Server 2005 会因为我使用 nvarchar(50) 而不是整数作为主键而惩罚我吗?

Posted

技术标签:

【中文标题】SQL Server 2005 会因为我使用 nvarchar(50) 而不是整数作为主键而惩罚我吗?【英文标题】:Will SQL Server 2005 penalize me for using an nvarchar(50) as a primary key, instead of an integer? 【发布时间】:2008-10-22 05:40:23 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

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

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

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

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

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

Systems Engineering and RDBMS

Techrepublic

Tony Rogerson's blog

希望这会有所帮助。

【讨论】:

【参考方案2】:

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

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

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

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

【讨论】:

Kim Tripp 在最近的“Run As Radio”话题中谈到了这个话题。 runasradio.com/default.aspx?showNum=76【参考方案3】:

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

有多少行? 1000 或 1,000,000 或 10,000,000 ??

它位于什么服务器上? (内存、磁盘空间)

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

【讨论】:

【参考方案4】:

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

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

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

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

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

【讨论】:

【参考方案5】:

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

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

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

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

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

【讨论】:

以上是关于SQL Server 2005 会因为我使用 nvarchar(50) 而不是整数作为主键而惩罚我吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的SQL SERVER2005在连接ODBC时会出现连接超时过期呢

将使用 SQL Server Express 2008 创建的 mdf 导入 SQL Server 2005 时出现问题

SQL Server 2005 全文搜索:干扰词

Linux 上的 SQL Server 2005 扩展

SQL Server 2005 缓存

在 SQL Server 2005 中恢复 SQL Server 2014 数据库