跨服务器管理身份/主键

时间:2011-09-08 12:30:36

标签: sql-server primary-key identity

我正在设计一个需要支持复制的新数据库,而我却决定选择什么作为我的主键。

在我们当前的主键数据库中,我们使用两个int列,第一列是identity,另一列用于描述插入行的服务器。现在我想避免为主键使用两列,而只是使用一列。到目前为止,我有两种方法:

  1. 将GUID用于我的主键

    这将确保在任意数量的服务器上始终存在唯一密钥。我不喜欢这个,是GUID是16字节大小,当用于跨越许多表的外键时,它将浪费空间。在编写查询时也很难使用它,查询速度会慢一些。

  2. 使用int或bigint,并为每台服务器上的每个表手动指定种子和增量值。例如,如果有两台服务器,第一台服务器上的X表将从1号开始,第二台服务器上的X表将从2号开始,每台将增加2.因此会有(1,3,5,...) ..)首先,和(2,4,6,...)在第二台服务器上。这种设计的好处在于它在编写查询时更容易使用,速度快,而且外键使用的空间更少。不好的是,我们永远不知道将运行多少台服务器,因此很难说出增量值是多少。此外,在服务器上管理架构更改也更加困难。

  3. 管理多台服务器的最佳做法是什么,如果出现这种情况,最好的方法是什么?

3 个答案:

答案 0 :(得分:2)

你的问题很好,经常被问到。

从维护的角度来看,我绝对会选择GUIDS。他们是有原因的。 在某些地方,您可能会遇到复杂的操作,移动并重新复制您的数据,然后其他选项可能会使它变得比它需要的更复杂。

这里有关于各种选项的简短阅读:

http://msdn.microsoft.com/en-us/library/bb726011.aspx

至于复制部分 - 如果正确完成,复制没有真正的麻烦。

答案 1 :(得分:0)

<强>更新

找到一种更简单/手动的方法here。如您在评论中提到的那样,涉及使用NOT FOR REPLICATION和错开的身份种子值。

<强>原始

您最好的选择就像列出的第二个选项。为复制发布者和订阅者实例分配标识范围,然后启用自动范围管理。

This article讨论了在复制中管理标识列的选项,此处讨论了enabling identity range management

由于您不知道复制池中将有多少台服务器,因此您可能需要定期重新配置文章属性。

答案 2 :(得分:0)

我敢于完全反对复制:)这当然更有痛苦而不是乐趣。如果您负担得起,请查看Sync framework

至少可以说,玩身份是不灵活的。考虑添加移动服务器。标识插入,不同的模式等。

如果您使用newsequentialid()作为默认值,

GUID对于聚簇键是正常的。它有点大(多位),但它解决了一次又一次的麻烦:)

我的方法是拥有一个int identity clustered key,它只与数据库上下文相关。然后添加一个GUID列,这对同步上下文有意义。最好使用rowversion列来查看准备好同步的内容。