SQL Server: modifica la tabella, elimina e crea
-
28-09-2020 - |
Domanda
Il nostro database è SQL Server 2008 R2.Abbiamo alcune tabelle che hanno alcune colonne varchar(500) che voglio passare a datetime2 o bigint.Posso garantire che tutti i dati nelle colonne da cambiare siano validi per il tipo corretto.Le modifiche alle colonne influiscono sugli indici, ma non sulle chiavi.
Discutendo con i colleghi, siamo giunti a due modi per affrontare il problema.Entrambi questi sarebbero eseguiti tramite script T-Sql.
- Crea una tabella temporanea tramite Seleziona in, rilascia la vecchia tabella e ricrea la tabella con i tipi di dati corretti.Ricreare gli indici.
- Modificare la tabella/tipi di dati correnti tramite
ALTER TABLE x ALTER COLUMN Y datetime2
e quindi ricostruire o ricreare gli indici.
Poiché sono fiducioso che i dati verranno convertiti in modo pulito, mi propendo per il punto 2.Il mio collega e un amico DBA preferiscono il numero 1, ma il mio collega non riesce a ricordare perché lo hanno addestrato in quel modo.L'amico DBA è in vacanza quindi non gli ho chiesto il motivo.
Qualcuno può fornire informazioni su quale opzione ritiene sia migliore e perché?Alla fine è una mia decisione e mi chiedo perché il numero 1 dovrebbe essere preferito al numero 2?
Soluzione
Di recente l'ho fatto nella mia organizzazione in cui volevamo gestire una tabella con oltre un miliardo di righe.
Tutto il merito dell'idea va ad Aaron Bertrand e proviene dal suo post sul blog Colpi di trucco:Schema Switch-A-Roo
Prova il processo riportato di seguito su un tavolino e mettiti comodo prima di farlo in PROD.
- creare 2 schemi
fake
Eshadow
con autorizzazionedbo
. - Crea una tabella con le colonne e i tipi di dati desiderati
shadow
schema ad es.create table shadow.Correct_Table ...
- Inserisci i dati e crea tutti gli indici che la tabella originale ha nel file
shadow
tabella dello schema. - In questo modo hai copie identiche della tabella con dati e indici ma si trovano in schemi diversi (separati logicamente).
- Una volta terminato, aggiorna le statistiche sul tavolo con
shadow
schema. Cambia gli schemi (questa è un'operazione sui metadati ed è estremamente veloce)
--- ALTER SCHEMA TargetSchema TRANSFER SourceSchema.TableName; BEGIN TRANSACTION; ALTER SCHEMA fake TRANSFER dbo.original_table; ALTER SCHEMA dbo TRANSFER shadow.Correct_Table; COMMIT TRANSACTION; ALTER SCHEMA shadow TRANSFER fake.Lookup;
Fai un controllo finale per vedere se tutto è andato come previsto.Dovresti fare un
select count(1) from dbo.Correct_table
Una volta confermato il passaggio 7 e sei soddisfatto, rilascia il file
shadow.table
,shadow
schema efake
schema come ripulito.
Altri suggerimenti
Ecco come la vedo io.
Pro per il numero 1
- Poiché stai utilizzando una tabella separata, la tua tabella di produzione rimane in uso finché non hai finito.Nessun blocco (oltre a quelli necessari per leggere i dati).
- Questo vale anche per quanto detto da @AaronBertrand:puoi farlo frammentariamente, provare ecc
- Puoi modificare l'ordine delle colonne secondo necessità
Pro per il numero 2
- È un'operazione tutto o niente.Non c'è alcuna possibilità che tu perda i dati che sono stati inseriti/modificati nella tabella originale mentre non stavi guardando.
- Tutte le autorizzazioni specificatamente assegnate all'oggetto vengono mantenute.Se usi il numero 1 devi assicurarti di scrivere script e applicarli.
Detto questo, in genere utilizzerò il numero 2 per tavoli di piccole dimensioni o quando posso verificarsi un'interruzione (fare sempre un backup prima però) e il numero 1 se non riesco a ottenere un'interruzione così grande o devo riorganizzare l'ordine delle colonne, ecc.Se intendo eseguire il punto 1, in genere genererò lo script tramite la GUI e quindi lo esaminerò attentamente prima di eseguirlo.
Fai attenzione con l'opzione rilascia e ricrea:questo può lasciare sys.depends in uno stato strano e causare problemi per i piani memorizzati nella cache in cui l'ordinamento o il tipo di colonne cambia.
Sarà inoltre necessario adottare misure per mantenere eventuali autorizzazioni a livello di oggetto, poiché queste andranno perse nel file DROP
e non ricreato automaticamente con il successivo CREATE
.
ALTER TABLE
èl'opzione più pulita, secondo me, ma assicurati di testarlo attentamente prima di farlo in produzione sia per assicurarti che tutto vada bene in seguito sia per essere sicuro di sapere quanto tempo richiederà l'operazione (su una tabella con molte righe potrebbe essere un bel po' di tempo ).
Il mio collega ha finito per trovare un articolo su ciò a cui si riferiva: http://www.nigelrivett.net/SQLAdmin/AlterTableProblems.html.Dopo aver letto questo e aver realizzato che il nostro rapporto di fine anno stava per arrivare, abbiamo deciso di non apportare modifiche ai tipi di colonna e di rivisitarlo nei prossimi due mesi.Penso che dopo aver letto l'articolo, potrei semplicemente utilizzare il metodo Drop/Create.
Grazie a tutti per il loro feedback in merito.Molti approcci interessanti da considerare quando decidiamo di andare avanti.