sql >> Database >  >> RDS >> Mysql

ALTER TABLE in MySQL:vriend of vijand?

De ALTER TABLE-instructie is een van de meest gebruikte instructies in de MySQL-wereld - met de instructie kunt u kolommen in een tabel toevoegen, verwijderen of wijzigen. In deze blogpost gaan we dieper in op wat het is, wat het doet en wanneer het moet worden gebruikt.

Wat is ALTER TABLE en wat doet het?

Zoals hierboven al vermeld, stelt de ALTER TABLE-instructie DBA's en ontwikkelaars in staat om kolommen in een tabel toe te voegen, te verwijderen of te wijzigen. Simpel gezegd:ALTER TABLE verandert de structuur van een tabel - het stelt u in staat kolommen toe te voegen, te verwijderen, indexen toe te voegen of te verwijderen, de naam van kolommen te wijzigen of hun type te wijzigen.

Wanneer en hoe gebruik ik ALTER TABLE?

Om ALTER TABLE te gebruiken heb je over het algemeen de ALTER, CREATE en INSERT privileges nodig. Voor het hernoemen van een tabel zijn de vereiste bevoegdheden ALTER en DROP voor de oude tabel, en vervolgens de bevoegdheden CREATE, ALTER en INSERT voor de nieuwe tabel die moet worden gemaakt. Om de vereiste rechten aan een bepaalde gebruiker toe te kennen, kunt u de volgende vraag gebruiken:

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

Vervang database door uw databasenaam, het jokerteken door de tabelnaam als u wilt dat de privileges alleen van toepassing zijn op bepaalde tabellen (de wildcard maakt het privilege van toepassing op alle tabellen) en demo_user door de naam van uw gebruiker. Als u wilt dat de privileges worden gebruikt voor alle databases en alle tabellen erin, vervangt u de database eenvoudig door een jokerteken:

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

Om daadwerkelijk gebruik te maken van de ALTER TABLE-instructie, voert u een query uit die de structuur van een tabel verandert - ALTER TABLE wordt gebruikt om kolommen in een tabel toe te voegen, te verwijderen of te wijzigen:de query kan ook worden gebruikt om indexen aan kolommen toe te voegen. Hier zijn een paar basisvoorbeelden van de meest gebruikte zoekopdrachten:

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

zijn zoekopdracht zou een kolom column_name toevoegen aan een tabel demo_table. Voeg FIRST toe aan het einde van de zoekopdracht om van de kolom de eerste kolom in de tabel te maken.

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

zijn zoekopdracht zou een kolom column_2 toevoegen na de kolom column_1 op een tabel demo_table.

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

Deze zoekopdracht zou een gegenereerde kolom aan de tabel toevoegen.

ALTER TABLE demo_table DROP COLUMN demo_column; 

Deze zoekopdracht zou de kolom demo_column op een tabel demo_table laten vallen.

ALTER TABLE demo_table ADD INDEX demo_index(demo_column); 

Deze zoekopdracht zou een index met de naam demo_index (namen kunnen worden gekozen) toevoegen aan een kolom met de naam demo_column in een tabel met de naam demo_table.

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

Deze zoekopdracht zou een index toevoegen aan een kolom demo_column en een unieke index aan de demo_unique kolom.

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

Deze zoekopdracht zou de standaardtekenset van een specifieke kolom veranderen.

ALTER TABLE demo_table CONVERT TO CHARACTER SET charset_name; 

Deze zoekopdracht zou de standaardtekenset van de tabel en alle tekenkolommen (CHAR, VARCHAR en TEXT) wijzigen.

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

Deze query zou de kolom demo_column op hash in 8 partities verdelen.

ALTER TABLE demo_table TABLESPACE tablespace_1 STORAGE DISK; 

Deze query zou de tabel demo_table converteren naar schijfgebaseerde opslag.

Als je indexen toevoegt, houd er dan rekening mee dat je verschillende soorten indexen kunt toevoegen (bijvoorbeeld een BTREE-index of een FULLTEXT-index), je kunt ook een index toevoegen die slechts een bepaald aantal dekt tekens in een kolom met een zoekopdracht als volgt:

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

De bovenstaande zoekopdracht zou een index met de naam demo_index toevoegen aan de eerste 10 tekens van de kolom met de naam column_name in een tabel met de naam demo_table.

Indexen in MySQL zijn een complex beest en ze verdienen echt een eigen onderwerp, dus we zullen hier niet in details treden, maar als je meer wilt weten, zou ons eerdere bericht over MySQL-indexen wat moeten bieden meer inzicht.

Hoe werkt ALTER TABLE?

ALTER TABLE in MySQL heeft zijn eigen subtiliteiten. Vanaf de meest recente versie van MySQL, d.w.z. MySQL 8.0. Er zijn 3 algoritmen die van invloed zijn op hoe de ALTER TABLE presteert voor dergelijke wijzigingen. Dit zijn:

  • KOPIE

    • Bewerkingen worden uitgevoerd op een kopie van de originele tabel en tabelgegevens worden rij voor rij van de oorspronkelijke tabel naar de nieuwe tabel gekopieerd. In de meeste gevallen kan dit algoritme erg duur zijn in termen van resourcegebruik, vooral voor grote en grote tabellen. Wanneer dit algoritme wordt gekozen of geselecteerd, is alle gelijktijdige DML niet toegestaan, dus elke volgende query die naar de betreffende tabel verwijst, moet wachten of in de wachtrij worden geplaatst in de proceslijst. De kans is groot dat je database vastloopt als de verbindingen maximaal zijn.

  • PLAATSEN

    • Bewerkingen vermijden het kopiëren van tabelgegevens, maar kunnen de tabel op zijn plaats opnieuw opbouwen. Tijdens de voorbereidings- en uitvoeringsfasen van de operatie kan een exclusief metadataslot op de tafel kort worden genomen. Doorgaans wordt gelijktijdige DML ondersteund.

  • DIRECT

    • Bewerkingen wijzigen alleen metadata in de datadictionary. Er worden geen exclusieve metadatavergrendelingen op de tafel genomen tijdens voorbereiding en uitvoering, en tabelgegevens worden niet beïnvloed, waardoor bewerkingen onmiddellijk worden uitgevoerd. Gelijktijdige DML is toegestaan. (Geïntroduceerd in MySQL 8.0.12)

