【问题标题】:Managing identity/primary key across servers跨服务器管理身份/主键
【发布时间】:2011-11-12 23:08:55
【问题描述】:

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

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

  1. 为我的主键使用 GUID

    这将确保在任意数量的服务器上始终存在唯一的密钥。我不喜欢这个,GUID 的大小是 16 字节,当用于跨多个表的外键时,它会浪费空间。而且写查询的时候用起来比较麻烦,查询起来也比较慢。

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

管理多台服务器的最佳做法是什么?在这种情况下,最好的方法是什么?

【问题讨论】:

  • 但是即使两个 int 字段仍然只有 8 字节(而不是 GUID 的 16 个字节)....另外:两个 int 比 GUID 更好的集群键 - @987654321 @
  • 另一种选择是使用复合键,一列用于服务器,另一列用于服务器特定的 int。 (一个 GUID 是 16 个字节;没有一个字节被浪费。你也许可以想出一个更小的键,但这并不意味着 GUID 是浪费的。它只是比每个更窄的键宽一点。浪费在这里只是一个不好的词,因为它限制了你的思维。)

标签: sql-server primary-key identity


【解决方案1】:

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

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

这里有一个关于各种选项的非常好的简短阅读:

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

至于复制部分 - 如果处理得当,复制就不会真正令人头疼。

【讨论】:

    【解决方案2】:

    我敢于建议不要完全复制 :) 这肯定比有趣更痛苦。如果您负担得起,请查看Sync framework

    至少可以说,玩弄身份并不灵活。考虑添加移动服务器。身份插入、不同的架构等等。

    如果您使用 newsequentialid() 作为默认值,则 GUID 可以用于集群键。它有点大(一些位),但它一劳永逸地解决了麻烦:)

    我要采用的方法是拥有一个仅与数据库上下文相关的 int 身份集群键。然后添加一个 GUID 列,这对同步上下文有意义。用 rowversion 列填充它,以查看准备好同步的内容。

    【讨论】:

      【解决方案3】:

      更新:

      找到了更简单/手动的方法here。涉及使用 NOT FOR REPLICATION 和您在 cmets 中提到的惊人的身份种子值。

      原文:

      您最好的选择类似于列出的第二个选项。为复制发布者和订阅者实例分配身份范围,然后开启自动范围管理。

      This article 讨论了在复制中管理身份列的选项,enabling identity range management 在这里讨论。

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

      【讨论】:

      • 据我了解,它通过为每个服务器指定一些范围来工作,例如 1-10000、10001-20000、20001-30000,...我不认为身份范围是最好的方法来做到这一点。也许对于我的系统,我可以假设最多有 10 台服务器,然后从那里开始。那么我的增量将在每台服务器上增加 10,并且起始值将在 1-10 的范围内。
      • 我不明白你建议在每台服务器上增加 10,范围从 1-10。您能否详细说明为什么标识范围选项不适合您的环境?
      • 比如说只有两台服务器。在第一台服务器上我们创建空数据库,在第二台服务器上我们创建空数据库。现在在第一个数据库上,我们将每个表的每个身份键设置为从数字 1 开始。在第二个数据库上,我们将其设置为从数字 2 开始。在每个数据库上,身份将增加 2。所以在 db1 上将有 (1 ,3,5,7,9,... 到 max bigint),并且在 db2 上它们会去 (2,4,6,8,... 到 max bigint)。
      • 这种方法的好处是我们只需要在创建数据库时执行一次。不好的是我们不知道未来是否会有 3,4 甚至 10 台服务器。这就是为什么我很难过我可以假设会有 10 台服务器,所以如果需要,我们可以有一些空间来添加它们。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-17
      • 1970-01-01
      • 1970-01-01
      • 2014-05-25
      • 1970-01-01
      • 2019-09-15
      • 1970-01-01
      相关资源
      最近更新 更多