0Pricing
SQL Academy · Lekcja

Widoki aktualizowalne i triggery INSTEAD OF

Sprawiać, aby widoki można było bezpośrednio aktualizować, lub używać triggerów INSTEAD OF, gdy widok agreguje dane albo łączy tabele

Widoki aktualizowalne i triggery INSTEAD OF to bezpłatna lekcja SQL Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej SQL Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs SQL Academy zawiera 4 lekcji w sumie.

Automatycznie aktualizowalne widoki

PostgreSQL automatycznie umożliwia aktualizowanie prostych widoków. INSERT/UPDATE/DELETE na widoku jest przepisywane jako ta sama operacja na tabeli bazowej:

CREATE VIEW active_users AS
  SELECT id, email, full_name FROM users WHERE deleted_at IS NULL;

UPDATE active_users SET full_name = 'Alice' WHERE id = 1;
-- Translates to UPDATE on the users table.

Wymagania dotyczące automatycznej aktualizacji

Widok musi:

  • Odwoływać się dokładnie do JEDNEJ tabeli bazowej
  • Nie zawierać agregacji, GROUP BY, HAVING ani DISTINCT
  • Nie zawierać LIMIT ani OFFSET
  • Nie zawierać operacji zbiorowych (UNION itd.)
  • Bezpośrednio odwzorowywać kolumny (bez wyrażeń na liście SELECT — lub tylko z niektórymi wyrażeniami)

WITH CHECK OPTION

Uniemożliwiaj zapisy, które utworzyłyby wiersze niewidoczne w widoku:

CREATE VIEW active_users AS
  SELECT * FROM users WHERE deleted_at IS NULL
  WITH CHECK OPTION;

INSERT INTO active_users (email, deleted_at) VALUES (..., NOW());
-- ERROR — would create a row outside the view's WHERE.

Złożone widoki wymagają INSTEAD OF

Widoki zawierające złączenia, agregacje lub wyrażenia nie są automatycznie aktualizowalne. Należy napisać wyzwalacz INSTEAD OF, który określi sposób obsługi zapisu:

CREATE VIEW user_with_address AS
  SELECT u.id, u.email, a.city, a.country
  FROM users u JOIN addresses a ON a.user_id = u.id;

CREATE TRIGGER user_addr_update
INSTEAD OF UPDATE ON user_with_address
FOR EACH ROW EXECUTE FUNCTION update_user_addr();

Funkcja wyzwalacza INSTEAD OF

Funkcja decyduje, do których tabel bazowych zapisywać dane:

CREATE FUNCTION update_user_addr() RETURNS TRIGGER AS $$
BEGIN
  UPDATE users SET email = NEW.email WHERE id = NEW.id;
  UPDATE addresses SET city = NEW.city, country = NEW.country WHERE user_id = NEW.id;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Kiedy INSTEAD OF jest lepsze od logiki aplikacji

Jeśli wielu użytkowników aktualizuje widok, centralizacja logiki aktualizacji w wyzwalaczu zapewnia spójność. Jeśli aktualizuje go tylko jedna aplikacja, należy pozostawić tę logikę w kodzie aplikacji.

SECURITY BARRIER

Uniemożliwia planiście ujawnianie predykatów niezaufanym użytkownikom widoku (wyciek informacji przez koszt):

CREATE VIEW my_things AS
SELECT * FROM things WHERE owner_id = current_user_id()
WITH (security_barrier);

Bezpieczeństwo na poziomie wierszy jako alternatywa

Nowoczesny PostgreSQL obsługuje również bezpieczeństwo na poziomie wierszy (RLS) w tabelach bazowych — często jest to prostsze rozwiązanie niż tworzenie widoków bezpieczeństwa.

ALTER TABLE things ENABLE ROW LEVEL SECURITY;
CREATE POLICY owner_only ON things USING (owner_id = current_user_id());

Widoki rekurencyjne

PostgreSQL obsługuje widoki rekurencyjne (hierarchię, z której można wykonywać SELECT):

CREATE RECURSIVE VIEW tree (id, parent_id, depth) AS
  SELECT id, parent_id, 0 FROM nodes WHERE parent_id IS NULL
  UNION ALL
  SELECT n.id, n.parent_id, t.depth + 1
  FROM nodes n JOIN tree t ON n.parent_id = t.id;

Uprawnienia

Przyznaj uprawnienia do widoku, a nie do tabel bazowych:

GRANT SELECT, UPDATE ON active_users TO app_user;

Uwaga dotycząca wydajności

Wyzwalacz INSTEAD OF uruchamia się dla każdego wiersza. W przypadku zbiorowych operacji DML jest to powolne. Często lepiej, aby wywołujący zapisywali dane bezpośrednio do tabel bazowych.

Podsumowanie

Widoki mogą być zapisywalne.

  • Proste widoki: automatycznie aktualizowalne
  • Złożone widoki: wyzwalacze INSTEAD OF
  • WITH CHECK OPTION wymusza widoczność
  • RLS często zapewnia prostszy model bezpieczeństwa

Szybki sprawdzian

Zdefiniowano widok łączący dwie tabele. Czy domyślnie można wykonywać przez niego UPDATE?

Często zadawane pytania

Czy lekcja „Widoki aktualizowalne i triggery INSTEAD OF” jest bezpłatna?

Tak — pełny tekst „Widoki aktualizowalne i triggery INSTEAD OF” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu SQL Academy, przejdź na CoddyKit PRO. Kurs SQL Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Widoki aktualizowalne i triggery INSTEAD OF”?

Sprawiać, aby widoki można było bezpośrednio aktualizować, lub używać triggerów INSTEAD OF, gdy widok agreguje dane albo łączy tabele Ćwiczysz SQL Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć SQL Academy?

Nie wymagamy żadnego doświadczenia. SQL Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Widoki aktualizowalne i triggery INSTEAD OF”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji SQL Academy?

Tak. Każda lekcja SQL Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Widoki zwykłe: logiczne ponowne użycie
  2. Widoki aktualizowalne i triggery INSTEAD OF
  3. Widoki zmaterializowane i strategie REFRESH
  4. Kiedy wykonywać agregację wstępną
← Powrót do SQL Academy