Replica di colonne IdentityReplicate Identity Columns

In MicrosoftMicrosoft SQL ServerSQL Server quando si assegna la proprietà IDENTITY a una colonna, vengono automaticamente generati numeri sequenziali per le nuove righe inserite nella tabella contenente la colonna Identity.When you assign an IDENTITY property to a column, MicrosoftMicrosoft SQL ServerSQL Server automatically generates sequential numbers for new rows inserted in the table containing the identity column. Per altre informazioni, vedere IDENTITY (proprietà) (Transact-SQL).For more information, see IDENTITY (Property) (Transact-SQL). Dato che è possibile includere le colonne Identity come parte della chiave primaria, è importante evitare di inserire valori duplicati nelle colonne Identity.Because identity columns might be included as a part of the primary key, it is important to avoid duplicate values in the identity columns. Per utilizzare colonne Identity in una topologia di replica con aggiornamenti in più di un nodo, è necessario che ogni nodo presente nella topologia di replica utilizzi un intervallo di valori Identity diverso, in modo da non generare duplicati.To use identity columns in a replication topology that has updates at more than one node, each node in the replication topology must use a different range of identity values, so that duplicates do not occur.

Ad esempio, al server di pubblicazione potrebbe essere assegnato l'intervallo 1-100, al Sottoscrittore A l'intervallo 101-200 e al Sottoscrittore B l'intervallo 201-300.For example, the Publisher could be assigned the range 1-100, Subscriber A the range 101-200, and Subscriber B the range 201-300. Se una riga viene inserita nel server di pubblicazione e il valore Identity è, ad esempio, 65, tale valore viene replicato in ogni Sottoscrittore.If a row is inserted at the Publisher and the identity value is, for example, 65, that value is replicated to each Subscriber. Durante l'inserimento dei dati nei Sottoscrittori, il valore della colonna Identity nella tabella dei Sottoscrittori non viene incrementato, bensì viene inserito il valore letterale di 65.When replication inserts data at each Subscriber, it does not increment the identity column value in the Subscriber table; instead, the literal value 65 is inserted. Il valore della colonna Identity viene incrementato solo in seguito a inserimenti da parte dell'utente e non a inserimenti generati dall'agente di replica.Only user inserts, but not replication agent inserts cause the identity column value to be incremented.

La replica consente di gestire le colonne Identity di tutti i tipi di pubblicazione e sottoscrizione. È pertanto possibile scegliere di gestire manualmente le colonne oppure di gestirle automaticamente tramite la replica.Replication handles identity columns across all publication and subscription types, allowing you to manage the columns manually or have replication manage them automatically.

Nota

Non è consentito aggiungere una colonna Identity a una tabella pubblicata, perché ciò può impedire la convergenza dei dati durante la replica della colonna nel Sottoscrittore.Adding an identity column to a published table is not supported, because it can result in non-convergence when the column is replicated to the Subscriber. I valori della colonna Identity nel server di pubblicazione dipendono dall'ordine in cui vengono fisicamente archiviate le righe della tabella interessata.The values in the identity column at the Publisher depend on the order in which the rows for the affected table are physically stored. Nel caso in cui le righe siano state archiviate in modo diverso nel Sottoscrittore, il valore della colonna Identity può essere diverso per le stesse righe.The rows might be stored differently at the Subscriber; therefore the value for the identity column can be different for the same rows.

Specifica delle opzioni di gestione degli intervalli di valori IdentitySpecifying an Identity Range Management Option

