TRUNCATE vs. DELETE i SQL: Understanding the Differences

By rik

Utforska hur SQL-kommandona TRUNCATE och DELETE fungerar, vilka skillnader det finns mellan dem och i vilka situationer det är bäst att använda det ena eller det andra.

När man hanterar databastabeller kan det bli nödvändigt att avlägsna antingen vissa specifika rader eller hela tabellens innehåll. För att radera rader i en databastabell kan man använda SQL-kommandona TRUNCATE eller DELETE, beroende på det aktuella behovet.

I den här genomgången ska vi noggrant undersöka varje kommando, förstå deras mekanismer och avgöra när det är mer lämpligt att använda TRUNCATE istället för DELETE, och vice versa.

Innan vi går vidare är det bra att repetera följande SQL-kategorier:

  • Data Definition Language (DDL)-kommandon används för att skapa och hantera databasobjekt, som till exempel tabeller. SQL-kommandona CREATE, DROP och TRUNCATE är exempel på DDL-kommandon.
  • Data Manipulation Language (DML)-kommandon används för att manipulera data i databasobjekt. DML-kommandon används för att utföra operationer som att skapa, läsa, uppdatera och ta bort poster.
  • Data Query Language (DQL)-kommandon används för att hämta data från databastabeller. Alla SELECT-kommandon faller under DQL-kategorin.

Hur man använder SQL TRUNCATE-kommandot

Syntax för SQL TRUNCATE-kommandot

Syntaxen för att använda SQL TRUNCATE-kommandot ser ut så här:

TRUNCATE TABLE tabellnamn;

Att köra TRUNCATE-kommandot ovan raderar samtliga rader i tabellen som specificeras av tabellnamn – själva tabellen tas däremot inte bort.

Trunkeringen skannar inte alla poster i tabellen. Därför är den i allmänhet snabbare när man hanterar stora databastabeller.

SQL TRUNCATE Användningsexempel

📝 Notera: Om du har MySQL installerat på din dator kan du följa med genom att använda MySQL-kommandoradsklienten. Du kan också använda ett annat DBMS som du föredrar, till exempel PostgreSQL.

Låt oss först skapa en databas att arbeta med:

mysql> CREATE DATABASE db1;
Query OK, 1 row affected (1.50 sec)

Välj sedan den databas vi nyss skapade:

mysql> use db1;
Database changed

Nästa steg är att skapa en databastabell. Kör följande CREATE TABLE-kommando för att skapa en enkel uppgiftstabell:

-- Skapa tasks-tabellen
CREATE TABLE tasks (
    task_id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    due_date DATE,
    status ENUM('Pending', 'In Progress', 'Completed') DEFAULT 'Pending',
    assignee VARCHAR(100)
);

I det här exemplet har uppgiftstabellen dessa kolumner:

  • task_id: En automatiskt genererad unik identifierare för varje uppgift.
  • title: Uppgiftens titel eller namn, med en begränsning på 255 tecken.
  • due_date: Uppgiftens förfallodatum, angivet som ett datum.
  • status: Uppgiftens status, som kan vara ”Pending”, ”In Progress” eller ”Completed”. Standardvärdet är inställt på ’Pending’.
  • assignee: Den ansvariga personen för den specifika uppgiften.

Nu när vi har skapat uppgiftstabellen, låt oss lägga in några poster:

-- Infoga flera poster i tasks-tabellen
INSERT INTO tasks (title, due_date, status, assignee)
VALUES
    ('Task 1', '2023-08-10', 'Pending', 'John'),
    ('Task 2', '2023-08-11', 'In Progress', 'Jane'),
    ('Task 3', '2023-08-12', 'Completed', 'Mike'),
    ('Task 4', '2023-08-13', 'Pending', 'Alice'),
    ('Task 5', '2023-08-14', 'In Progress', 'Bob'),
    ('Task 6', '2023-08-15', 'Completed', 'Emily'),
    ('Task 7', '2023-08-16', 'Pending', 'David'),
    ('Task 8', '2023-08-17', 'In Progress', 'Olivia'),
    ('Task 9', '2023-08-18', 'Pending', 'Daniel'),
    ('Task 10', '2023-08-19', 'Completed', 'Sophia'),
    ('Task 11', '2023-08-20', 'Pending', 'Matthew'),
    ('Task 12', '2023-08-21', 'In Progress', 'Ava'),
    ('Task 13', '2023-08-22', 'Completed', 'William'),
    ('Task 14', '2023-08-23', 'Pending', 'Ella'),
    ('Task 15', '2023-08-24', 'In Progress', 'James'),
    ('Task 16', '2023-08-25', 'Completed', 'Lily'),
    ('Task 17', '2023-08-26', 'Pending', 'Benjamin'),
    ('Task 18', '2023-08-27', 'In Progress', 'Mia'),
    ('Task 19', '2023-08-28', 'Pending', 'Henry'),
    ('Task 20', '2023-08-29', 'Completed', 'Isabella');

