Mysql
 sql >> Database >  >> RDS >> Mysql

ALTER TABLE in MySQL:amico o nemico?

L'istruzione ALTER TABLE è una delle istruzioni più utilizzate nel mondo MySQL:l'istruzione consente di aggiungere, eliminare o modificare colonne in una tabella. In questo post del blog cercheremo di approfondire cos'è, cosa fa e quando dovrebbe essere usato.

Cos'è ALTER TABLE e cosa fa?

Come già accennato in precedenza, l'istruzione ALTER TABLE consente ai DBA e agli sviluppatori di aggiungere, eliminare o modificare colonne in una tabella. In poche parole ALTER TABLE cambia la struttura di una tabella:ti consente di aggiungere, eliminare colonne, aggiungere o rimuovere indici, rinominare colonne o cambiarne il tipo.

Quando e come utilizzo ALTER TABLE?

Per usare ALTER TABLE generalmente sono necessari i privilegi ALTER, CREATE e INSERT. Per rinominare una tabella, i privilegi richiesti sono ALTER e DROP per la vecchia tabella, quindi i privilegi CREATE, ALTER e INSERT per la nuova tabella da creare. Per assegnare i privilegi richiesti a un determinato utente, puoi utilizzare la seguente query:

GRANT ALTER, CREATE, INSERT ON database.* TO 'demo_user';

Sostituisci database con il nome del tuo database, il carattere jolly con il nome della tabella se desideri che i privilegi siano applicabili solo a determinate tabelle (il carattere jolly rende il privilegio applicabile a tutte le tabelle) e demo_user con il nome di il tuo utente. Se desideri che i privilegi vengano utilizzati in tutti i database e in tutte le tabelle al loro interno, sostituisci semplicemente il database con un carattere jolly:

GRANT ALTER, CREATE, INSERT ON *.* TO 'demo_user';

Per utilizzare effettivamente l'istruzione ALTER TABLE, eseguire una query che modifichi la struttura di una tabella - ALTER TABLE viene utilizzato per aggiungere, eliminare o modificare colonne in una tabella:la query può anche essere utilizzato per aggiungere indici alle colonne. Ecco alcuni esempi di base delle query utilizzate più di frequente:

ALTER TABLE demo_table ADD column_name VARCHAR(255) NOT NULL DEFAULT ‘’; T

la sua query aggiungerebbe una colonna column_name a una tabella demo_table. Aggiungi FIRST alla fine della query per rendere la colonna la prima colonna della tabella.

ALTER TABLE demo_table ADD column_2 VARCHAR(255) NOT NULL DEFAULT ‘’ AFTER column_1; T

la sua query aggiungerebbe una colonna column_2 dopo la colonna column_1 su una tabella demo_table.

ALTER TABLE demo_table ADD COLUMN column_2 INT GENERATED ALWAYS AS (column_1 + 1) STORED; 

Questa query aggiungerebbe una colonna generata alla tabella.

ALTER TABLE demo_table DROP COLUMN demo_column; 

Questa query rilascerebbe la colonna demo_column su una tabella demo_table.

ALTER TABLE demo_table ADD INDEX demo_index(demo_column); 

Questa query aggiungerebbe un indice denominato demo_index (è possibile scegliere i nomi) su una colonna denominata demo_column in una tabella denominata demo_table.

ALTER TABLE demo_table ADD INDEX (demo_column), ADD UNIQUE (demo_unique); 

Questa query aggiungerebbe un indice su una colonna demo_column e un indice univoco sulla colonna demo_unique.

ALTER TABLE demo_table MODIFY column_name VARCHAR(255) CHARACTER SET utf8mb4; 

Questa query modificherebbe il set di caratteri predefinito di una colonna specifica.

ALTER TABLE demo_table CONVERT TO CHARACTER SET charset_name; 

Questa query modificherebbe il set di caratteri predefinito della tabella e tutte le colonne di caratteri (CHAR, VARCHAR e TEXT).

ALTER TABLE demo_table PARTITION BY HASH(demo_column) PARTITIONS 8; 

Questa query partizionerebbe la colonna demo_column in 8 partizioni tramite hash.

ALTER TABLE demo_table TABLESPACE tablespace_1 STORAGE DISK; 

Questa query converte la tabella demo_table in una memoria basata su disco.

Se stai aggiungendo indici, tieni presente che puoi aggiungere diversi tipi di indici (ad esempio un indice BTREE o un indice FULLTEXT), puoi anche aggiungere un indice che copre solo un certo importo di caratteri in una colonna con una query del genere:

ALTER TABLE demo_table ADD INDEX demo_index(column_name(10));

La query precedente aggiungerebbe un indice chiamato demo_index sui primi 10 caratteri della colonna chiamata column_name in una tabella chiamata demo_table.

Gli indici in MySQL sono una bestia complessa e meritano davvero un argomento a parte, quindi non entreremo nei dettagli qui, ma se vuoi saperne di più, il nostro precedente post sugli indici MySQL dovrebbe fornirne alcuni maggiori informazioni.

Come funziona ALTER TABLE?

