sql >> Databáze >  >> RDS >> Sqlserver

Zúžení datových typů na velmi velké tabulce

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:

  1. 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.
  2. Přidat spouštěč AFTER UPDATE, DELETE na [tabulce], aby se změny synchronizovaly (ale nemusíte se starat o nové řádky)
  3. 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 ??
  4. 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] .
  5. 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.
  6. 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 zde INT 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.
  7. Během přerušování (samozřejmě v režimu TRY / CATCH):
    1. ZAČNĚTE PŘENOS
    2. 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í)
    3. přejmenujte aktuální tabulku na "starou"
    4. přejmenujte tabulku „nová“ tak, aby neměla „nová“
    5. zrušte úlohu SQL Agent (nebo ji alespoň zakažte)
    6. přejmenovávat a závislé objekty, jako jsou omezení atd.
    7. POTVRDIT


  1. Standardy pro přidání data/času?

  2. Dotazování na více tabulek se složitými vztahy

  3. Klasické ASP + Motobit Pure ASP Upload + UTF-8 znaková sada

  4. Python převádí výsledek dotazu mysql na json