Efter att du kört insert-kommandot bör du se ett utdata som liknar detta:

Query OK, 20 rows affected (0.18 sec)
Records: 20  Duplicates: 0  Warnings: 0

Kör nu kommandot TRUNCATE TABLE för att ta bort alla poster från uppgiftstabellen:

TRUNCATE TABLE tasks;
Query OK, 0 rows affected (0.72 sec)

Detta tar bort alla poster, men inte tabellen. Du kan bekräfta detta genom att köra SHOW TABLES; så här:

SHOW TABLES;
+---------------+
| Tables_in_db1 |
+---------------+
| tasks         |
+---------------+
1 row in set (0.00 sec)

Och en SELECT-fråga för att hämta data från uppgiftstabellen returnerar ett tomt resultat:

SELECT * FROM tasks;
Empty set (0.00 sec)

Hur man använder SQL DELETE-kommandot

Syntax för SQL DELETE-kommandot

Den grundläggande syntaxen för att använda SQL DELETE-kommandot är som följer:

DELETE FROM tabellnamn 
WHERE villkor;

Villkoret i WHERE-satsen definierar vilka rader som ska raderas. DELETE-kommandot tar bort alla rader där villkoret är sant.

DELETE-kommandot ger dig alltså större kontroll över vilka poster som ska raderas.

Men vad händer om du använder DELETE-kommandot utan en WHERE-sats? 🤔

DELETE FROM tabellnamn;

Att köra DELETE-kommandot på detta sätt tar bort alla rader i databastabellen.

Om ett DELETE-kommando eller en serie DELETE-kommandon är en del av en transaktion som inte har genomförts, kan du återställa ändringarna. Det rekommenderas dock att du säkerhetskopierar din data på annat håll.

SQL DELETE Användningsexempel

Låt oss nu se hur SQL DELETE-kommandot fungerar i praktiken.

Vi har tagit bort alla poster från uppgiftstabellen. Därför kan du köra INSERT-kommandot igen (som vi använde tidigare) för att fylla tabellen med poster:

-- Infoga flera poster i tasks-tabellen
INSERT INTO tasks (title, due_date, status, assignee)
VALUES
    ('Task 1', '2023-08-10', 'Pending', 'John'),
    ('Task 2', '2023-08-11', 'In Progress', 'Jane'),
    ('Task 3', '2023-08-12', 'Completed', 'Mike'),
    ...
    ('Task 18', '2023-08-27', 'In Progress', 'Mia'),
    ('Task 19', '2023-08-28', 'Pending', 'Henry'),
    ('Task 20', '2023-08-29', 'Completed', 'Isabella');

Låt oss först använda DELETE-kommandot med en WHERE-sats. Följande fråga tar bort alla rader där statusen är ”Completed”:

DELETE FROM tasks WHERE status="Completed";
Query OK, 6 rows affected (0.14 sec)

Kör nu denna SELECT-fråga:

SELECT * FROM tasks;

Du kommer att se att det nu finns 14 rader:

