Först och främst, tack för att du gör detta. Det är en så självklar vinst som många inte skulle se mycket värde i, men det kommer att vara väl värt det :). Gör världen lite sundare.
Angående IsActive
vara en boolean. Min gissning är att du funderar på att göra det till en BIT
fält. Det kan vara vägen att gå, men ibland är det bättre att gå med TINYINT
eftersom det finns möjlighet att utöka betydelsen till mer än 2 tillstånd. I så fall blir det verkligen mer av StatusID
. Vanligtvis handlar det om något som förenklat börjar som aktivt / Inaktiv , men senare kanske Raderad och/eller andra. Ur ett storleksperspektiv, TINYINT
är alltid 1 byte. Å andra sidan, BIT
är 1 byte för upp till 8 BIT
fält . Det betyder en BIT
fältet är 1 byte, 2 BIT
fält är också en byte, och så vidare upp till 8 BIT
fält som lagras i en enda byte. Så det finns ingen platsbesparing genom att välja BIT
över TINYINT
när tabellen bara har 1 BIT
fält. Bara något att tänka på.
Att göra ett ALTER TABLE är lite mycket för ett stort bord, som du såg. Ett alternativ, även om det inte är bra, är att lägga till en NOT NULL
field--Number_1new
--med en DEFAULT
värde (detta kommer att vara omedelbart på grund av standardinställningen, åtminstone från och med SQL 2012) som ingen av dem naturligt skulle ha (t.ex. 255), och sedan långsamt migrera värdena, i en loop, som i:
UPDATE TOP (5000) tab
SET tab.Number_1new = tab.Number_1
FROM [table] tab
WHERE tab.Number_1new = 255;
Och när det är gjort gör du:
sp_rename 'table.Number_1', 'Number_1old', 'COLUMN';
sp_rename 'table.Number_1new', 'Number_1', 'COLUMN';
Naturligtvis, bäst att slå in det i en TRANSAKTION, och det insvept i ett TRY/CATCH. När den relaterade koden har uppdaterats och allt har testats och data ser bra ut kan du släppa Number_1old
kolumn.
Det bästa sättet jag har hittat är dock att skapa en ny tabell, långsamt överföra data och sedan byta tabeller och kod samtidigt. Jag beskrev stegen i en artikel om SQL Server Central:Restructure 100 Million Row (eller mer) Tabeller på sekunder. SRSLY! (gratis registrering krävs). Om det skulle uppstå problem med att komma till den artikeln, här är de grundläggande stegen:
- Skapa en ny tabell med den idealiska strukturen--[tabellNy]. Om du använder Enterprise Edition, överväg att aktivera antingen ROW- eller PAGE-komprimering eftersom de ibland kan hjälpa. Men snälla gör lite forskning först eftersom det finns vissa situationer när de har en negativ effekt. Det finns dokumentation om MSDN som hjälper dig att ta reda på det samt några verktyg för att uppskatta potentiell besparing. Men även om du aktiverar komprimering, skulle jag inte se den åtgärden som en ersättning för projektet du gör här.
- Lägg till en utlösare
AFTER UPDATE, DELETE
på [tabell] för att hålla ändringar synkroniserade (men du behöver inte oroa dig för nya rader) - Skapa ett SQL Agent Job som flyttar över saknade rader i batcher. Gör detta i en loop som gör en
INSERT INTO [tableNew] (Columns) SELECT TOP (n) Columns FROM [table] WHERE ?? ORDER BY ??
- Klausulerna WHERE och ORDER BY beror på situationen. De bör vara inriktade på att utnyttja det klustrade indexet på bästa sätt. Om det klustrade indexet för den nya tabellen är strukturellt detsamma som den gamla/nuvarande tabellen, kan du i början av varje slinga hämta MAX([id]) från [tableNew] och använda den för att få
WHERE table.[id] > @MaxIdInTableNew ORDER BY table.[id]
. - Skapa den nya tabellen, trigga på den aktuella tabellen och SQL Agent Job en vecka eller så innan du behöver göra hela cut-over. Den tidsramen kan ändras beroende på din situation, men se bara till att ge dig själv gott om tid. Det är mycket bättre för jobbet att slutföra migreringen av rader och bara ha några få som droppar in åt gången i stället för att vara 100 000 blyg för hela uppsättningen när releasen ska börja.
- Om planen är att migrera de andra relaterade tabellerna (PK-referenserna för de två FK som du vill omvandla till
INT
s), gör sedan dessa fält härINT
nu och lägg bara inte till FK förrän de andra tabellerna har migrerats över till att ha INT-fält som sina PK:er. Du vill inte behöva bygga om den här tabellen igen bara för att göra den ändringen för FK-fälten. - Under cut-over (i en TRY/CATCH, naturligtvis):
- BÖRJA TRAN
- gör en sista radräkning på båda tabellerna för att se till att allt flyttas över (du kanske vill kontrollera raderna innan releasen för att se till att utlösaren gjorde uppdateringarna och raderna som förväntat)
- byt namn på den aktuella tabellen till "gammal"
- byt namn på den "nya" tabellen för att inte ha den "nya"
- släpp SQL Agent-jobbet (eller åtminstone inaktivera det)
- byt namn på och beroende objekt såsom begränsningar, etc.
- ÅTGÄRDER