Usuwanie to nie tylko funkcja, to prawdziwa sztuka! Ważne, żeby usunąć dokładnie to, co trzeba, i nie wywalić nic więcej (przypadkowo skasowane dane mogą ci się śnić po nocach). Dzisiaj nauczymy się robić to porządnie i według zasad!
Usuwanie danych to proces wyrzucania jednego lub kilku wierszy z tabeli, które już nie pasują do logiki biznesowej albo wymagań twojego systemu. Na przykład, musisz usunąć rekordy o studentach, którzy skończyli studia albo poważnie, hmm, złamali zasady uczelni. Albo, powiedzmy, chcesz wyczyścić dane w tabeli, żeby zostawić tylko aktualne info.
Operacja usuwania danych przydaje się w takich sytuacjach:
- Usuwanie danych o użytkownikach, którzy już nie są aktywni.
- Czyszczenie tabel z tymczasowych rekordów.
- Usuwanie duplikatów danych.
- Kasowanie starych rekordów zgodnie z określoną logiką biznesową.
Składnia komendy DELETE
Do usuwania danych używamy komendy DELETE. Oto jej podstawowa składnia:
DELETE FROM tabela
WHERE warunek;
Główne elementy:
DELETE FROM— kluczowa fraza, która mówi, że trzeba usunąć wiersze z tabeli.- tabela — nazwa tabeli, z której chcesz wywalić dane.
WHERE warunek— warunek filtrowania wierszy do usunięcia. Możesz tu użyć dowolnych operatorów porównania, operatorów logicznych (AND,OR,NOT) i nawet subzapytania.
Przykład: wyobraź sobie, że mamy tabelę students i chcemy usunąć z niej studenta z ID = 5:
DELETE FROM students
WHERE id = 5;
To zapytanie usunie wiersz z tabeli students, gdzie identyfikator studenta (kolumna id) to 5.
Uwaga: jeśli zapomnisz dodać warunek WHERE, PostgreSQL usunie wszystkie wiersze z tabeli. Taki błąd może być katastrofalny, zwłaszcza jeśli chodzi o produkcję.
Usuwanie wszystkich wierszy z tabeli
Jeśli chcesz wywalić wszystkie wiersze z tabeli, możesz napisać zapytanie bez warunku WHERE. Na przykład:
DELETE FROM students;
To zapytanie usunie wszystkie rekordy z tabeli students. Ale struktura tabeli zostaje — po prostu będzie pusta.
Alternatywa: TRUNCATE
Do usuwania wszystkich wierszy z tabeli możesz też użyć komendy TRUNCATE. Jest szybsza niż DELETE, bo nie zapisuje każdego usunięcia w dzienniku transakcji. Przykład:
TRUNCATE TABLE students;
Różnice DELETE vs TRUNCATE:
DELETEzapisuje każde usunięcie w dzienniku transakcji, więc można je cofnąć, jeśli trzeba.TRUNCATEnie obsługuje warunków (WHERE) i nie zapisuje każdego usunięcia osobno, więc jest szybszy, ale mniej elastyczny.
Jeśli chcesz po prostu wyczyścić tabelę, TRUNCATE to świetny wybór. Ale jeśli zależy ci na usunięciu tylko części danych albo chcesz mieć możliwość cofnięcia zmian, lepiej użyć DELETE.
Usuwanie danych według złożonych warunków
Warunki usuwania w DELETE mogą być nie tylko proste, ale też złożone, z operatorami logicznymi (AND, OR, NOT) albo nawet subzapytaniami. Zobaczmy przykład.
Przykład 1: Usuwanie kilku rekordów Usuńmy wszystkich studentów, którzy mają więcej niż 30 lat i nie byli na zajęciach przez ostatnie 3 miesiące:
DELETE FROM students
WHERE age > 30 AND last_attendance_date < (CURRENT_DATE - INTERVAL '3 months');
To zapytanie usunie tylko tych studentów, którzy spełniają oba warunki naraz.
Przykład 2: Usuwanie z użyciem subzapytania
Załóżmy, że mamy tabelę failed_students, gdzie trzymamy identyfikatory studentów wyrzuconych za brak postępów. Musimy ich usunąć z głównej tabeli students:
DELETE FROM students
WHERE id IN (SELECT student_id FROM failed_students);
Tutaj subzapytanie zwraca wszystkie identyfikatory studentów z tabeli failed_students, a komenda DELETE usuwa odpowiednie wiersze z tabeli students.
Rekomendacja
Zanim coś usuniesz, napisz SELECT, który pokaże dane, które chcesz wywalić. Potem po prostu zamień SELECT na DELETE i usuniesz dokładnie te same wiersze, które przed chwilą widziałeś.
Przykład praktyczny
Wyobraź sobie, że student z ID = 7 postanowił zmienić uczelnię. Usuńmy wszystkie dane o nim z naszej tabeli:
DELETE FROM students
WHERE id = 7;
Sprawdź tabelę po wykonaniu komendy, żeby upewnić się, że rekord faktycznie zniknął:
SELECT * FROM students WHERE id = 7;
Jeśli nie ma już rekordów z ID = 7, operacja usuwania się udała.
Ostrzeżenia i typowe błędy
Zapomniana sekcja WHERE
Jednym z najczęstszych błędów przy pracy z DELETE jest pominięcie sekcji WHERE. To prowadzi do usunięcia wszystkich wierszy z tabeli, co może być prawdziwą katastrofą. Zawsze sprawdzaj swoje zapytania przed ich odpaleniem.
Przykład sytuacji przez nieuwagę:
DELETE FROM students;
-- Błąd! Usunięcie wszystkich studentów.
Żeby uniknąć takich wpadek, zaleca się przed wykonaniem DELETE zawsze przetestować warunek WHERE za pomocą SELECT. Na przykład:
SELECT * FROM students WHERE id = 5;
Jeśli wynik ci pasuje, możesz spokojnie odpalać DELETE.
Usuwanie powiązanych danych
Jeśli tabela ma klucze obce (FOREIGN KEY), przy usuwaniu danych może pojawić się błąd. Dzieje się tak, jeśli usuwany wiersz jest powiązany z innymi rekordami. Na przykład, jeśli student jest zapisany na kurs w tabeli enrollments, PostgreSQL nie pozwoli ci go usunąć z tabeli students.
Jak rozwiązać ten problem?
- Użyć kaskadowego usuwania
ON DELETE CASCADEprzy tworzeniu klucza obcego. - Ręcznie usunąć powiązane rekordy przed usunięciem rekordu z głównej tabeli.
Przykład ręcznego usuwania powiązanych danych:
-- najpierw usuwamy dane o studencie 5 z tabeli enrollments
DELETE FROM enrollments
WHERE student_id = 5;
-- potem usuwamy samego studenta 5
DELETE FROM students
WHERE id = 5;
Usuwanie z transakcjami
Do krytycznych operacji usuwania warto używać transakcji. Dzięki temu możesz cofnąć zmiany, jeśli coś pójdzie nie tak.
Przykład usuwania w transakcji:
BEGIN;
DELETE FROM students
WHERE id = 42;
-- Sprawdzamy wynik
SELECT * FROM students WHERE id = 42;
-- Jeśli wszystko OK, zatwierdzamy zmiany
COMMIT;
-- Jeśli nie, cofamy
-- ROLLBACK;
Więcej o transakcjach w kolejnych wykładach :P
GO TO FULL VERSION