sql >> Databasteknik >  >> RDS >> Mysql

ALTER TABLE i MySQL:Vän eller fiende?

ALTER TABLE-satsen är en av de mest använda satserna i MySQL-världen - satsen låter dig lägga till, ta bort eller ändra kolumner i en tabell. I det här blogginlägget kommer vi att försöka titta djupare på vad det är, vad det gör och när det ska användas.

Vad är ALTER TABLE och vad gör den?

Som redan nämnts ovan gör ALTER TABLE-satsen det möjligt för DBA:er och utvecklare att lägga till, ta bort eller ändra kolumner i en tabell. Enkelt uttryckt ALTER TABLE ändrar strukturen för en tabell - den låter dig lägga till, ta bort kolumner, lägga till eller ta bort index, byta namn på kolumner eller ändra deras typ.

När och hur använder jag ALTER TABLE?

För att använda ALTER TABLE behöver du i allmänhet ALTER-, CREATE- och INSERT-behörigheterna. För att byta namn på en tabell krävs privilegier ALTER och DROP för den gamla tabellen, sedan CREATE, ALTER och INSERT privilegier för den nya tabellen som ska skapas. För att tilldela de nödvändiga rättigheterna till en viss användare kan du använda följande fråga:

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

Ersätt databas med ditt databasnamn, jokertecknet med tabellnamnet om du vill att behörigheterna endast ska gälla för vissa tabeller (jokertecknet gör att behörigheten gäller för alla tabeller) och demo_user med namnet på din användare. Om du vill att privilegierna ska användas över alla databaser och alla tabeller i dem, ersätt helt enkelt databasen med ett jokertecken:

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

För att faktiskt använda ALTER TABLE-satsen, kör en fråga som ändrar strukturen i en tabell - ALTER TABLE används för att lägga till, ta bort eller ändra kolumner i en tabell:frågan kan också användas för att lägga till index i kolumner. Här är några grundläggande exempel på vanligast använda frågor:

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

hans fråga skulle lägga till en kolumn kolumnnamn till en tabell demo_table. Lägg till FIRST i slutet av frågan för att göra kolumnen till den första kolumnen i tabellen.

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

hans fråga skulle lägga till en kolumn column_2 efter kolumnen column_1 i en tabell demo_table.

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

Denna fråga skulle lägga till en genererad kolumn i tabellen.

ALTER TABLE demo_table DROP COLUMN demo_column; 

Denna fråga skulle ta bort kolumnen demo_column i en tabell demo_table.

ALTER TABLE demo_table ADD INDEX demo_index(demo_column); 

Denna fråga skulle lägga till ett index med namnet demo_index (namn kan väljas) på en kolumn som heter demo_column i en tabell som heter demo_table.

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

Denna fråga skulle lägga till ett index på en kolumn demo_column och ett unikt index på kolumnen demo_unique.

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

Denna fråga skulle ändra standardteckenuppsättningen för en specifik kolumn.

ALTER TABLE demo_table CONVERT TO CHARACTER SET charset_name; 

Denna fråga skulle ändra standardteckenuppsättningen för tabellen och alla tecken (CHAR, VARCHAR och TEXT) kolumner.

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

Denna fråga skulle partitionera kolumnen demo_column i 8 partitioner med hash.

ALTER TABLE demo_table TABLESPACE tablespace_1 STORAGE DISK; 

Denna fråga skulle konvertera tabellen demo_table till diskbaserad lagring.

Om du lägger till index, kom ihåg att du kan lägga till olika typer av index (till exempel ett BTREE-index eller ett FULLTEXT-index), du kan också lägga till ett index som bara täcker en viss mängd tecken i en kolumn med en fråga som så:

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

Frågan ovan skulle lägga till ett index som heter demo_index på de första 10 tecknen i kolumnen som heter kolumnnamn i en tabell som heter demo_table.

Index i MySQL är en komplex best och de förtjänar verkligen ett eget ämne så vi kommer inte gå in på detaljer här, men om du vill lära dig mer bör vårt tidigare inlägg om MySQL-index ge några mer insikt.

Hur fungerar ALTER TABLE?

ALTER TABLE i MySQL har sina egna finesser. Från och med den senaste versionen av MySQL, dvs MySQL 8.0. Det finns 3 algoritmer som påverkar hur ALTER TABLE presterar för sådana ändringar. Dessa är:

  • KOPIERA

    • Åtgärder utförs på en kopia av den ursprungliga tabellen, och tabelldata kopieras från den ursprungliga tabellen till den nya tabellen rad för rad. I de flesta fall kan denna algoritm vara mycket dyr när det gäller resursanvändning, särskilt för stora och stora bord. När denna algoritm väljs eller väljs är all samtidig DML inte tillåten så därför måste alla efterföljande frågor som refererar till den berörda tabellen vänta eller köa in i processlistan. Chansen är stor att din databas fastnar om anslutningarna är maxade.

  • INPLACERA

    • Operationer undviker att kopiera tabelldata men kan bygga om tabellen på plats. Ett exklusivt metadatalås på bordet kan tas kort under förberedelse- och exekveringsfasen av operationen. Vanligtvis stöds samtidig DML.

  • Omedelbar

    • Operationer ändrar endast metadata i dataordlistan. Inga exklusiva metadatalås tas på bordet under förberedelse och körning, och tabelldata påverkas inte, vilket gör operationer omedelbara. Samtidig DML är tillåten. (Introduceras i MySQL 8.0.12)

