我正在设计一个需要支持复制的新数据库,而我却决定选择什么作为我的主键。
在我们当前的主键数据库中,我们使用两个int列,第一列是identity,另一列用于描述插入行的服务器。现在我想避免为主键使用两列,而只是使用一列。到目前为止,我有两种方法:
将GUID用于我的主键
这将确保在任意数量的服务器上始终存在唯一密钥。我不喜欢这个,是GUID是16字节大小,当用于跨越许多表的外键时,它将浪费空间。在编写查询时也很难使用它,查询速度会慢一些。
使用int或bigint,并为每台服务器上的每个表手动指定种子和增量值。例如,如果有两台服务器,第一台服务器上的X表将从1号开始,第二台服务器上的X表将从2号开始,每台将增加2.因此会有(1,3,5,...) ..)首先,和(2,4,6,...)在第二台服务器上。这种设计的好处在于它在编写查询时更容易使用,速度快,而且外键使用的空间更少。不好的是,我们永远不知道将运行多少台服务器,因此很难说出增量值是多少。此外,在服务器上管理架构更改也更加困难。
管理多台服务器的最佳做法是什么,如果出现这种情况,最好的方法是什么?
答案 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列来查看准备好同步的内容。