Modifica della colonna identità da INT a BIGINT


9

Ho una tabella con una colonna di identità che è anche una chiave primaria. Attualmente ha 50 milioni di righe, con il valore più alto della colonna identità che si trova a 148.921.803. La tabella ha molte DELETEs ed INSERTSeseguite su di essa, quindi l'alto valore.

Vogliamo cambiare il tipo di dati da INTa BIGINTper preparare l'aggiunta di più righe. Si noti che non ci sono riferimenti alla colonna PK.

Qual è il modo migliore per farlo, con tempi di fermo minimi? Ho due opzioni.

  1. Rilascia il PK e modifica la colonna; o
  2. Il metodo copy-drop-rename, come descritto qui :

Risposte:


7

Poiché esiste una chiave primaria definita nella colonna identità, non sarà possibile modificare direttamente questa colonna.

Entrambi gli approcci che hai menzionato nella tua domanda possono essere utilizzati e i tempi di inattività dipendono dalle prestazioni del tuo server e dal numero di righe che risiedono in quella tabella.

  1. Rilascia il PK e modifica la colonna; o

Per prima cosa rilascia il PK

/****** Object: DROP Index [PK_DatabaseLog_DatabaseLogID]******/

ALTER TABLE [dbo].[TableName] DROP CONSTRAINT [PK_TableName_ID]
GO

Modifica colonna

ALTER TABLE [dbo].[TableName] ALTER COLUMN [dbo.ID] BIGINT

Aggiungi chiave primaria

/****** Object: ADD Index [PK_DatabaseLog_DatabaseLogID]******/
ALTER TABLE [dbo].[TableName] ADD  CONSTRAINT [PK_TableName_ID] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)

Questo approccio di solito non richiede molto tempo. Nel mio ambiente ci vogliono secondi di mare su grandi tavoli che hanno più di 5 milioni di righe.

  1. Il metodo copy-drop-rename, come descritto

Puoi anche usare questo approccio. Tuttavia, per questo approccio sono necessari più tempi di inattività rispetto all'approccio 1 in quanto è necessario sincronizzare le tabelle.


6

Aaron Bertrand ha una serie in 4 parti su questo argomento, che inizia con:

Riduzione al minimo dell'impatto dell'ampliamento di una colonna IDENTITÀ - parte 1

Se devi assolutamente spostarti bigint, ridurre al minimo i tempi di inattività e avere molto tempo per pianificare, l'approccio che documenta nella parte 4 è:

A un livello molto alto, l'approccio è quello di creare un set di tabelle shadow, in cui tutti gli inserti sono indirizzati a una nuova copia della tabella (con il tipo di dati più grande) e l'esistenza delle due serie di tabelle è trasparente il più possibile all'applicazione e ai suoi utenti.

Più in dettaglio, Aaron afferma:

  1. Crea copie shadow delle tabelle, con i giusti tipi di dati.
  2. Modificare le stored procedure (o il codice ad hoc) per utilizzare bigint per i parametri. (Ciò potrebbe richiedere modifiche oltre l'elenco dei parametri, come variabili locali, tabelle temporanee, ecc., Ma qui non è così.)
  3. Rinominare le vecchie tabelle e creare viste con quei nomi che uniscono le vecchie e le nuove tabelle.
    • Tali viste avranno invece dei trigger per indirizzare correttamente le operazioni DML alle tabelle appropriate, in modo che i dati possano ancora essere modificati durante la migrazione.
    • Ciò richiede anche che SCHEMABINDING venga eliminato da qualsiasi vista indicizzata, le viste esistenti abbiano unioni tra vecchie e nuove tabelle e le procedure che si basano su SCOPE_IDENTITY () per essere modificate.
  4. Migrare i vecchi dati nelle nuove tabelle in blocchi.
  5. Pulizia, composta da:
    • Eliminazione delle viste temporanee (che elimineranno i trigger INSTEAD OF).
    • Rinominare le nuove tabelle con i nomi originali.
    • Correzione delle procedure memorizzate per ripristinare SCOPE_IDENTITY ().
    • Far cadere i vecchi tavoli, ora vuoti.
    • Riportare SCHEMABINDING su viste indicizzate e ricreare indici cluster.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.