MySQL:s ALTER TABLE-process kanske inte är ett problem med mindre tabeller, men om din datauppsättning är större kan du stöta på problem - många människor har upplevt ALTER TABLE-frågor som har tagit timmar, dagar eller till och med veckor att slutföra. I de flesta fall händer det på grund av MySQL:s tabelländringsprocess som beskrivs ovan. Det finns dock ett sätt att åtminstone något minska tiden det tar att slutföra frågan:

  1. Skapa en ny tabell som din källtabell med önskad struktur genom att köra
    CREATE TABLE demo_table_new LIKE demo_table;
    sedan justera dess struktur. I det här fallet är demo_table källtabellen och demo_table_new är den nya tabellen.
  2. Infoga data i den nya tabellen.
  3. Byt namn på den gamla tabellen till demo_table_old (justera namnet efter dina behov).
  4. Byt namn på den nya tabellen till det tidigare namnet på den gamla tabellen.
  5. Kopiera slutligen raderna från den gamla tabellen till den nya tabellen och skapa index om det behövs.

Även om stegen ovan fungerar bra. Ändå, i verkliga scenarier, använder DBA:er eller utvecklare att använda Perconas pt-online-schema-change eller att använda Githubs gh-ost. Du kan ta en titt på vårt tidigare inlägg Top Open Source Tools for MySQL &MariaDB Migrations som tar en översikt över dessa schemaändringsverktyg.

Hur som helst, det vi har beskrivit ovan är ofta känt som "skuggkopieringsmetoden":i huvudsak bygger du en ny tabell med den önskade strukturen, utför sedan ett namnbyte och släpp för att byta de två tabellerna . Det finns också ett annat sätt:du kan också byta runt servrar och köra ALTER TABLE på servrar som inte är i produktion. För MyISAM kan du INAKTIVERA NYCKLAR, ladda data och sedan AKTIVERA NYCKEL.

ÄNDRA TABELL Fått

Om du använder ALTER TABLE-satsen för att skapa index (du kan också använda CREATE INDEX-satsen), rekommenderas det att skapa index efter att du har infogat data eftersom det är ett ganska välkänt sätt att snabba upp bearbetning inte bara i MySQL, utan även i andra databashanteringssystem, såsom Oracle. Men i allmänhet, kom ihåg att de flesta ALTER TABLE-operationer bör förväntas orsaka vissa problem (avbrott i tjänsten) för MySQL.

Det finns också ett annat sätt att påskynda hela processen, även om det är lite mer avancerat:om du kan övertyga MySQL att endast modifiera tabellens .frm-fil (.frm-filer beskriver definitionen av bordet) och lämna bordet ifred, processen blir snabbare:

  1. Skapa en tom tabell med samma layout som den gamla tabellen utan att ändra den.
  2. Stäng alla tabeller som används och förhindra att alla nya tabeller öppnas genom att köra 
    FLUSH TABLES WITH READ LOCK.
  3. Byt ut .frm-filerna.
  4. Släpp läslåset genom att köra UNLOCK TABLES.

Tänk också på att om du vill ändra en kolumn och syntaxen verkar korrekt men du fortfarande får ett fel, kan det vara dags att titta på en annan syntax. Till exempel:

ALTER TABLE demo_table ADD long VARCHAR(255); 

En fråga som denna skulle felas eftersom lång är ett reserverat ord. För att undvika ett sådant fel, undvik ordet med backticks:

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

Det är också värt att notera att kolumnnamnen endast kan escapes med backtick och inte med enkla citattecken eller dubbla citattecken. Till exempel, en fråga som den här skulle också felas:

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

Sammanfattning

MySQL använder ALTER TABLE-satsen för att lägga till, ta bort eller ändra kolumner i en tabell. För att satsen ska kunna köras framgångsrikt måste du ha behörigheterna ALTER, CREATE och INSERT för tabellen. Uttalandet har också några finesser som är unika för sig självt:dess prestanda kan bli lidande när den körs på mycket stora bord på grund av hur det fungerar, men så länge du vet hur uttalandet fungerar och vad det gör borde det gå bra.


  1. MySQL Group av SUM

  2. Skapa en CHECK-begränsning i SQLite

  3. En rapports egenskaper

  4. hur ersätter den accentuerade bokstaven i en varchar2-kolumn i Oracle