Nella replica sono disponibili tre opzioni di gestione degli intervalli di valori Identity:Replication offers three identity range management options:

  • Automatico.Automatic. Questa opzione viene utilizzata per la replica transazionale e di merge con aggiornamenti nel Sottoscrittore.Used for merge replication and transactional replication with updates at the Subscriber. Specificare gli intervalli per il server di pubblicazione e i Sottoscrittori. L'assegnazione dei nuovi intervalli viene gestita automaticamente.Specify size ranges for the Publisher and Subscribers, and replication automatically manages the assignment of new ranges. Nella colonna Identity nel Sottoscrittore viene impostata l'opzione NOT FOR REPLICATION, in modo che il valore della colonna nel Sottoscrittore venga incrementato solo nel caso di inserimenti da parte dell'utente.Replication sets the NOT FOR REPLICATION option on the identity column at the Subscriber, so that only user inserts cause the value to be incremented at the Subscriber.

    Nota

    È necessario sincronizzare i Sottoscrittori con il server di pubblicazione per ricevere i nuovi intervalli.Subscribers must synchronize with the Publisher to receive new ranges. Dato che gli intervalli di valori Identity vengono assegnati automaticamente ai Sottoscrittori, è possibile che un Sottoscrittore esaurisca gli intervalli disponibili se ne richiede ripetutamente di nuovi.Because Subscribers are assigned identity ranges automatically, it is possible for any Subscriber to exhaust the entire supply of identity ranges if it repeatedly requests new ranges.

  • Manuale.Manual. Questa opzione viene utilizzata per la replica snapshot e transazionale con aggiornamenti nel Sottoscrittore, per la replica transazionale peer-to-peer oppure se l'applicazione richiede il controllo degli intervalli di valori Identity a livello di programmazione.Used for snapshot and transactional replication without updates at the Subscriber, peer-to-peer transactional replication, or if your application must control identity ranges programmatically. Se si sceglie la gestione manuale, è necessario verificare che gli intervalli vengano assegnati al server di pubblicazione e a tutti i Sottoscrittori e che vengano assegnati nuovi intervalli se quelli iniziali sono già in uso.If you specify manual management, you must ensure that ranges are assigned to the Publisher and each Subscriber and that new ranges are assigned if the initial ranges are used. Nella replica l'opzione NOT FOR REPLICATION viene impostata nella colonna Identity del Sottoscrittore.Replication sets the NOT FOR REPLICATION option on the identity column at the Subscriber.

  • NessunoNone. Questa opzione è consigliata solo per la compatibilità con le versioni precedenti di SQL ServerSQL Server ed è disponibile solo dall'interfaccia delle stored procedure delle pubblicazioni transazionali.This option is recommended only for backwards compatibility with earlier versions of SQL ServerSQL Server and is available only from the stored procedure interface for transactional publications.

    Per specificare un'opzione di gestione degli intervalli di valori Identity, vedere Gestire le colonne Identity.To specify an identity range management option, see Manage Identity Columns.

Assegnazione degli intervalli di valori IdentityAssigning Identity Ranges

In questa sezione vengono descritti i diversi metodi di assegnazione degli intervalli utilizzati per la replica di tipo merge e per la replica transazionale.Merge replication and transactional replication use different methods for assigning ranges; these methods are described in this section.

Nella replica di colonne Identity è opportuno considerare due tipi di intervalli, ovvero gli intervalli assegnati al server di pubblicazione e ai Sottoscrittori e l'intervallo del tipo di dati della colonna.There are two types of ranges to take into account when replicating identity columns: the ranges assigned to the Publisher and Subscribers, and the range of the data type in the column. Nella tabella seguente vengono illustrati gli intervalli disponibili per i tipi di dati utilizzati in genere nelle colonne Identity.The following table shows the ranges available for the data types typically used in identity columns. L'intervallo è applicato a tutti i nodi presenti in una topologia.The range is used across all nodes in a topology. Ad esempio, se si utilizza smallint con un valore iniziale di 1 e con un incremento di 1, il numero massimo di inserimenti possibili è 32.767 per il server di pubblicazione e tutti i Sottoscrittori.For example, if you use smallint starting at 1 with an increment of 1, the maximum number of inserts is 32,767 for the Publisher and all Subscribers. Il numero effettivo di inserimenti dipende dal fatto che vi siano o meno gap nei valori utilizzati e che venga utilizzato o meno un valore soglia.The actual number of inserts depends on whether there are gaps in the values used and whether a threshold value is used. Per ulteriori informazioni sulle soglie, vedere le sezioni seguenti relative alla replica di merge e alla replica transazionale con sottoscrizioni ad aggiornamento in coda.For more information about thresholds, see the following sections "Merge Replication" and "Transactional Replication with Queued Updating Subscriptions".

