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

ÆNDRINGSTABEL i MySQL:Ven eller fjende?

ALTER TABLE-sætningen er en af ​​de mest brugte sætninger i MySQL-verdenen - sætningen giver dig mulighed for at tilføje, slette eller ændre kolonner i en tabel. I dette blogindlæg vil vi forsøge at se dybere ind i, hvad det er, hvad det gør, og hvornår skal det bruges.

Hvad er ALTER TABLE, og hvad gør den?

Som allerede nævnt ovenfor, gør ALTER TABLE-sætningen det muligt for DBA'er og udviklere at tilføje, slette eller ændre kolonner i en tabel. Simpelthen ændrer ALTER TABLE strukturen af ​​en tabel - den giver dig mulighed for at tilføje, slette kolonner, tilføje eller fjerne indekser, omdøbe kolonner eller ændre deres type.

Hvornår og hvordan bruger jeg ALTER TABLE?

For at bruge ALTER TABLE har du generelt brug for rettighederne ALTER, CREATE og INSERT. For at omdøbe en tabel er de nødvendige privilegier ALTER og DROP for den gamle tabel, derefter CREATE, ALTER og INSERT privilegier for den nye tabel, der skal oprettes. For at tildele de nødvendige rettigheder til en bestemt bruger, kan du bruge følgende forespørgsel:

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

Erstat databasen med dit databasenavn, jokertegnet med tabelnavnet, hvis du ønsker, at privilegierne kun skal gælde for bestemte tabeller (jokertegnet gør privilegiet gældende på tværs af alle tabeller) og demo_user med navnet på din bruger. Hvis du ønsker, at privilegierne skal bruges på tværs af alle databaser og alle tabeller i dem, skal du blot erstatte databasen med et jokertegn:

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

For faktisk at gøre brug af ALTER TABLE-sætningen skal du køre en forespørgsel, der ændrer strukturen i en tabel - ALTER TABLE bruges til at tilføje, slette eller ændre kolonner i en tabel:forespørgslen kan også bruges til at tilføje indekser til kolonner. Her er et par grundlæggende eksempler på oftest brugte forespørgsler:

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

hans forespørgsel ville tilføje en kolonne kolonnenavn til en tabel demo_tabel. Tilføj FIRST til slutningen af ​​forespørgslen for at gøre kolonnen til den første kolonne i tabellen.

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

hans forespørgsel ville tilføje en kolonne column_2 efter kolonnen column_1 på en tabel demo_table.

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

Denne forespørgsel ville tilføje en genereret kolonne til tabellen.

ALTER TABLE demo_table DROP COLUMN demo_column; 

Denne forespørgsel ville droppe kolonnen demo_column på en tabel demo_table.

ALTER TABLE demo_table ADD INDEX demo_index(demo_column); 

Denne forespørgsel ville tilføje et indeks med navnet demo_index (navne kan vælges) på en kolonne kaldet demo_column i en tabel kaldet demo_table.

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

Denne forespørgsel ville tilføje et indeks på en kolonne demo_column og et unikt indeks på demo_unique kolonnen.

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

Denne forespørgsel ville ændre standardtegnsættet for en specifik kolonne.

ALTER TABLE demo_table CONVERT TO CHARACTER SET charset_name; 

Denne forespørgsel ville ændre standardtegnsættet for tabellen og alle tegnkolonner (CHAR, VARCHAR og TEXT).

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

Denne forespørgsel vil opdele kolonnen demo_column i 8 partitioner med hash.

ALTER TABLE demo_table TABLESPACE tablespace_1 STORAGE DISK; 

Denne forespørgsel ville konvertere tabellen demo_table til disk-baseret lager.

Hvis du tilføjer indekser, skal du huske på, at du kan tilføje forskellige typer indekser (f.eks. et BTREE-indeks eller et FULLTEXT-indeks), du kan også tilføje et indeks, der kun dækker en vis mængde af tegn i en kolonne med en forespørgsel som sådan:

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

Ovenstående forespørgsel ville tilføje et indeks kaldet demo_index på de første 10 tegn i kolonnen kaldet kolonnenavn i en tabel kaldet demo_table.

Indekser i MySQL er et komplekst dyr, og de fortjener virkelig et eget emne, så vi vil ikke gå i detaljer her, men hvis du vil lære mere, burde vores tidligere indlæg om MySQL-indekser give nogle mere indsigt.

Hvordan virker ALTER TABLE?

ALTER TABLE i MySQL har sine egne finesser. Fra den seneste version af MySQL, dvs. MySQL 8.0. Der er 3 algoritmer, som påvirker, hvordan ALTERTABELLEN yder for sådanne ændringer. Disse er:

  • KOPI

    • Operationer udføres på en kopi af den originale tabel, og tabeldata kopieres fra den originale tabel til den nye tabel række for række. I de fleste tilfælde kan denne algoritme være meget dyr med hensyn til ressourceforbrug, især for store og store borde. Når denne algoritme er valgt eller valgt, er al samtidig DML ikke tilladt, så derfor skal alle efterfølgende forespørgsler, der refererer til den berørte tabel, vente eller stå i kø på proceslisten. Chancerne er, at du vil få din database til at hænge fast, hvis forbindelserne er maks.

  • INPLACER

    • Operationer undgår at kopiere tabeldata, men kan genopbygge tabellen på plads. En eksklusiv metadatalås på bordet kan tages kort under forberedelses- og udførelsesfaserne af operationen. Typisk understøttes samtidig DML.

  • ØJEBLIKKELIG

    • Operationer ændrer kun metadata i dataordbogen. Der tages ingen eksklusive metadatalåse på bordet under forberedelse og udførelse, og tabeldata er upåvirket, hvilket gør operationer øjeblikkelige. Samtidig DML er tilladt. (Introduceret i MySQL 8.0.12)

