Za prvé, děkuji, že to děláte. Je to tak samozřejmá výhra, v níž by mnozí neviděli velkou cenu, ale bude to stát za to :). Děláme svět tak trochu rozumnějším.
Ohledně IsActive
být booleovský. Hádám, že uvažujete o tom, že z toho uděláte BIT
pole. To by mohla být cesta, ale někdy je lepší jít s TINYINT
protože existuje možnost rozšíření významu do více než 2 stavů. V takovém případě se skutečně stane více z StatusID
. Obvykle se jedná o případ, kdy něco začíná zjednodušeně jako aktivní / Neaktivní , ale později možná Smazáno a/nebo další. Z hlediska velikosti TINYINT
je vždy 1 bajt. Na druhé straně BIT
je 1 bajt až 8 BIT
pole . To znamená jeden BIT
pole je 1 bajt, 2 BIT
pole je také jeden bajt a tak dále až 8 BIT
pole jsou uložena v jednom bajtu. Volba BIT
tedy neušetří místo přes TINYINT
když tabulka má pouze 1 BIT
pole. Jen něco ke zvážení.
Jak jste viděli, udělat ALTER TABLE je na velký stůl trochu moc. Jedna možnost, i když ne skvělá, je přidat NOT NULL
pole --Number_1new
--s DEFAULT
hodnotu (toto bude okamžité kvůli výchozímu nastavení, alespoň počínaje SQL 2012), kterou by žádný z nich přirozeně neměl (např. 255), a poté pomalu migrujte hodnoty ve smyčce, jako v:
UPDATE TOP (5000) tab
SET tab.Number_1new = tab.Number_1
FROM [table] tab
WHERE tab.Number_1new = 255;
A až to bude hotové, udělejte:
sp_rename 'table.Number_1', 'Number_1old', 'COLUMN';
sp_rename 'table.Number_1new', 'Number_1', 'COLUMN';
Nejlepší je samozřejmě zabalit to do TRANSAKCE a to zabalit do VYZKOUŠEJTE / ODLOŽTE. Až bude související kód aktualizován a vše otestováno a data vypadají dobře, můžete vypustit Number_1old
sloupec.
Nejlepším způsobem, který jsem našel, je vytvořit novou tabulku, pomalu převádět data a poté tabulky a kód prohodit současně. Postup jsem podrobně popsal v článku na SQL Server Central:Restrukturalizace 100 milionů Row (nebo více) Tabulky v sekundách. SRSLY! (nutná bezplatná registrace). Pro případ, že by došlo k problémům s přístupem k tomuto článku, zde jsou základní kroky:
- Vytvořte novou tabulku s ideální strukturou--[tableNew]. Pokud používáte Enterprise Edition, zvažte povolení komprese ROW nebo PAGE, protože někdy mohou pomoci. Nejprve si však proveďte průzkum, protože existují situace, kdy mají negativní účinek. Na webu MSDN je dokumentace, která vám pomůže to zjistit, a také některé nástroje, které vám pomohou odhadnout potenciální úspory. Ale i když kompresi povolíte, neviděl bych tuto akci jako nahrazení projektu, který zde děláte.
- Přidat spouštěč
AFTER UPDATE, DELETE
na [tabulce], aby se změny synchronizovaly (ale nemusíte se starat o nové řádky) - Vytvořte úlohu agenta SQL, která se v dávkách přesune přes chybějící řádky. Udělejte to ve smyčce, která provede
INSERT INTO [tableNew] (Columns) SELECT TOP (n) Columns FROM [table] WHERE ?? ORDER BY ??
- Klauzule WHERE a ORDER BY závisí na situaci. Měly by být zaměřeny na co nejlepší využití seskupeného indexu. Pokud je seskupený index nové tabulky strukturálně stejný jako stará/aktuální tabulka, pak na začátku každé smyčky můžete získat MAX([id]) z [tableNew] a použít jej k získání tabulky
WHERE table.[id] > @MaxIdInTableNew ORDER BY table.[id]
. - Vytvořte novou tabulku, spusťte na aktuální tabulce a úlohu SQL Agent Job přibližně týden před tím, než budete muset provést úplné přerušení. Tento časový rámec se může změnit v závislosti na vaší situaci, ale nezapomeňte si dát dostatek času. Pro tuto práci je mnohem lepší dokončit migraci řádků a nechat jich nakapat jen několik najednou, než se 100 000 vyhýbat celé sadě, protože vydání má začít.
- Pokud je v plánu migrace dalších souvisejících tabulek (odkazy na PK pro dva FK, které chcete změnit na
INT
s), pak tato pole vytvořte zdeINT
nyní a prostě nepřidávejte FK, dokud tyto ostatní tabulky nebudou migrovány na pole INT jako jejich PK. Nechcete, abyste museli znovu sestavovat tuto tabulku, jen abyste provedli tuto změnu pro pole FK. - Během přerušování (samozřejmě v režimu TRY / CATCH):
- ZAČNĚTE PŘENOS
- proveďte poslední počet řádků v obou tabulkách, abyste se ujistili, že je vše přesunuto (možná by bylo dobré zkontrolovat řádky před vydáním, abyste se ujistili, že spouštěč provedl aktualizace a odstranění podle očekávání)
- přejmenujte aktuální tabulku na "starou"
- přejmenujte tabulku „nová“ tak, aby neměla „nová“
- zrušte úlohu SQL Agent (nebo ji alespoň zakažte)
- přejmenovávat a závislé objekty, jako jsou omezení atd.
- POTVRDIT