sql >> Database teknologi >  >> RDS >> Sqlserver

Sådan tilføjes en identitetskolonne til en eksisterende databasetabel, som har et stort antal rækker

Den overordnede proces vil sandsynligvis være meget langsommere med flere overordnede låseomkostninger, men hvis du kun bekymrer dig om størrelsen på transaktionsloggen, kan du prøve følgende.

  1. Tilføj en kolonne med null-heltal uden identitet (kun ændring af metadata).
  2. Skriv kode for at opdatere dette med unikke sekventielle heltal i batches. Dette vil reducere størrelsen af ​​hver enkelt transaktion og holde logstørrelsen nede (forudsat en simpel gendannelsesmodel). Min kode nedenfor gør dette i batches af 100, forhåbentlig har du en eksisterende PK, du kan bruge til at fortsætte, hvor du slap, i stedet for de gentagne scanninger, der vil tage mere og mere lang tid mod slutningen.
  3. brug ALTER TABLE ... ALTER COLUMN for at markere kolonnen som NOT NULL . Dette kræver, at hele tabellen låses og scannes for at validere ændringen, men det kræver ikke megen logning.
  4. Brug ALTER TABLE ... SWITCH at gøre kolonnen til en identitetskolonne. Dette er kun en ændring af metadata.

Eksempelkode nedenfor

/*Set up test table with just one column*/ CREATE TABLE table_1 ( original_column INT ) INSERT INTO table_1 SELECT DISTINCT number FROM master..spt_values /*Step 1 */ ALTER TABLE table_1 ADD id INT NULL /*Step 2 */ DECLARE @Counter INT = 0 , @PrevCounter INT = -1 WHILE @PrevCounter <> @Counter BEGIN SET @PrevCounter = @Counter; WITH T AS ( SELECT TOP 100 * , ROW_NUMBER() OVER ( ORDER BY @@SPID ) + @Counter AS new_id FROM table_1 WHERE id IS NULL ) UPDATE T SET id = new_id SET @Counter = @Counter + @@ROWCOUNT END BEGIN TRY; BEGIN TRANSACTION ; /*Step 3 */ ALTER TABLE table_1 ALTER COLUMN id INT NOT NULL /*Step 4 */ DECLARE @TableScript NVARCHAR(MAX) = ' CREATE TABLE dbo.Destination( original_column INT, id INT IDENTITY(' + CAST(@Counter + 1 AS VARCHAR) + ',1) ) ALTER TABLE dbo.table_1 SWITCH TO dbo.Destination; ' EXEC(@TableScript) DROP TABLE table_1 ; EXECUTE sp_rename N'dbo.Destination', N'table_1', 'OBJECT' ; COMMIT TRANSACTION ; END TRY BEGIN CATCH IF XACT_STATE() <> 0 ROLLBACK TRANSACTION ; PRINT ERROR_MESSAGE() ; END CATCH ;

  1. PostgreSQL Ingen Auto Increment-funktion?

  2. MySQL - SUMMEN af en gruppe af tidsforskelle

  3. Tillad ikke omvendt sammensat primær nøgle i MySQL

  4. hvad er der galt med min procedure i mysql?