- Med
INSERT IGNORE
- Med
REPLACE
- Med
INSERT ... ON DUPLICATE KEY UPDATE
MySQL tillhandahåller ett antal användbara uttalanden när det är nödvändigt att INSERTED
rader efter avgöra om den raden faktiskt är ny eller redan existerar.
Nedan kommer vi att undersöka de tre olika metoderna och förklara fördelarna och nackdelarna med var och en i tur och ordning så att du har ett fast grepp om hur du konfigurerar dina egna uttalanden när du tillhandahåller nya eller potentiellt befintliga data för INSERTION
.
Använda INSERT IGNORE
Använder INSERT IGNORE
får MySQL att ignorera effektivt exekveringsfel vid försök att utföra INSERTED
uttalanden. Detta betyder att en INSERT IGNORE
sats som innehåller ett dubblettvärde i en UNIQUE
index eller PRIMARY KEY
fältet inte producerar ett fel, men kommer istället helt enkelt att ignorera den specifika INSERTED
kommandot helt och hållet. Det uppenbara syftet är att köra ett stort antal INSERTED
uttalanden för en kombination av data som både redan finns i databasen och nya data som kommer in i systemet.
Till exempel våra books
Tabell kan redan innehålla några poster:
mysql> SELECT * FROM books LIMIT 3;
+----+-------------------------+---------------------+----------------+
| id | title | author | year_published |
+----+-------------------------+---------------------+----------------+
| 1 | In Search of Lost Time | Marcel Proust | 1913 |
| 2 | Ulysses | James Joyce | 1922 |
| 3 | Don Quixote | Miguel de Cervantes | 1605 |
+----+-------------------------+---------------------+----------------+
3 rows in set (0.00 sec)
Om vi har en stor mängd nya och befintliga data att INSERTED
och en del av den datan innehåller ett matchande värde för id
fält (som är en UNIQUE
PRIMARY_KEY
i tabellen), med en grundläggande INSERTED
kommer att ge ett förväntat fel:
mysql> INSERT INTO books
(id, title, author, year_published)
VALUES
(1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
Å andra sidan, om vi använder INSERT IGNORE
, dupliceringsförsöket ignoreras och inga resulterande fel uppstår:
mysql> INSERT IGNORE INTO books
(id, title, author, year_published)
VALUES
(1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
Query OK, 0 rows affected (0.00 sec)
Använda REPLACE
I händelse av att du faktiskt vill byta ut rader där INSERTED
kommandon skulle producera fel på grund av dubbletter av UNIQUE
eller PRIMARY KEY
värden som beskrivs ovan är ett alternativ att välja REPLACE
uttalande.
När du utfärdar en REPLACE
uttalande finns det två möjliga utfall för varje utfärdat kommando:
- Ingen befintlig datarad hittades med matchande värden och därmed en standard
INSERTED
uttalande utförs. - En matchande datarad är hittas, vilket gör att den befintliga raden raderas med standarden
DELETE
sats, sedan en normalINSERTED
utförs efteråt.
Till exempel kan vi använda REPLACE
för att byta ut vår befintliga post med id = 1
av I Search of Lost Time av Marcel Proust med Gröna ägg och skinka av Dr. Seuss:
mysql> REPLACE INTO books
(id, title, author, year_published)
VALUES
(1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
Query OK, 2 rows affected (0.00 sec)
Observera att även om vi bara ändrade en rad, indikerar resultatet att två rader påverkades eftersom vi faktiskt DELETED
den befintliga raden och sedan INSERTED
den nya raden för att ersätta den.
Mer information om hur du använder REPLACE
finns i den officiella dokumentationen.
Använda INSERT ... ON DUPLICATE KEY UPDATE
Den alternativa (och generellt föredragna) metoden för INSERTING
i rader som kan innehålla dubbletter av UNIQUE
eller PRIMARY KEY
värden är att använda INSERT ... ON DUPLICATE KEY UPDATE
uttalande och klausul.
Till skillnad från REPLACE
– ett i sig destruktivt kommando på grund av DELETE
kommandon som den utför när det behövs – med INSERT ... ON DUPLICATE KEY UPDATE
är icke-förstörande , eftersom det bara kommer att utfärda INSERTED
eller UPDATE
uttalanden, men aldrig DELETE
.
Till exempel har vi bestämt att vi vill ersätta vårt id = 1
register över Gröna ägg och skinka och återställ den till originalet In Search of Lost Time spela in istället. Vi kan därför ta vår ursprungliga INSERTED
uttalande och lägg till den nya ON DUPLICATE KEY UPDATE
klausul:
mysql> SET @id = 1,
@title = 'In Search of Lost Time',
@author = 'Marcel Proust',
@year_published = 1913;
INSERT INTO books
(id, title, author, year_published)
VALUES
(@id, @title, @author, @year_published)
ON DUPLICATE KEY UPDATE
title = @title,
author = @author,
year_published = @year_published;
Observera att vi använder normal UPDATE
syntax (men exklusive den onödiga table
namn och SET
nyckelord), och bara tilldelar non-UNIQUE
värden. Även om det är onödigt för ON DUPLICATE KEY UPDATE
metod för att fungera korrekt har vi också valt att använda user variables
så vi behöver inte specificera de faktiska värdena vi vill INSERTED
eller UPDATE
mer än en gång.
Som ett resultat blir vårt id = 1
posten var korrekt UPDATED
som förväntat:
mysql> SELECT * FROM books LIMIT 1;
+----+------------------------+---------------+----------------+
| id | title | author | year_published |
+----+------------------------+---------------+----------------+
| 1 | In Search of Lost Time | Marcel Proust | 1913 |
+----+------------------------+---------------+----------------+
1 row in set (0.00 sec)
Mer information finns i den officiella dokumentationen.