Ändern der Identitätsspalte von INT in BIGINT

9

Ich habe eine Tabelle mit einer Identitätsspalte, die auch ein Primärschlüssel ist. Derzeit hat es 50 Millionen Zeilen, wobei der höchste Wert der Identitätsspalte bei 148.921.803 liegt. Die Tabelle hat viele DELETEs und wird darauf INSERTSausgeführt, daher der hohe Wert.

Wir wollen den Datentyp ändern von INTbis BIGINTfür die Zugabe von mehr Reihen vorzubereiten. Beachten Sie, dass es keine Verweise auf die PK-Spalte gibt.

Was ist der beste Weg, dies mit minimalen Ausfallzeiten zu tun? Ich habe zwei Möglichkeiten.

  1. Lassen Sie die PK fallen und ändern Sie die Spalte. oder
  2. Die Kopie-Drop-Umbenennungsverfahren, wie hier :
Felix Pamittan
quelle

Antworten:

7

Da in der Identitätsspalte ein Primärschlüssel definiert ist, können Sie diese Spalte nicht direkt ändern.

Beide Ansätze, die Sie in Ihrer Frage erwähnt haben, können verwendet werden. Ausfallzeiten hängen von der Leistung Ihres Servers und der Anzahl der Zeilen in dieser Tabelle ab.

  1. Lassen Sie die PK fallen und ändern Sie die Spalte. oder

Lassen Sie zuerst die PK fallen

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

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

Spalte ändern

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

Primärschlüssel hinzufügen

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

Dieser Ansatz nimmt normalerweise nicht viel Zeit in Anspruch. In meiner Umgebung dauert es bei großen Tischen mit mehr als 5 Millionen Zeilen nur wenige Sekunden.

  1. Die Copy-Drop-Rename-Methode, wie beschrieben

Sie können diesen Ansatz auch verwenden. Für diesen Ansatz benötigen Sie jedoch mehr Ausfallzeiten als für Ansatz 1, da Sie die Tabellen synchronisieren müssen.

Shashank Tiwari
quelle
6

Aaron Bertrand hat eine 4-teilige Serie zu diesem Thema, beginnend mit:

Minimierung der Auswirkungen der Erweiterung einer IDENTITY-Spalte - Teil 1

Wenn Sie unbedingt umziehen bigintmüssen, Ausfallzeiten minimieren und genügend Zeit für die Planung haben müssen, dokumentiert er den in Teil 4 dokumentierten Ansatz :

Auf einer sehr hohen Ebene besteht der Ansatz darin, einen Satz von Schattentabellen zu erstellen, wobei alle Einfügungen auf eine neue Kopie der Tabelle (mit dem größeren Datentyp) gerichtet sind und die Existenz der beiden Sätze von Tabellen ebenso transparent ist wie möglich für die Anwendung und ihre Benutzer.

Im Detail sagt Aaron:

  1. Erstellen Sie Schattenkopien der Tabellen mit den richtigen Datentypen.
  2. Ändern Sie die gespeicherten Prozeduren (oder den Ad-hoc-Code), um bigint für Parameter zu verwenden. (Dies erfordert möglicherweise Änderungen außerhalb der Parameterliste, z. B. lokale Variablen, temporäre Tabellen usw., dies ist hier jedoch nicht der Fall.)
  3. Benennen Sie die alten Tabellen um und erstellen Sie Ansichten mit den Namen, die die alten und neuen Tabellen verbinden.
    • Diese Ansichten haben anstelle von Triggern die Möglichkeit, DML-Vorgänge ordnungsgemäß auf die entsprechenden Tabellen zu leiten, sodass die Daten während der Migration weiterhin geändert werden können.
    • Dazu muss SCHEMABINDING auch aus indizierten Ansichten entfernt werden, vorhandene Ansichten müssen über Vereinigungen zwischen neuen und alten Tabellen verfügen, und Prozeduren, die auf SCOPE_IDENTITY () basieren, müssen geändert werden.
  4. Migrieren Sie die alten Daten in Blöcken in die neuen Tabellen.
  5. Aufräumen, bestehend aus:
    • Löschen der temporären Ansichten (wodurch die STATT-Trigger gelöscht werden).
    • Umbenennen der neuen Tabellen in die ursprünglichen Namen.
    • Korrigieren der gespeicherten Prozeduren, um zu SCOPE_IDENTITY () zurückzukehren.
    • Die alten, jetzt leeren Tische fallen lassen.
    • Setzen Sie SCHEMABINDING wieder auf indizierte Ansichten und erstellen Sie Clustered-Indizes neu.
Paul White 9
quelle