Sql server 使用;“瓦查尔”;作为主键?坏主意?还是好?

Sql server 使用;“瓦查尔”;作为主键?坏主意?还是好?,sql-server,database,sql-server-2008,database-design,Sql Server,Database,Sql Server 2008,Database Design,使用“varchar”作为主键真的那么糟糕吗 (将存储用户文档,是的,它可以超过20多亿个文档)使用ID(如果您只想显示50个等等,这将非常方便)。然后使用文件名在varchar上设置一个唯一的约束(我假设,这就是您要存储的) 这将起作用并提高速度。这完全取决于数据。在很多完全合法的情况下,您可能会使用VARCHAR主键,但如果将来某个时候有人可能想更新相关列,请不要将其用作键。我认为int或bigint通常更好 int可以与较少的CPU指令(连接查询…)相比较 默认情况下,int序列是按顺序排

使用“varchar”作为主键真的那么糟糕吗

(将存储用户文档,是的,它可以超过20多亿个文档)

使用ID(如果您只想显示50个等等,这将非常方便)。然后使用文件名在varchar上设置一个唯一的约束(我假设,这就是您要存储的)


这将起作用并提高速度。

这完全取决于数据。在很多完全合法的情况下,您可能会使用
VARCHAR
主键,但如果将来某个时候有人可能想更新相关列,请不要将其用作键。

我认为int或bigint通常更好

  • int可以与较少的CPU指令(连接查询…)相比较
  • 默认情况下,int序列是按顺序排列的->平衡索引树->如果使用PK作为聚集索引,则不进行重组
  • 索引可能需要更少的空间

  • 如果要连接到其他表,则varchar,尤其是宽varchar,可能比int慢

    此外,如果您有许多子记录,并且varchar可能会更改,那么级联更新可能会导致所有用户的阻塞和延迟。一个像汽车VIN一样的varchar号码,如果有任何变化,它几乎不会改变。一个像varchar这样的名字会改变,这可能是一场等待发生的噩梦。如果可能的话,PKs应该是稳定的

    接下来,许多可能的varchar PK不是真正唯一的,有时它们看起来是唯一的(如电话号码),但可以重复使用(您放弃号码,电话公司重新分配),然后子记录可能会附加到错误的位置。因此,在使用之前,请确保您确实具有唯一的不变值

    如果决定使用代理键,则为varchar字段创建唯一索引。这将使您获得更快的连接和更少的记录更新的好处,如果某些内容发生更改,但保持您想要的唯一性


    现在,如果您没有子表,而且可能永远也不会有子表,那么这大部分都是没有意义的,添加整数pk只是浪费时间和空间

    我意识到我在这里参加聚会有点晚了,但我想详细说明一下以前的答案会有所帮助

    使用VARCHAR()作为主键并不总是坏事,但几乎总是这样。到目前为止,我还没有遇到过一个不能提供更好的固定大小主键字段的时候

    VARCHAR比整数(INT)或短的固定长度字符(char)字段需要更多的处理

    除了为每个记录存储额外的字节(指示存储在此字段中的数据的“实际”长度),数据库引擎还必须在每次读取之前进行额外的工作,以计算字段的起始字节和结束字节的位置(在内存中)

    外键还必须使用与被引用父表的主键相同的数据类型,以便在连接表以进行输出时处理进一步的复合

    对于少量数据,这种额外的处理不太可能明显,但随着数据库的增长,您将开始看到性能下降


    您说过要使用GUID作为键,这样您就可以提前知道列的长度是固定的。这是一个使用固定长度字符(36)字段的好时机,它产生的处理开销要少得多。

    什么长度
    varchar
    ?你能给出几个建议键的例子吗?用户将如何选择要检索的文档?varchar的长度是36(guid)。作为varchar的Guid被用作主键;我将仔细考虑<代码> VARCHAR < /C>是使用的正确类型-如果涉及多个文化,也许<代码> NVARCHAR 会更合适。但是,通过将键中使用的字符数增加一倍,这会产生连锁反应。请解释添加
    id
    如何方便地仅显示50个字符。这些不保证是连续的,回滚和删除会留下间隙。此外,通过在列上设置唯一约束,这将使其成为候选键,在这种情况下,选择哪一个作为主键是任意的。如果您有多个由任何类型的唯一索引强制执行的候选键,则其中任何一个都可以参与外键关系。当您要显示这些文件名时,您确实不希望选择20亿条记录,并且限制在50条以上。使用id,您可以选择id>您保存的某些位置的所有文件。这将通过以下方式提高执行速度。。。好。。。更多:-)。您也可以使用
    varchar
    来实现这一点。它仍然会在索引中查找正确的位置,然后从该点检索
    Top50
    行。我认为关键是,使用数字标识符获取范围要容易得多<代码>选择。。。其中Id>58和Id<98,沿着这些线。这还取决于
    varchar
    索引的创建方式(随机或多个顺序算法)。@Mark-主键应该是稳定的。如果更新它们,更改可能需要传播到其他表,并将它们用作FK,默认情况下,它们也会成为SQL Server中的群集键,因此也需要复制以充当非群集索引中的行定位器,这也需要更新。因此,这适用于任何类型,而不仅仅是varchar@Mark-是的,我想它确实适用于所有数据类型,正如我前面提到的,它完全取决于数据和意图。我见过一些情况,其中一个表上的PK也用于许多其他相关表中,但没有通过FK约束强制执行。这使得PK的更新非常糟糕。是的,不使用FK约束确实会使数据库unreliable@ninesided:押注于用户、开发人员和DBA手动强制执行外键约束(通过在插入、更新和删除时非常小心)是一种风险