Se dopo un inserimento il server di pubblicazione esaurisce il proprio intervallo di valori Identity, è possibile assegnare automaticamente un nuovo intervallo a condizione che l'inserimento sia stato eseguito da un membro del ruolo predefinito del database db_owner .If the Publisher exhausts its identity range after an insert, it can automatically assign a new range if the insert was performed by a member of the db_owner fixed database role. Se l'inserimento è stato eseguito da un utente che non dispone di quel ruolo, è necessario che l'agente di lettura log, l'agente di merge o l'utente che è membro del ruolo db_owner esegua la stored procedure sp_adjustpublisheridentityrange (Transact-SQL).If the insert was performed by a user not in that role, the Log Reader Agent, Merge Agent, or a user who is a member of the db_owner role must run sp_adjustpublisheridentityrange (Transact-SQL). Nel caso di pubblicazioni transazionali, l'agente di lettura log deve essere in esecuzione per allocare automaticamente un nuovo intervallo di valori (per impostazione predefinita l'agente viene eseguito continuamente).For transactional publications, the Log Reader Agent must be running to automatically allocate a new range (the default is for the agent to run continuously).

Avviso

Durante l'inserimento di un batch di grandi dimensioni, il trigger di replica viene generato solo una volta, non per ogni riga inserita.During a large batch insert the replication trigger is fired only once, not for each row of the insert. Questa condizione può comportare un errore dell'istruzione di inserimento se un intervallo di valori Identity viene esaurito durante un inserimento di grandi dimensioni, ad esempio un'istruzione INSERT INTO .This can lead to a failure of the insert statement if an identity range is exhausted during an large insert, such as an INSERT INTO statement.

Tipo di datiData type IntervalloRange
tinyinttinyint Non supportato per la gestione automaticaNot supported for automatic management
smallintsmallint da -2^15 (-32.768) a 2^15-1 (32.767)-2^15 (-32,768) to 2^15-1 (32,767)
intint da -2^31 (-2.147.483.648) a 2^31-1 (2.147.483.647)-2^31 (-2,147,483,648) to 2^31-1 (2,147,483,647)
bigintbigint da -2^63 (-9.223.372.036.854.775.808) a 2^63-1 (9.223.372.036.854.775.807)-2^63 (-9,223,372,036,854,775,808) to 2^63-1 (9,223,372,036,854,775,807)
decimal e numericdecimal and numeric da -10^38+1 a 10^38-1-10^38+1 through 10^38-1

Nota

Per creare un numero a incremento automatico da usare in più tabelle o da chiamare dalle applicazioni senza fare riferimento ad alcuna tabella, vedere Numeri di sequenza.To create an automatically incrementing number that can be used in multiple tables or that can be called from applications without referencing any table, see Sequence Numbers.

Replica di tipo mergeMerge Replication

Gli intervalli di valori Identity vengono gestiti dal server di pubblicazione e distribuiti ai Sottoscrittori dall'agente di merge. In una gerarchia di ripubblicazione, invece, gli intervalli vengono gestiti dal server di pubblicazione radice e dai server di ripubblicazione.Identity ranges are managed by the Publisher and propagated to Subscribers by the Merge Agent (in a republishing hierarchy, ranges are managed by the root Publisher and the republishers). I valori Identity vengono assegnati da un pool nel server di pubblicazione.The identity values are assigned from a pool at the Publisher. Se si aggiunge un articolo con una colonna Identity a una pubblicazione mediante Creazione guidata nuova pubblicazione o usando la stored procedure sp_addmergearticle (Transact-SQL), è necessario specificare i valori seguenti:When you add an article with an identity column to a publication in the New Publication Wizard or by using sp_addmergearticle (Transact-SQL), you specify values for:

  • Il parametro @identity_range , che controlla le dimensioni dell'intervallo di valori Identity inizialmente allocato sia nel server di pubblicazione sia nei Sottoscrittori con sottoscrizioni client.The @identity_range parameter, which controls the identity range size initially allocated both to the Publisher and to Subscribers with client subscriptions.

    Nota

    Per i Sottoscrittori che eseguono le precedenti versioni di SQL ServerSQL Server, questo parametro, e non il parametro @pub_identity_range , controlla anche le dimensioni dell'intervallo di valori Identity nei Sottoscrittori di ripubblicazione.For Subscribers running previous versions of SQL ServerSQL Server, this parameter (rather than the @pub_identity_range parameter) also controls the identity range size at republishing Subscribers.

  • Il parametro @pub_identity_range , che controlla le dimensioni dell'intervallo di valori Identity per la ripubblicazione allocato nei Sottoscrittori con sottoscrizioni server ed è necessario per la ripubblicazione dei dati.The @pub_identity_range parameter, which controls the identity range size for republishing allocated to Subscribers with server subscriptions (required for republishing data). Tutti i Sottoscrittori con sottoscrizioni server ricevono un intervallo per la ripubblicazione, anche se non eseguono la ripubblicazione dei dati.All Subscribers with server subscriptions receive a range for republishing, even if they don't actually republish data.

  • Il parametro @threshold , utilizzato per determinare quando è necessario un nuovo intervallo di valori Identity per una sottoscrizione di SQL Server CompactSQL Server Compact o una versione precedente di SQL ServerSQL Server.The @threshold parameter, which is used to determine when a new range of identities is required for a subscription to SQL Server CompactSQL Server Compact or a previous version of SQL ServerSQL Server.

    Ad esempio, è possibile specificare 10.000 per @identity_range e 500.000 per @pub_identity_range.For example, you could specify 10000 for @identity_range and 500000 for @pub_identity_range. Al server di pubblicazione e a tutti i Sottoscrittori che eseguono SQL Server 2005SQL Server 2005 o versione successiva, incluso il Sottoscrittore con la sottoscrizione server, viene assegnato un intervallo primario di 10000.The Publisher and all Subscribers running SQL Server 2005SQL Server 2005 or a later version, including the Subscriber with the server subscription, are assigned a primary range of 10000. Al Sottoscrittore con la sottoscrizione server viene inoltre assegnato un intervallo primario di 500000, che può essere utilizzato dai Sottoscrittori che eseguono la sincronizzazione con il Sottoscrittore di ripubblicazione. È inoltre necessario specificare i parametri @identity_range, @pub_identity_rangee @threshold per gli articoli della pubblicazione nel Sottoscrittore di ripubblicazione.The Subscriber with the server subscription is also assigned a primary range of 500000, which can be used by Subscribers that synchronize with the republishing Subscriber (you must also specify @identity_range, @pub_identity_range, and @threshold for the articles in the publication at the republishing Subscriber).

    Tutti i Sottoscrittori che eseguono SQL Server 2005SQL Server 2005 o versione successiva ricevono inoltre un intervallo di valori Identity secondario.Each Subscriber running SQL Server 2005SQL Server 2005 or a later version also receives a secondary identity range. Questo valore secondario ha le stesse dimensioni dell'intervallo primario. Quando quest'ultimo si esaurisce viene utilizzato l'intervallo secondario. L'agente di merge assegna al Sottoscrittore un nuovo intervallo,The secondary range is equal in size to the primary range; when the primary range is exhausted, the secondary range is used, and the Merge Agent assigns a new range to the Subscriber. che diventa l'intervallo secondario. In questo modo, quando vengono utilizzati i valori Identity del Sottoscrittore il processo continua.The new range becomes the secondary range, and the process continues as the Subscriber uses identity values.

Replica transazionale con sottoscrizioni ad aggiornamento in codaTransactional Replication with Queued Updating Subscriptions

Gli intervalli di valori Identity vengono gestiti dal server di distribuzione e distribuiti ai Sottoscrittori dall'agente di distribuzione.Identity ranges are managed by the Distributor and propagated to Subscribers by the Distribution Agent. I valori Identity vengono assegnati da un pool nel server di distribuzione.The identity values are assigned from a pool at the Distributor. Le dimensioni del pool dipendono dalle dimensioni del tipo di dati e dall'incremento utilizzato per la colonna Identity.The pool size is based on the size of the data type and the increment used for the identity column. Se si aggiunge un articolo con una colonna Identity a una pubblicazione mediante Creazione guidata nuova pubblicazione o usando la stored procedure sp_addarticle (Transact-SQL), è necessario specificare i valori seguenti:When you add an article with an identity column to a publication in the New Publication Wizard or by using sp_addarticle (Transact-SQL), you specify values for:

  • Il parametro @identity_range , che controlla le dimensioni dell'intervallo di valori Identity inizialmente allocato a tutti i Sottoscrittori.The @identity_range parameter, which controls the identity range size initially allocated to all Subscribers.

  • Il parametro @pub_identity_range , che controlla le dimensioni dell'intervallo di valori Identity allocato al server di pubblicazione.The @pub_identity_range parameter, which controls the identity range size allocated to the Publisher.

  • Il parametro @threshold , utilizzato per determinare quando è necessario un nuovo intervallo di valori Identity per una sottoscrizione.The @threshold parameter, which is used to determine when a new range of identities is required for a subscription.

    Ad esempio, è possibile specificare 10.000 per @pub_identity_range, 1000 per @identity_range (presupponendo aggiornamenti minori nel Sottoscrittore) e 80% per @threshold.For example, you could specify 10000 for @pub_identity_range, 1000 for @identity_range (assuming fewer updates at the Subscriber), and 80 percent for @threshold. Dopo 800 inserimenti in un Sottoscrittore, pari all'80% di 1000, al Sottoscrittore viene assegnato un nuovo intervallo.After 800 inserts at a Subscriber (80 percent of 1000), a Subscriber is assigned a new range. Dopo 8.000 inserimenti nel server di pubblicazione, al server di pubblicazione viene assegnato un nuovo intervallo.After 8000 inserts at the Publisher, the Publisher is assigned a new range. A questo punto vi sarà un gap nell'intervallo di valori Identity della tabella.When a new range is assigned, there will be a gap in the identity range values in the table. Specificando una soglia più elevata si avranno gap più piccoli, ma il sistema sarà meno tollerante agli errori. Se per qualche ragione non è possibile eseguire l'agente di distribuzione, i Sottoscrittori potrebbero esaurire più facilmente i valori Identity.Specifying a higher threshold results in smaller gaps, but the system is less fault-tolerant: if the Distribution Agent cannot run for some reason, a Subscriber could more easily run out of identities.

Assegnazione di intervalli per la gestione manuale degli intervalli di valori IdentityAssigning ranges for manual identity range management

Se si sceglie la gestione manuale, è necessario verificare che il server di pubblicazione e tutti i Sottoscrittori utilizzino intervalli di valori Identity diversi.If you specify manual identity range management, you must ensure that the Publisher and each Subscriber use different identity ranges. Si consideri, ad esempio, una tabella nel server di pubblicazione con una colonna Identity definita come IDENTITY(1,1): la colonna Identity comincia col valore 1 e viene incrementata di 1 ogni volta che viene inserita una riga.For example, consider a table at the Publisher with an identity column defined as IDENTITY(1,1): the identity column starts at 1 and is incremented by 1 each time a row is inserted. Se la tabella nel server di pubblicazione ha 5.000 righe e si prevede una crescita nella tabella superiore alla durata dell'applicazione, per il server di pubblicazione si potrebbe utilizzare l'intervallo 1-10.000.If the table at the Publisher has 5,000 rows, and you expect some growth in the table over the life of the application, the Publisher could use the range 1-10,000. Nel caso vi siano due Sottoscrittori, per il Sottoscrittore A si potrebbe utilizzare l'intervallo 10.001-20.000 e per il Sottoscrittore B l'intervallo 20.001-30.000.Given two Subscribers, Subscriber A could use 10,001–20,000, and Subscriber B could use 20,001-30,000.

Dopo aver inizializzato un Sottoscrittore con uno snapshot o altri metodi, eseguire DBCC CHECKIDENT per assegnare al Sottoscrittore un punto di partenza per l'intervallo di valori Identity.After a Subscriber is initialized with a snapshot or through another means, execute DBCC CHECKIDENT to assign the Subscriber a starting point for its identity range. Ad esempio, nel Sottoscrittore A si eseguirà DBCC CHECKIDENT('<TableName>','reseed',10001),For example, at Subscriber A, you would execute DBCC CHECKIDENT('<TableName>','reseed',10001). mentre nel Sottoscrittore B si eseguirà CHECKIDENT('<TableName>','reseed',20001).At Subscriber B, you would execute CHECKIDENT('<TableName>','reseed',20001).

Per assegnare nuovi intervalli al server di pubblicazione o ai Sottoscrittori, eseguire DBCC CHECKIDENT e specificare un nuovo valore per reinizializzare la tabella.To assign new ranges to the Publisher or Subscribers, execute DBCC CHECKIDENT and specify a new value to reseed the table. È consigliabile definire un metodo per determinare quando è necessario assegnare un nuovo intervallo.You should have some way to determine when a new range must be assigned. Ad esempio, nell'applicazione potrebbe esserci un meccanismo che rileva quando un nodo sta per esaurire il proprio intervallo e quindi consente di assegnare un nuovo intervallo mediante DBCC CHECKIDENT.For example, your application could have a mechanism that detects when a node is about to use up its range and assign a new range using DBCC CHECKIDENT. È inoltre possibile aggiungere un vincolo CHECK per impedire che venga aggiunta una riga se ciò determina l'utilizzo di un valore Identity non compreso nell'intervallo disponibile.You can also add a check constraint to ensure that a row cannot be added if it would cause an out of range identity value to be used.

Gestione degli intervalli di valori Identity dopo il ripristino di un databaseHandling Identity Ranges after a Database Restore

Se si utilizza la gestione automatica, quando un Sottoscrittore viene ripristinato da un backup, viene richiesto automaticamente un nuovo intervallo di valori Identity.If you are using automatic identity range management, when a Subscriber is restored from a backup, it automatically requests a new range of identity values. Se un server di pubblicazione viene ripristinato da un backup, è necessario verificare che al server di pubblicazione venga assegnato l'intervallo appropriato.If a Publisher is restored from a backup, you must ensure that the Publisher is assigned an appropriate range. Per la replica di tipo merge, assegnare un nuovo intervallo mediante sp_restoremergeidentityrange (Transact-SQL).For merge replication, assign a new range using sp_restoremergeidentityrange (Transact-SQL). Nella replica transazionale determinare il valore massimo utilizzato e quindi impostare il punto di partenza dei nuovi intervalli.For transactional replication, determine the highest value that has been used and then set the starting point for new ranges. Utilizzare la procedura seguente dopo aver ripristinato il database di pubblicazione:Use the following procedure after the publication database has been restored:

  1. Arrestare tutte le attività di tutti i Sottoscrittori.Stop all activity on all Subscribers.

  2. Per ogni tabella pubblicata che include una colonna Identity:For each published table that includes an identity column:

    1. Nel database di sottoscrizione di ogni Sottoscrittore eseguire IDENT_CURRENT('<TableName>').In the subscription database at each Subscriber, execute IDENT_CURRENT('<TableName>').

    2. Registrare il valore massimo rilevato in tutti i Sottoscrittori.Record the highest value found across all Subscribers.

    3. Nel database di pubblicazione del server di pubblicazione eseguire DBCC CHECKIDENT(<TableName>','reseed',<HighestValueFound+1>.In the publication database at the Publisher, execute DBCC CHECKIDENT(<TableName>','reseed',<HighestValueFound+1>).

    4. Nel database di pubblicazione del server di pubblicazione eseguire sp_adjustpublisheridentityrange <PublicationName>, <TableName>.In the publication database at the Publisher, execute sp_adjustpublisheridentityrange <PublicationName>, <TableName>.

    Nota

    Se il valore nella colonna Identity viene impostato per essere decrementato anziché incrementato, registrare il valore minimo rilevato e quindi reinizializzare tale valore.If the value in the identity column is set to decrement rather than increment, record the lowest value found, and then reseed with that value.

Vedere ancheSee Also

BACKUP (Transact-SQL) BACKUP (Transact-SQL)
DBCC CHECKIDENT (Transact-SQL) DBCC CHECKIDENT (Transact-SQL)
IDENT_CURRENT (Transact-SQL) IDENT_CURRENT (Transact-SQL)
IDENTITY (proprietà) (Transact-SQL) IDENTITY (Property) (Transact-SQL)
sp_adjustpublisheridentityrange (Transact-SQL)sp_adjustpublisheridentityrange (Transact-SQL)