ALTER TABLE in MySQL ha le sue sottigliezze. A partire dalla versione più recente di MySQL, ovvero MySQL 8.0. Esistono 3 algoritmi per i quali influisce sul modo in cui ALTER TABLE si comporta per tali alterazioni. Questi sono:

  • COPIA

    • Le operazioni vengono eseguite su una copia della tabella originale e i dati della tabella vengono copiati dalla tabella originale alla nuova tabella riga per riga. Nella maggior parte dei casi, questo algoritmo può essere molto costoso in termini di utilizzo delle risorse, specialmente per tabelle grandi e grandi. Quando questo algoritmo viene scelto o selezionato, tutti i DML simultanei non sono consentiti, quindi qualsiasi query successiva che fa riferimento alla tabella interessata dovrà attendere o accodarsi nell'elenco dei processi. È probabile che il database si bloccherà se le connessioni sono esaurite.

  • IN POSTO

    • Le operazioni evitano di copiare i dati della tabella ma possono ricostruire la tabella sul posto. Un esclusivo blocco dei metadati sulla tabella può essere effettuato brevemente durante le fasi di preparazione ed esecuzione dell'operazione. In genere, è supportato DML simultaneo.

  • ISTANTANEO

    • Le operazioni modificano solo i metadati nel dizionario dei dati. Durante la preparazione e l'esecuzione non vengono presi blocchi esclusivi di metadati sulla tabella e i dati della tabella non vengono modificati, rendendo le operazioni istantanee. È consentito DML simultaneo. (Introdotto in MySQL 8.0.12)

Il processo ALTER TABLE di MySQL potrebbe non essere un problema con tabelle più piccole, ma se il tuo set di dati è più grande puoi incorrere in problemi:molte persone hanno riscontrato query ALTER TABLE che hanno richiesto ore, giorni o addirittura settimane completare. Nella maggior parte dei casi, ciò accade a causa del processo di alterazione della tabella di MySQL descritto sopra. Tuttavia, esiste un modo per ridurre almeno leggermente il tempo necessario per il completamento della query:

  1. Crea una nuova tabella come la tua tabella di origine con la struttura desiderata eseguendo
    CREATE TABLE demo_table_new LIKE demo_table;
    poi aggiustandone la struttura. In questo caso demo_table è la tabella di origine e demo_table_new è la nuova tabella.
  2. Inserisci i dati nella nuova tabella.
  3. Rinomina la vecchia tabella in demo_table_old (modifica il nome in base alle tue esigenze).
  4. Rinomina la nuova tabella con il nome precedente della vecchia tabella.
  5. Infine, copia le righe dalla vecchia tabella alla nuova tabella e, se necessario, crea gli indici.

Anche se i passaggi precedenti funzionano bene. Tuttavia, in scenari di casi reali, i DBA o gli sviluppatori prendono la snella per utilizzare il cambio di schema pt-online di Percona o utilizzando gh-ost di Github. Puoi dare un'occhiata al nostro post precedente I migliori strumenti open source per le migrazioni MySQL e MariaDB che offre una panoramica di questi strumenti di modifica dello schema.

Comunque, quello che abbiamo descritto sopra è spesso conosciuto come l'approccio della “copia shadow”:in sostanza, si costruisce una nuova tabella con la struttura desiderata, quindi si esegue una ridenominazione e si rilascia per scambiare le due tabelle . C'è anche un altro modo:puoi anche scambiare i server ed eseguire ALTER TABLE su server che non sono in produzione. Per MyISAM, puoi DISABILITARE CHIAVI, caricare dati, quindi ABILITARE CHIAVI.

ALTER TABLE Gotchas

Se stai usando l'istruzione ALTER TABLE per creare indici (puoi anche usare l'istruzione CREATE INDEX), si consiglia di creare indici dopo aver inserito i dati perché è un modo abbastanza noto per accelerare elaborazione non solo in MySQL, ma anche in altri sistemi di gestione di database, come Oracle. In generale, tuttavia, tieni presente che la maggior parte delle operazioni di ALTER TABLE dovrebbero causare alcuni problemi (interruzione del servizio) a MySQL.

C'è anche un altro modo per velocizzare l'intero processo, anche se è un po' più avanzato:se riesci a convincere MySQL a modificare solo il file .frm della tabella (i file .frm descrivono la definizione di il tavolo) e lascia stare il tavolo, il processo sarà più veloce:

  1. Crea una tabella vuota con lo stesso layout della vecchia tabella senza modificarla.
  2. Chiudi tutte le tabelle in uso e impedisci l'apertura di tutte le nuove tabelle eseguendo 
    FLUSH TABLES WITH READ LOCK.
  3. Scambia i file .frm.
  4. Rilascia il blocco di lettura eseguendo UNLOCK TABLES.

Tieni anche presente che se vuoi modificare una colonna e la sintassi sembra corretta ma ricevi ancora un errore, potrebbe essere il momento di esaminare una sintassi diversa. Ad esempio:

ALTER TABLE demo_table ADD long VARCHAR(255); 

Una query come questa andrebbe in errore perché long è una parola riservata. Per evitare un tale errore, sfuggi alla parola con i backtick:

ALTER TABLE demo_table ADD `long` VARCHAR(255);

Vale anche la pena notare che i nomi delle colonne possono essere evitati solo usando backtick e non con virgolette singole o doppie. Ad esempio, anche una query del genere risulterebbe in errore:

ALTER TABLE demo_table CHANGE COLUMN ‘demo_column’ ‘demo_column_2’ VARCHAR(255);

Riepilogo

MySQL utilizza l'istruzione ALTER TABLE per aggiungere, eliminare o modificare colonne in una tabella. Affinché l'istruzione venga eseguita correttamente, è necessario disporre dei privilegi ALTER, CREATE e INSERT per la tabella. L'istruzione ha anche alcune sottigliezze uniche a se stessa:le sue prestazioni possono risentirne quando si esegue su tavoli molto grandi a causa del modo in cui funziona, ma finché sai come funziona l'istruzione e cosa fa dovresti andare bene.