MySQL's ALTER TABLE-proces is misschien geen probleem met kleinere tabellen, maar als uw dataset groter is, kunt u problemen tegenkomen - veel mensen hebben ALTER TABLE-query's ervaren die uren, dagen of zelfs weken hebben geduurd vervolledigen. In de meeste gevallen gebeurt dat vanwege het hierboven beschreven proces voor het wijzigen van tabellen van MySQL. Er is echter een manier om de tijd die nodig is om de zoekopdracht te voltooien op zijn minst enigszins te verkorten:

  1. Maak een nieuwe tabel zoals uw brontabel met de gewenste structuur door
    CREATE TABLE demo_table_new LIKE demo_table;
    vervolgens de structuur aanpassen. In dit geval is de demo_table de brontabel en demo_table_new is de nieuwe tabel.
  2. Gegevens invoegen in de nieuwe tabel.
  3. Hernoem de oude tabel naar demo_table_old (pas de naam aan volgens uw behoeften).
  4. Hernoem de nieuwe tafel naar de oude naam van de oude tafel.
  5. Kopieer tot slot de rijen van de oude tabel naar de nieuwe tabel en maak, indien nodig, indexen.

Hoewel de bovenstaande stappen prima werken. Maar in reële scenario's nemen DBA's of ontwikkelaars de neiging om Percona's pt-online-schema-change of Github's gh-ost te gebruiken. U kunt onze vorige post Top Open Source-tools voor MySQL- en MariaDB-migraties bekijken, waarin een overzicht wordt gegeven van deze hulpprogramma's voor het wijzigen van schema's.

Hoe dan ook, wat we hierboven hebben beschreven, staat vaak bekend als de "schaduwkopie"-benadering:in wezen bouwt u een nieuwe tabel met de gewenste structuur, voert u een hernoeming uit en laat u deze vallen om de twee tabellen te verwisselen . Er is ook een andere manier:je kunt ook servers verwisselen en ALTER TABLE draaien op servers die niet in productie zijn. Voor MyISAM kunt u SLEUTELS UITSCHAKELEN, gegevens laden en vervolgens SLEUTELS INSCHAKELEN.

WIJZIG TABEL Gotchas

Als je het ALTER TABLE-statement gebruikt om indexen te maken (je kunt ook het CREATE INDEX-statement gebruiken), is het aan te raden om indexen te maken na het invoegen van de gegevens, want dat is een vrij bekende manier van versnellen. verwerking niet alleen in MySQL, maar ook in andere databasebeheersystemen, zoals Oracle. Houd er echter in het algemeen rekening mee dat de meeste ALTER TABLE-bewerkingen naar verwachting enkele problemen (onderbreking van de service) voor MySQL zullen veroorzaken.

Er is echter ook een andere manier om het hele proces te versnellen, zij het iets geavanceerder:als je MySQL kunt overtuigen om alleen het .frm-bestand van de tabel aan te passen (.frm-bestanden beschrijven de definitie van de tafel) en laat de tafel met rust, het proces zal sneller zijn:

  1. Maak een lege tabel met dezelfde lay-out als de oude tabel zonder deze aan te passen.
  2. Sluit alle tabellen die in gebruik zijn en voorkom dat alle nieuwe tabellen worden geopend door 
    FLUSH TABLES WITH READ LOCK.
  3. Verwissel de .frm-bestanden.
  4. Ontgrendel de leesvergrendeling door UNLOCK TABLES uit te voeren.

Houd er ook rekening mee dat als je een kolom wilt wijzigen en de syntaxis correct lijkt, maar je nog steeds een foutmelding krijgt, het misschien tijd is om naar een andere syntaxis te kijken. Bijvoorbeeld:

ALTER TABLE demo_table ADD long VARCHAR(255); 

Een zoekopdracht als deze zou fouten opleveren omdat lang een gereserveerd woord is. Om een ​​dergelijke fout te voorkomen, ontsnap je aan het woord met backticks:

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

Het is ook vermeldenswaard dat de kolomnamen alleen kunnen worden escaped met backticks en niet met enkele aanhalingstekens of dubbele aanhalingstekens. Een zoekopdracht als zo zou bijvoorbeeld ook een fout opleveren:

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

Samenvatting

MySQL gebruikt de instructie ALTER TABLE om kolommen in een tabel toe te voegen, te verwijderen of te wijzigen. Om de instructie met succes uit te voeren, moet u de machtigingen ALTER, CREATE en INSERT voor de tabel hebben. De verklaring heeft ook een paar subtiliteiten die uniek zijn voor zichzelf:de prestaties kunnen eronder lijden wanneer ze op zeer grote tabellen worden uitgevoerd vanwege de manier waarop ze werkt, maar zolang je weet hoe de verklaring werkt en wat het doet, zou het goed moeten komen.


  1. Python psycopg2 wordt niet ingevoegd in postgresql-tabel

  2. Een blik op de Oracle Group-by Bug

  3. Relationeel databasebeheersysteem (RDBMS):MSSQL versus MySQL

  4. Een emotieloze, logische kijk op de naamgevingsconventies van SQL Server