使用"varchar"作为主键?馊主意?还好吗?

001*_*001 14 database sql-server database-design sql-server-2008

使用"varchar"作为主键真的那么糟糕吗?

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

nin*_*ded 17

这完全取决于数据.有许多完全合法的情况,您可能会使用VARCHAR主键,但如果有人可能希望在将来的某个时刻更新相关列的最远的机会,请不要将其用作密钥.

  • @ninesided:投注用户,开发人员和DBA手动强制执行外键约束 - 通过精心插入,更新和删除 - 几乎是*不可靠的定义*. (6认同)
  • @Mark - 主键应该是稳定的.如果更新它们,则更改可能需要使用它们作为FK传播到其他表,默认情况下它们也会成为SQL Server中的集群键,因此复制它们也可以充当非集群索引中的行定位器,这也需要得到更新. (4认同)
  • @Mark - 是的,我想它确实适用于所有数据类型,正如我之前提到的,它完全取决于数据和意图.我见过一个表上的PK也用在许多其他相关表中的情况,但没有通过FK约束强制执行.这使PK的更新真的很讨厌. (3认同)
  • 所以这适用于任何类型,而不仅仅是varchar (2认同)

HLG*_*GEM 7

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

此外,如果您有许多子记录且varchar可能会发生变化,则级联更新可能会导致所有用户出现阻塞和延迟.像汽车VIN号码这样的varchar很少有变化,很好.像名字一样的varchar会发生变化,这可能是一场等待发生的噩梦.如果可能的话,PK应该是稳定的.

接下来许多可能的varchar Pks并不是唯一的,有时候它们看起来很独特(比如电话号码),但可以重复使用(你放弃号码,电话公司重新分配它),然后子记录可以附加到错误的地方.因此,在使用之前,请确保您确实拥有独特的不变价值.

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

现在,如果你没有子表,并且可能永远不会,那么大部分都没有实际意义并且添加整数pk只是浪费时间和空间.