身份列如何复制?

Oni*_*ght 2 replication sql-server ssms identity

在事务复制期间,我们将数据从服务器 A 传输到服务器 B。

假设我们要在服务器 A 上的表上重新植入身份列(无论出于何种原因),这将如何影响服务器 B 上的数据?

我的直觉是,服务器 A 上的数据将使用新播种的身份,并将按原样发送到服务器 B(服务器 B 将具有使用新身份的内容),但我不确定这是否是正确的。

Kin*_*hah 5

当您有身份列并且该列是表的主键时,这总是很棘手。

\n

根据我处理 T-Rep 和 Merge 的经验,我建议使用NOT FOR REPLICATIONNO。默认情况下它设置为 YES。您可以使用 .sql 在 sql 2005 及更高版本上动态执行此操作(不影响复制)sys.sp_identitycolumnforreplication

\n

如果您没有更新订户端的数据,应该没问题。

\n

回答你的问题:

\n
\n

假设我们要在服务器 A 上的表上重新植入身份列(无论出于何种原因),这将如何影响服务器 B 上的数据?

\n
\n

考虑到您没有更新订阅者上的数据,当您想要重新设定种子时,您应该始终从标识列中获取最大值,然后相应地重新设定该值。

\n

您可以使用下面的 sql 来查找:

\n
SELECT  QUOTENAME(SCHEMA_NAME(t.schema_id)) + \'.\' +  QUOTENAME(t.name) AS TableName, \n        c.name AS ColumnName,\n        IDENT_CURRENT(SCHEMA_NAME(t.schema_id)  + \'.\' + t.name) AS CurrentIdentityValue,\n        IDENT_INCR (SCHEMA_NAME(t.schema_id) + \'.\' + t.name) as Identity_increment\n    FROM    sys.columns AS c \n        INNER JOIN  sys.tables AS t ON t.[object_id] = c.[object_id]\n        WHERE   c.is_identity = 1 \n  -- write here the table name if you want to filter for specific table\n    and t.name like \'%TABLE_NAME%\'\n
Run Code Online (Sandbox Code Playgroud)\n

例如考虑下面的客户表:

\n
TableName     ColumnName    CurrentIdentityValue    Identity_increment\n[dbo].[customer]    id         7                    1\n
Run Code Online (Sandbox Code Playgroud)\n

现在,如果您想以某种方式重新播种身份值,您可以运行

\n
dbcc checkident (\'customer\',reseed,8 ) \n
Run Code Online (Sandbox Code Playgroud)\n

这意味着它将把当前的 Identity 值设置为 8,因此下次将任何行插入到表中时,它的当前 Identity 值将是 8 (CurrentIdentityValue) + 1(Identity_increment) = 9。

\n

这样做必须小心,因为这可能会导致身份差距。

\n

您可以做的其他事情是:

\n
    \n
  • 分区
  • \n
  • sp_addaritcle使用以下参数的手动身份范围管理解决方案@identity_range ,@pub_identity_range and @threshold
  • \n
\n

阅读:

\n
    \n
  1. 复制中的身份危机——希拉里·科特 (Hilary Cotter)
  2. \n
  3. 关于 \xe2\x80\x9cIdentity Range Management\xe2\x80\x9d 的所有信息 - 作者:Chris Skorlinski
  4. \n
\n