MySQL's ALTER TABLE-proces er muligvis ikke et problem med mindre tabeller, men hvis dit datasæt er større, kan du løbe ind i problemer - mange mennesker har oplevet ALTER TABLE-forespørgsler, der har taget timer, dage eller endda uger at færdiggøre. I de fleste tilfælde sker det på grund af MySQLs tabelændringsproces beskrevet ovenfor. Der er dog en måde at i det mindste en smule reducere den tid, det tager at gennemføre forespørgslen:

  1. Opret en ny tabel som din kildetabel med din ønskede struktur ved at køre
    CREATE TABLE demo_table_new LIKE demo_table;
    derefter justere dens struktur. I dette tilfælde er demo_table kildetabellen og demo_table_new er den nye tabel.
  2. Indsæt data i den nye tabel.
  3. Omdøb den gamle tabel til demo_table_old (tilpas navnet efter dine behov).
  4. Omdøb den nye tabel til det tidligere navn på den gamle tabel.
  5. Kopier til sidst rækkerne fra den gamle tabel til den nye tabel, og opret om nødvendigt indekser.

Selvom ovenstående trin fungerer fint. Alligevel, i virkelige scenarier, tager DBA'er eller udviklere det magre at bruge Perconas pt-online-schema-change eller bruge Github's gh-ost. Du kan tage et kig på vores tidligere indlæg Top Open Source-værktøjer til MySQL &MariaDB-migrering, som giver et overblik over disse skemaændringsværktøjer.

I hvert fald, det, vi har beskrevet ovenfor, er ofte kendt som "skyggekopi"-tilgangen:i bund og grund bygger du en ny tabel med den ønskede struktur, udfører derefter et omdøb og slip for at bytte de to tabeller . Der er også en anden måde:du kan også bytte rundt på servere og køre ALTER TABLE på servere, der ikke er i produktion. For MyISAM kan du DEAKTIVERE NØGLER, indlæse data og derefter AKTIVERE NØGLER.

ALTER TABLE Gotchas

Hvis du bruger ALTER TABLE-sætningen til at oprette indekser (du kan også bruge CREATE INDEX-sætningen), anbefales det at oprette indekser efter at have indsat dataene, fordi det er en ret velkendt måde at fremskynde behandling ikke kun i MySQL, men også i andre databasestyringssystemer, såsom Oracle. Generelt skal du dog huske på, at de fleste ALTER TABLE-operationer forventes at forårsage nogle problemer (afbrydelse af tjenesten) til MySQL.

Der er også en anden måde at fremskynde hele processen på, selvom den er en smule mere avanceret:hvis du kan overbevise MySQL om kun at ændre tabellens .frm-fil (.frm-filer beskriver definitionen af bordet) og lad bordet være, vil processen være hurtigere:

  1. Opret en tom tabel med samme layout som den gamle tabel uden at ændre den.
  2. Luk alle tabeller i brug, og forhindre alle nye tabeller i at blive åbnet ved at køre 
    FLUSH TABLES WITH READ LOCK.
  3. Skift .frm-filerne.
  4. Slip læselåsen ved at køre UNLOCK TABLES.

Husk også, at hvis du vil ændre en kolonne, og syntaksen virker korrekt, men du stadig får en fejl, kan det være på tide at undersøge en anden syntaks. For eksempel:

ALTER TABLE demo_table ADD long VARCHAR(255); 

En forespørgsel som denne ville fejle, fordi lang er et reserveret ord. For at undgå en sådan fejl skal du undslippe ordet med backticks:

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

Det er også værd at bemærke, at kolonnenavnene kun kan escapes ved at bruge backticks og ikke med enkelte anførselstegn eller dobbelte anførselstegn. For eksempel ville en forespørgsel som sådan også fejle:

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

Oversigt

MySQL bruger ALTER TABLE-sætningen til at tilføje, slette eller ændre kolonner i en tabel. For at sætningen kan udføres korrekt, skal du have rettighederne ALTER,CREATE og INSERT for tabellen. Udsagnet har også et par finesser, der er unikke for sig selv:dets ydeevne kan lide, når det kører på meget store borde på grund af den måde, det fungerer på, men så længe du ved, hvordan udsagnet fungerer, og hvad det gør, burde du have det fint.


  1. Sådan får du alle fejl i alle SSIS-pakker i en løsning

  2. mysql-lignende præstationsboost

  3. Returner standardresultat for IN-værdi uanset

  4. Begrænsning defineret UDSKYLDIG Umiddelbart er stadig UDSAT?