+---------+---------+------------+-------------+----------+
| task_id | title   | due_date   | status      | assignee |
+---------+---------+------------+-------------+----------+
|       1 | Task 1  | 2023-08-10 | Pending     | John     |
|       2 | Task 2  | 2023-08-11 | In Progress | Jane     |
|       4 | Task 4  | 2023-08-13 | Pending     | Alice    |
|       5 | Task 5  | 2023-08-14 | In Progress | Bob      |
|       7 | Task 7  | 2023-08-16 | Pending     | David    |
|       8 | Task 8  | 2023-08-17 | In Progress | Olivia   |
|       9 | Task 9  | 2023-08-18 | Pending     | Daniel   |
|      11 | Task 11 | 2023-08-20 | Pending     | Matthew  |
|      12 | Task 12 | 2023-08-21 | In Progress | Ava      |
|      14 | Task 14 | 2023-08-23 | Pending     | Ella     |
|      15 | Task 15 | 2023-08-24 | In Progress | James    |
|      17 | Task 17 | 2023-08-26 | Pending     | Benjamin |
|      18 | Task 18 | 2023-08-27 | In Progress | Mia      |
|      19 | Task 19 | 2023-08-28 | Pending     | Henry    |
+---------+---------+------------+-------------+----------+
14 rows in set (0.00 sec)

Om du kör följande DELETE-kommando raderas alla de 14 återstående posterna i tabellen:

DELETE FROM tasks;
Query OK, 14 rows affected (0.20 sec)

Och uppgiftstabellen är nu tom:

SELECT * FROM tasks;
Empty set (0.00 sec)

SQL DROP-kommandot

Hittills har vi lärt oss att:

  • TRUNCATE-kommandot tar bort alla rader från tabellen.
  • DELETE-kommandot – utan en WHERE-sats – tar bort alla poster från tabellen.

Men TRUNCATE- och DELETE-kommandona tar inte bort tabellen. Om du vill radera tabellen från databasen kan du använda kommandot DROP TABLE på följande sätt:

DROP TABLE tabellnamn;

Låt oss nu ta bort uppgiftstabellen från databasen:

mysql> DROP TABLE tasks;
Query OK, 0 rows affected (0.43 sec)

Du kommer att märka att SHOW TABLES; returnerar ett tomt resultat (eftersom vi har tagit bort den enda tabellen i databasen):

mysql> SHOW TABLES;
Empty set (0.00 sec)

När ska man använda TRUNCATE vs. DELETE i SQL

Funktion TRUNCATE DELETE
Syntax TRUNCATE TABLE tabellnamn; Med WHERE-sats: DELETE FROM tabellnamn WHERE villkor;
Utan WHERE-sats: DELETE TABLE tabellnamn;
SQL Undergrupp Data Definition Language (DDL) Data Manipulation Language (DML)
Effekt Tar bort alla rader i databastabellen. När den körs utan WHERE-satsen raderar DELETE-kommandot alla poster i databastabellen.
Prestanda Mer effektivt än DELETE-kommandot när man hanterar stora tabeller. Mindre effektivt än TRUNCATE-kommandot.

Sammanfattningsvis:

  • När du behöver ta bort alla rader från en stor databastabell ska du använda TRUNCATE-kommandot.
  • För att ta bort en delmängd av rader baserat på specifika villkor ska du använda DELETE-kommandot.

Summering

Låt oss avsluta vår diskussion med en sammanfattning:

  • När du arbetar med databastabeller kan du behöva ta bort en delmängd av rader eller alla rader i en specifik tabell. För att göra det kan du använda kommandona TRUNCATE eller DELETE.
  • TRUNCATE-kommandot har syntaxen: TRUNCATE TABLE tabellnamn;. Det tar bort alla rader i tabellen som specificeras av tabellnamn, men själva tabellen tas inte bort.
  • DELETE-kommandot har syntaxen: DELETE FROM tabellnamn WHERE villkor;. Det tar bort de rader där villkoret är sant.
  • Om du kör SQL DELETE-kommandot utan en WHERE-sats raderas alla rader i tabellen. Funktionellt uppnår detta samma resultat som SQL TRUNCATE-kommandot.
  • Att köra TRUNCATE är i synnerhet snabbare vid hantering av större tabeller, eftersom det inte skannar hela tabellen. Så när du behöver ta bort alla rader i en stor databastabell kan det vara mer effektivt att köra en trunkering.
  • När du behöver ta bort en delmängd av rader – baserat på ett specifikt villkor – kan du använda SQL DELETE-kommandot.

För en snabb genomgång av vanliga SQL-kommandon kan du kolla in den här SQL-fusklistan.