🗄️ BI-DBS – Databázové systémy

Státnicové poznámky · Bakalářské státní zkoušky · FIT ČVUT

Relační model & algebra Jazyk SQL Integritní omezení Transakce & ACID
Okruh 1 — BI-SPOL.21-5

Relační databáze, relační algebra, základy SQL a integritní omezení

Relační datový model, schéma databáze, dotazování pomocí relační algebry, základní konstrukty jazyka SQL (SELECT, DDL, DML, DCL, TCL) a vyjádření integritních omezení v DDL.

📐 Relační datový model – základní pojmy

Relace je matematická množina n-tic. Intuitivně odpovídá tabulce, ale je to množina (bez duplicit, bez pořadí).

Relační datový model (RDM) je základ relačních databází. Pracuje s daty jako s matematickými množinami — relacemi. Klíčový rozdíl oproti tabulkám v tabulkovém procesoru: v relaci nezáleží na pořadí řádků a nesmí existovat duplicitní řádky.

  • Atribut — sloupec tabulky; každý atribut má svou doménu (přípustné hodnoty, např. celá čísla, řetězce).
  • N-tice — jeden řádek relace; prvek kartézského součinu domén všech atributů.
  • Schéma relace R(A₁:D₁, A₂:D₂, …, Aₙ:Dₙ) — záhlaví tabulky (jméno + atributy s doménami).
  • Schéma relační databáze — dvojice (R, I), kde R je množina relací a I je množina integritních omezení.
  • 1NF (první normální forma) — atributy musí být atomické (žádné vícehodnotové atributy, žádné vnořené tabulky).
⚠️ Relace vs. tabulka – co se musí vědět
  • Relace = množina n-tic → bez duplicit, bez pořadí.
  • RDBMS implementují tabulky, které mohou obsahovat duplicity a mají pořadí (proto SQL používáme DISTINCT a ORDER BY).
  • SQL SELECT bez DISTINCT vrací multimnožinu (bag), ne množinu!
Termín relačního modeluOdpovídá v tabulce
RelaceTabulka
Schéma relaceZáhlaví tabulky (definice sloupců)
AtributSloupec
N-ticeŘádek
Doména atributuDatový typ sloupce

🔑 Klíče a integritní omezení v relačním modelu

Klíč schématu R(A) je minimální podmnožina atributů K ⊆ A, která jednoznačně určuje každou n-tici v jakékoli přípustné relaci R*.

Proč minimální? Musí platit, že neexistuje žádná vlastní podmnožina K' ⊂ K, která by také jednoznačně určovala n-tice. Bez požadavku minimality by byl klíčem i celý řádek.

  • Primární klíč (PK) — jeden vybraný klíč, který identifikuje n-tice. Hodnoty nesmí být NULL.
  • Alternativní klíč (UK, Unique Key) — ostatní klíče relace; v SQL vyjádřeno jako UNIQUE + NOT NULL.
  • Cizí klíč (FK) — odkaz z jedné relace na klíč jiné relace (nebo téže). Zajišťuje referenční integritu: MA_NA_PROGRAMU[JmenoF] ⊆ FILM[JmenoF].

Příklad: KINO(NazevK, Adresa), FILM(JmenoF, Herec, Rok), MA_NA_PROGRAMU(NazevK, JmenoF, Datum) — primární klíče podtrženy, cizí klíče odkazují na KINO a FILM.

✅ Přípustná (konzistentní) databáze

Přípustná relační databáze se schématem (R, I) je taková množina konkrétních relací {R₁*, R₂*, …, Rₙ*}, jejichž n-tice vyhovují všem tvrzením v I (integritním omezením).

Relační algebra – přehled operací

Relační algebra je formální dotazovací jazyk nad relacemi. Je POUZE dotazovací – neobsahuje DML ani DDL. Každá operace vrací relaci (výsledky lze řetězit).

Relační algebra byla vzorem pro návrh příkazu SELECT v SQL. SQL SELECT je relačně úplný (umí vyjádřit jakýkoli výraz relační algebry) a navíc má větší vyjadřovací sílu (agregace, vnější spojení, řazení…).

Minimální množina operací RA: {×, selekce, projekce, přejmenování →, sjednocení ∪, rozdíl \}

OperaceZápis v RAOdpovídá v SQL SELECTPopis
Selekce (restrikce) R(φ) WHERE φ Vybere řádky splňující podmínku φ.
Projekce R[C] SELECT DISTINCT A₁, A₂, … Vybere jen zadané sloupce (a eliminuje duplicity).
Přejmenování t → alias SELECT A AS B Přejmenuje atribut.
Přirozené spojení R * S FROM R NATURAL JOIN S Spojí přes rovnost všech společných atributů.
Obecné (Θ-)spojení R[t₁ Θ t₂]S FROM R JOIN S ON (R.t₁ Θ S.t₂) Spojí podle podmínky Θ ∈ {<, >, =, ≤, ≥, ≠}.
Kartézský součin R × S FROM R CROSS JOIN S Všechny kombinace řádků z R a S.
Sjednocení R ∪ S … UNION … Sjednocení kompatibilních relací.
Průnik R ∩ S … INTERSECT … Společné n-tice.
Rozdíl R \ S … EXCEPT (Oracle: MINUS) … N-tice v R, které nejsou v S.
Levé polospojení R <* S SELECT DISTINCT R.* FROM R JOIN S ON … N-tice z R spojitelné s nějakou n-ticí z S.
Antijoin R ⊳ S R \ {R <* S} N-tice z R NEspojitelné s žádnou n-ticí z S.
Relační dělení R ÷ S Pomocí NOT EXISTS nebo EXCEPT Hodnoty x z R, které tvoří dvojici s KAŽDÝM prvkem y z S.
🎓 Priority vyhodnocení v RA

Vyhodnocuje se zleva doprava. Selekce a projekce mají přednost před binárními operacemi. Pro změnu priority se používají složené závorky. Příklad:

{MA_NA_PROGRAMU(NazevK='Mir')[JmenoF, Datum] * FILM}[Herec → Hvezda]

Kvantifikátory v relační algebře a relační dělení

Nejčastější „záludné" úlohy u státnic se týkají správné formulace dotazů se všeobecným kvantifikátorem (∀ – „pro každý/všechny").

Existenční kvantifikátor (∃x)(P(x)): Přímá selekce nebo polospojení — „existuje alespoň jedna n-tice, která splňuje P."

Všeobecný kvantifikátor (∀x)(P(x)): Přímo v RA neexistuje, ale platí: ∀x.P(x) ≡ ¬∃x.(¬P(x))

Postup pro dotazy se všeobecnou kvantifikací (vzorec):

  1. Zkonstruuj universum (kartézský součin toho, co chceme porovnávat).
  2. Zkonstruuj reálnou množinu (co skutečně existuje).
  3. Odečti reálnou od universa → získáš „nerealizované" dvojice.
  4. Projekcí získáš diskvalifikované prvky.
  5. Odečti diskvalifikované od kandidátů → výsledek.
Relační dělení: R(x, y) ÷ S(y) = R[x] \ {{R[x] × S} \ R}[x]
Výsledkem jsou všechny hodnoty x z R, které v R tvoří dvojici s každým prvkem y z S.

Příklady typů dotazů (na státnicích je třeba umět rozlišit!):

  • Kina, která hrají alespoň jeden film s Brando → polospojení (∃).
  • Kina, která nehrají žádný film s Brando → rozdíl všech kin minus kina hrající Brando.
  • Kina, která hrají pouze filmy s Brando → složitější dotaz (nejde přes dělení).
  • Kina, která hrají každý film s Brando → relační dělení (÷) nebo vzorec se všeobecným kvantifikátorem.

📝 Jazyk SQL – úvod a SELECT

SQL (Structured Query Language) je standardizovaný dotazovací a definičný jazyk pro relační databáze. Deklarativní: říkáme co chceme, ne jak se to má technicky udělat.

Klíčové vlastnosti SQL:

  • Klíčová slova a názvy objektů nejsou case sensitive; porovnání řetězců ANO (pokud není session nastavena jinak).
  • Standardizace: 1986, 1992, 1999, 2003 … Poslední čistě relační standard byl 1992.
  • Implementace mají odchylky — zejm. pro NULL, OUTER JOIN, datové typy.

Základní syntaxe SELECT:

SELECT [DISTINCT | ALL] specifikace_sloupců
FROM specifikace_zdroje
[WHERE podmínka]
[GROUP BY seznam_sloupců]
[HAVING podmínka_skupiny]
[ORDER BY specifikace_řazení];

Pořadí vyhodnocení klauzulí (velmi důležité!):

  1. FROM — zdroj dat
  2. WHERE — filtrování řádků
  3. GROUP BY — seskupení
  4. Agregační funkce (COUNT, SUM, AVG, MAX, MIN) dle skupin
  5. HAVING — filtrování skupin
  6. SELECT — výběr / výpočet sloupců
  7. ORDER BY — řazení výsledku
💡 Proč je pořadí vyhodnocení důležité?

Proto nelze v klauzuli WHERE použít aliasy definované v SELECT (SELECT ještě nebyl vyhodnocen). Proto HAVING slouží pro podmínky na výsledky agregačních funkcí, zatímco WHERE filtruje před agregací.

Operátory v klauzuli WHERE: =, <>, !=, <, >, <=, >=, BETWEEN, IN, LIKE, EXISTS, IS NULL, IS NOT NULL, AND, OR, NOT, ANY, ALL, SOME, UNIQUE.

Zástupné znaky v LIKE: % = libovolná skupina znaků (i prázdná), _ = právě jeden znak. Escape: LIKE '%AAA\%BBB%' ESCAPE '\'

NULL hodnota: Má význam „neznámá", „neuvedená", „N/A". Není to nula ani prázdný řetězec! SQL používá tříhodnotovou logiku: TRUE, FALSE, NULL (UNKNOWN). Porovnání s NULL dává NULL, proto se používá IS NULL / IS NOT NULL místo = NULL.

🔗 SELECT – spojení tabulek, agregace, poddotazy

Typy spojení (JOIN):

  • CROSS JOIN — kartézský součin (odpovídá R × S v RA).
  • JOIN … ON (podmínka) — Θ-spojení (obecné).
  • JOIN … USING (sloupce) — spojení přes rovnost zadaných sloupců.
  • NATURAL JOIN — přirozené spojení (automaticky přes všechny shodně pojmenované sloupce — pozor na nečekané shody!).
  • LEFT [OUTER] JOIN — levé vnější spojení: zachová všechny řádky z levé tabulky, chybějící hodnoty z pravé doplní NULL.
  • RIGHT [OUTER] JOIN — analogicky pro pravou tabulku.
  • FULL [OUTER] JOIN — zachová řádky z obou stran.
⚠️ OUTER JOIN vs. polospojení (semi-join)
  • OUTER JOIN — SQL — normální spojení + zachování nespojitelných řádků (doplněny NULL).
  • Polospojení (semi-join) — RA — redukce n-tic relace na ty, které jsou spojitelné s druhou relací.
  • Anti-join — RA — redukce na n-tice NEspojitelné s druhou relací.

Agregační funkce: COUNT, SUM, AVG, MAX, MIN.

  • COUNT(*) — počítá všechny řádky včetně NULL.
  • COUNT(A) — ignoruje NULL hodnoty atributu A.
  • Ostatní agregační funkce (SUM, AVG) ignorují NULL hodnoty.
  • SUM(∅) = NULL (ne 0!) — proto pozor na COALESCE.
  • COUNT(∅) = 0.

GROUP BY seskupuje řádky. V SELECT lze uvést pouze seskupovací atributy nebo agregační funkce. HAVING filtruje skupiny podle výsledků agregací.

Poddotazy (vnořené dotazy):

  • Nevztažený (uncorrelated) — vnitřní dotaz lze vyhodnotit samostatně; vrací skalár, seznam hodnot nebo tabulku.
  • Vztažný (correlated) — vnitřní dotaz se odvolává na vnější; vyhodnocuje se pro každý řádek vnějšího dotazu (dražší).
  • Použití: v WHERE (= (SELECT …), IN (SELECT …), EXISTS (SELECT …)), v FROM (inline view), v SELECT (skalární poddotaz).

Kvantifikace v SQL:

  • EXISTS (SELECT …) — existenční kvantifikátor: TRUE pokud poddotaz vrátí alespoň jeden řádek.
  • NOT EXISTS (SELECT …) — negace existenčního kvantifikátoru → implementace všeobecného (∀).
  • IN (…) ≡ = SOME; NOT IN (…) ≡ <> ALL.
  • ANYSOME — alespoň pro jednu hodnotu.
  • ALL — pro všechny hodnoty.

Příkaz WITH (Common Table Expression – CTE): Definice dočasných pohledů pro aktuální dotaz. Umožňuje přehlednou formulaci složitých dotazů a nahrazení relačního dělení. Klíčové pro dotazy se všeobecnou kvantifikací.

⚙️ Rozdělení SQL: DDL, DML, DCL, TCL

ZkratkaNázevHlavní příkazyCo dělá
DDL Data Definition Language CREATE, ALTER, DROP, RENAME Definuje strukturu databáze: tabulky, pohledy, indexy, integritní omezení.
DML Data Manipulation Language SELECT, INSERT, UPDATE, DELETE, MERGE Dotazování a manipulace s daty. Při DML operacích DBMS automaticky kontroluje integritní omezení.
DCL Data Control Language GRANT, REVOKE Správa přístupových práv k databázovým objektům.
TCL Transaction Control Language COMMIT, ROLLBACK, SAVEPOINT Řízení transakcí — potvrzení nebo odvolání změn.
⚠️ Důležité: RA vs. SQL

Relační algebra pokrývá POUZE dotazování (odpovídá SELECT). DDL, DML (mimo SELECT), TCL a DCL v relační algebře neexistují!

🏗️ DDL – Definice struktury databáze

CREATE TABLE:

CREATE TABLE tabulka (
  sloupec datovy_typ [io_sloupce ...],
  ...
  [io_tabulky ...]
);

Příklad:

CREATE TABLE VYPUJCKY (
  c_kopie  CHAR(3)        NOT NULL,
  c_zak    CHARACTER(6)   NOT NULL,
  cena     DECIMAL(5,2),
  rod_c    CHARACTER(10)  NOT NULL,
  datum_v  DATE
);

ALTER TABLE: Mění strukturu existující tabulky.

ALTER TABLE KINA ADD pocet_mist INTEGER;           -- přidání sloupce
ALTER TABLE KINA DROP COLUMN pocet_mist;           -- odebrání sloupce
ALTER TABLE t ADD CONSTRAINT io_name CHECK (...);  -- přidání IO
ALTER TABLE t DROP CONSTRAINT io_name;             -- odebrání IO

DROP TABLE:

DROP TABLE KINA CASCADE;  -- smaže tabulku a závislé objekty

Datové typy v SQL: numerické (INTEGER, DECIMAL, FLOAT…), textové (CHAR, VARCHAR, TEXT…), datum a čas (DATE, TIME, TIMESTAMP…). NULL je prvkem každého datového typu (pokud nespecifikujeme NOT NULL).

🛡️ Integritní omezení (IO) v SQL DDL

Integritní omezení jsou tvrzení definovaná ve schématu, která určují, jaká data v databázi být mohou (přípustná databáze). DBMS je automaticky hlídá při DML operacích.

Druhy integritních omezení v SQL:

  • NOT NULL — atribut nesmí být NULL (povinnost).
  • DEFAULT hodnota — výchozí hodnota atributu.
  • UNIQUE — hodnota atributu (nebo kombinace atributů) musí být jedinečná. V SQL může být NULL (PostgreSQL: jen jedna NULL; Oracle: více NULL).
  • PRIMARY KEY — primární klíč: UNIQUE + NOT NULL. Tabulka může mít jen jeden.
  • FOREIGN KEY … REFERENCES — cizí klíč: zajišťuje referenční integritu.
  • CHECK (podmínka) — libovolná podmínka na hodnotu atributu nebo kombinace atributů.

IO lze definovat na úrovni sloupce (pro jednoduchá IO) nebo na úrovni tabulky (pro složená IO, např. složený primární klíč). Pojmenování IO (CONSTRAINT jméno) je doporučené.

CREATE TABLE PREDSTAVENI (
  NAZEV_K  CHAR VARYING(20)  NOT NULL,
  NAZEV_F  CHAR VARYING(20)  NOT NULL,
  DATUM    DATE               NOT NULL,
  CONSTRAINT PREDSTAVENI_PK
    PRIMARY KEY (NAZEV_K, NAZEV_F),
  CONSTRAINT PREDSTAVENI_KINA_FK
    FOREIGN KEY (NAZEV_K) REFERENCES KINA,
  CONSTRAINT PREDSTAVENI_FILMY_FK
    FOREIGN KEY (NAZEV_F) REFERENCES FILMY
);

Referenční integrita – kaskádní reakce (co se stane při DELETE/UPDATE rodičovského záznamu):

AkceChování
NO ACTION / RESTRICTOperace se odmítne, pokud existují závislé záznamy.
CASCADEZávislé záznamy se automaticky smažou / aktualizují.
SET NULLCizí klíč v závislých záznamech se nastaví na NULL.
SET DEFAULTCizí klíč se nastaví na výchozí hodnotu.

Odložitelné IO (DEFERRED): SQL umožňuje nastavit kontrolu IO jako odloženou až na konec transakce (DEFERRED). Užitečné např. při přehlašování na termín — lze dočasně porušit IO uvnitř transakce. Oracle umí také dočasně vypnout IO příkazem ALTER TABLE … DISABLE/ENABLE CONSTRAINT.

💡 Co učitele zajímá u integritních omezení
  • Jaké druhy IO SQL podporuje deklarativně (NOT NULL, UNIQUE, PK, FK, CHECK).
  • Proč některá IO nelze vyjádřit deklarativně (složitá byznys pravidla, podmínky přes více tabulek) → řeší se triggery (procedurální IO).
  • Co je referenční integrita a jaké jsou možnosti kaskádní reakce.
  • Rozdíl mezi IO na úrovni sloupce a tabulky.

✏️ DML – Manipulace s daty

INSERT: Vložení řádku nebo řádků.

-- Vložení jednoho řádku (výčet sloupců je doporučen)
INSERT INTO Zakaznici (rod_c, jmeno)
  VALUES ('4804230160', 'Novák');

-- Vložení více řádků pomocí SELECT
INSERT INTO Kolik_kopii
  SELECT rod_c, COUNT(c_kopie) FROM Vypujcky
  GROUP BY rod_c;

UPDATE: Změna hodnot.

UPDATE Zakaznici SET jmeno = 'Gotzová'
WHERE rod_c = '4655292130';

-- UPDATE pomocí vnořeného dotazu
UPDATE Zakaznici Z
SET Pocet_pujcek = (SELECT COUNT(*) FROM Vypujcky V
                    WHERE V.rod_c = Z.rod_c);

DELETE: Smazání řádků.

DELETE FROM Filmy
WHERE jmeno_f = 'Puška';  -- POZOR na správnou podmínku!

MERGE (UPSERT): Kombinace INSERT a UPDATE — pokud záznam existuje, provede se UPDATE, jinak INSERT. PostgreSQL používá UPSERT místo MERGE.

🔐 DCL – Přístupová práva; TCL – Řízení transakcí

DCL — GRANT a REVOKE:

  • Každý objekt má vlastníka (ten, kdo ho vytvořil).
  • GRANT — přidělí práva; REVOKE — odebere práva.
  • Přidělitelná práva (dle typu objektu): SELECT, INSERT, UPDATE, DELETE, ALTER, EXECUTE, INDEX, REFERENCES.
  • Práva lze přidělovat uživatelům, rolím nebo PUBLIC (všem).
GRANT SELECT ON V_Filmy TO XNOVAKJ3;
GRANT ALL PRIVILEGES ON V_filmy TO PUBLIC;
REVOKE INSERT ON Filmy FROM XNOVAKJ3;

Schéma vs. uživatel: V Oracle jsou schema = uživatel. V PostgreSQL jsou to oddělené koncepty (schéma = namespace pro databázové objekty).

TCL — COMMIT, ROLLBACK, SAVEPOINT:

  • COMMIT — potvrdí všechny změny provedené v aktuální transakci; změny jsou perzistentně uloženy a viditelné ostatním session.
  • ROLLBACK — odvolá všechny změny provedené v aktuální transakci; databáze se vrátí do stavu před transakcí.
  • SAVEPOINT jméno — definuje záchytný bod uvnitř transakce; ROLLBACK TO SAVEPOINT jméno odvolá jen část transakce.

AUTOCOMMIT: Pokud je ON, každý DML příkaz je automaticky potvrzen. Pokud je OFF, musí přijít explicitní COMMIT nebo ROLLBACK. Doporučení: nespoléhat na AUTOCOMMIT ON; v insert skriptech vždy používat explicitní COMMIT.

Pohledy (VIEW): Virtuální relace — v systémovém katalogu uložen SELECT příkaz. Pohled se chová jako tabulka pro dotazování. DML nad pohledy je možné jen pro „simple views" (bez JOIN, agregací, výrazů). Pohledy nepřinášejí výkonnostní zrychlení (k tomu slouží materializované pohledy – MATERIALIZED VIEWS).

📋 Shrnutí okruhu 1

  • Relační databáze je sada relací (množin n-tic) + sada integritních omezení. Klíče (PK, UK) a cizí klíče (FK) jsou základní IO.
  • Relační algebra je formální dotazovací jazyk (selekce, projekce, spojení, množinové operace, polospojení, antijoin, dělení). Je vzorem pro SQL SELECT.
  • SQL se dělí na DDL, DML, DCL, TCL. Každá skupina má specifické příkazy a účel.
  • Integritní omezení v SQL: NOT NULL, DEFAULT, UNIQUE, PRIMARY KEY, FOREIGN KEY (REFERENCES), CHECK — lze definovat na úrovni sloupce nebo tabulky.
  • Referenční integrita: cizí klíč odkazuje na primární klíč jiné tabulky; reakce na DELETE/UPDATE: NO ACTION, RESTRICT, CASCADE, SET NULL, SET DEFAULT.
🎓 Kontrolní otázky pro státnice
  • Co je relace a jak se liší od tabulky? — Relace je množina n-tic (bez duplicit, bez pořadí). Tabulka v RDBMS může obsahovat duplicity (proto DISTINCT) a má pořadí (proto ORDER BY).
  • Co je schéma relační databáze? — Dvojice (R, I): množina relačních schémat R a množina integritních omezení I.
  • Co je klíč schématu a proč požadujeme minimalitu? — Klíč je minimální množina atributů jednoznačně určující každou n-tici. Minimalita zaručuje, že odstraněním libovolného atributu z klíče přestane jednoznačně identifikovat.
  • Jaké operace tvoří minimální množinu RA? — Kartézský součin, selekce, projekce, přejmenování, sjednocení, množinový rozdíl.
  • Jak formulovat dotaz se všeobecným kvantifikátorem v RA? — Využitím ekvivalence ∀x.P(x) ≡ ¬∃x.(¬P(x)) a konstrukce: universum – reálná množina = nerealizované; výsledek = kandidáti – diskvalifikovaní. Alternativně relačním dělením (÷).
  • Jak se liší pořadí klauzulí SQL SELECT a pořadí jejich vyhodnocení? — Píšeme: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY. Vyhodnocuje se: FROM → WHERE → GROUP BY → SELECT (agregace) → HAVING → ORDER BY.
  • Jaká integritní omezení lze vyjádřit deklarativně v SQL DDL? — NOT NULL, UNIQUE, PRIMARY KEY, FOREIGN KEY/REFERENCES, CHECK, DEFAULT.
  • Co je referenční integrita a jaké jsou možnosti reakce na porušení? — FK odkazuje na PK jiné tabulky; při DELETE/UPDATE lze reagovat: NO ACTION, RESTRICT, CASCADE, SET NULL, SET DEFAULT.
  • K čemu slouží TCL příkazy? — COMMIT (potvrdit transakci), ROLLBACK (odvolat), SAVEPOINT (záchytný bod uvnitř transakce).
  • Co je DCL a jak funguje GRANT/REVOKE? — GRANT přiděluje přístupová práva uživateli/roli, REVOKE je odebírá.
Okruh 2 — BI-SPOL.21-6

Transakce a jejich vlastnosti – ACID

Pojem transakce, vlastnosti ACID (Atomicity, Consistency, Independence, Durability), stavový diagram transakce, transakční žurnál, stupně izolace, uzamykací protokoly a řešení souběžného přístupu.

🔄 Co je transakce a proč je potřeba

Transakce je sekvence akcí (DML příkazů), které spolu logicky souvisí a které se mají provést jako jeden celek — buď celé, nebo vůbec.

Klasický příklad: převod peněz z účtu A na účet B. Transakce se skládá ze dvou UPDATE příkazů:

  1. Odečti X z účtu A.
  2. Přičti X na účet B.
  3. COMMIT nebo ROLLBACK.

Pokud by po kroku 1 došlo k pádu systému bez transakčního zpracování, peníze by „zmizely". Transakce zajistí, že buď proběhnou oba kroky, nebo ani jeden.

Dva základní požadavky na DBMS:

  • Ochrana dat — odolnost vůči haváriím serveru (chyba HW, SW, výpadek proudu).
  • Korektní souběžný přístup — více uživatelů pracuje současně se stejnými daty bez konfliktů.

Moduly DB stroje zajišťující transakční zpracování:

  • Concurrency control — řízení souběžného zpracování: každý uživatel vidí konzistentní stav DB bez ohledu na souběžné přístupy.
  • Recovery — zotavení z chyb: stav DB nesmí být narušen při havárii.

⚗️ ACID vlastnosti transakce

ACID = Atomicity, Consistency, Independence, Durability. Soubor vlastností, které musí transakční zpracování zaručovat, aby databáze zůstala konzistentní.
🅰️ A – Atomicity (Atomicita)

Transakce musí buď proběhnout celá, nebo vůbec. Nelze provést jen část transakce. Pokud dojde k chybě uprostřed transakce, všechny změny se odvolají (ROLLBACK) → databáze se vrátí do stavu před transakcí.

Jak je implementováno: Pomocí transakčního žurnálu (logu) — UNDO operace odvolává nepotvrzené změny.

🅲 C – Consistency (Konzistence)

Transakce transformuje databázi z jednoho konzistentního stavu do jiného konzistentního stavu. Konzistence = splnění všech integritních omezení.

Poznámka: Databáze smí být dočasně nekonzistentní uvnitř transakce (např. při přehlašování na termín: student je krátce zapsán na dva termíny). Konzistence je vyžadována pouze na konci transakce.

Jak je implementováno: Interními algoritmy DML operací, které kontrolují IO.

🅸 I – Independence / Isolation (Nezávislost)

Dílčí efekty jedné transakce nejsou viditelné jiným transakcím (dokud transakce není potvrzena). Každá transakce se chová, jako by probíhala izolovaně.

Jak je implementováno: Dvoufázový uzamykací protokol (2PL) a různé stupně izolace.

🅳 D – Durability (Trvanlivost)

Efekty úspěšně potvrzené (committed) transakce jsou trvale uloženy v databázi a přežijí jakýkoli následný pád systému.

Jak je implementováno: Transakční žurnál — REDO operace zopakuje změny potvrzených transakcí po restartu.

🎓 Pamatuj: Jak jsou vlastnosti ACID implementovány
  • Atomicity + Durability → transakční žurnál (UNDO + REDO).
  • Consistency → interní algoritmy DML + možnost více DML/SELECT v jedné transakci.
  • Independence → dvoufázový uzamykací protokol (2PL), stupně izolace.

📊 Stavový diagram transakce

Transakce prochází těmito stavy:

  • Aktivní (Active) — transakce probíhá, provádějí se DML příkazy.
  • Částečně potvrzená (Partially Committed) — provedena poslední operace transakce, změny jsou zatím jen v paměti (bufferu).
  • Potvrzená (Committed) — COMMIT byl úspěšně proveden; změny jsou trvale uloženy na disk. Stav je nevratný.
  • Chybná (Failed) — transakce narazila na chybu; v normálním průběhu nelze pokračovat.
  • Zrušená (Aborted) — po provedení ROLLBACK; databáze vrácena do stavu před transakcí.

Hranice transakce:

  • Konec: explicitní COMMIT nebo ROLLBACK; implicitní ukončení session (chování závisí na klientovi).
  • Začátek: skončením předchozí transakce nebo vznikem session. Pozor na AUTOCOMMIT!

📓 Transakční žurnál (Log) a obnova po pádu

Transakční žurnál (log) je sekvenční soubor, do kterého DBMS zaznamenává každou změnu v databázi ve formě změnových vektorů: <transID, blockID, old data, new data>.

Žurnál obsahuje speciální záznamy pro COMMIT, ROLLBACK a checkpoint (synchronizační bod — SCN v Oracle).

Operace při obnově:

  • UNDO — odvolání nepotvrzených změn (po pádu): obnoví old data z žurnálu.
  • REDO — opakování potvrzených změn (po pádu): znovu aplikuje new data z žurnálu.

Postup obnovy po pádu systému:

  1. Roll Forward (REDO) — přehraní žurnálu od posledního checkpointu; obnoví vyrovnávací paměť.
  2. Roll Back (UNDO) — odvolání transakcí, které nebyly v době pádu dokončeny.

Třídy chyb:

  • Globální — pád systému (výpadek proudu → ztráta bufferu), uváznutí, chyba komunikace, chyba média.
  • Lokální — logická chyba v jedné transakci (porušení IO, dělení nulou) → ošetřuje se explicitním ROLLBACK.

Problémy souběžného zpracování

Při souběžném zpracování transakcí mohou nastat tyto anomálie:

❌ Ztráta aktualizace (Lost Update)

T1 čte X (=80), T2 čte X (=80), T1 zapíše X-5 (=75), T2 zapíše X+4 (=84). Výsledek by měl být 79, ale je 84 — T1's aktualizace je ztracena.

❌ Dočasná aktualizace / Dirty Read

T1 provede změnu, T2 čte tuto nezávaznou (dirty) hodnotu, T1 provede ROLLBACK. T2 pracuje s daty, která nikdy nebyla platná.

❌ Neopakovatelné čtení (Non-repeatable Read)

T1 čte řádky, T2 změní hodnoty některých řádků, T1 čte znovu — dostane jiné hodnoty.

❌ Fantóm (Phantom)

T1 čte sadu řádků, T2 vloží nebo smaže řádky splňující podmínku T1's dotazu, T1 čte znovu — dostane jinou sadu dat (nové nebo chybějící řádky).

🎚️ Stupně izolace transakcí

Stupeň izolace definuje, jaké anomálie souběžného zpracování jsou povoleny. Vyšší izolace = méně anomálií, ale menší paralelismus (a výkon).
Stupeň izolace Dirty Read Non-repeatable Read Phantom
READ UNCOMMITTED (0)✅ povolen✅ povolen✅ povolen
READ COMMITTED (1)❌ zakázán✅ povolen✅ povolen
REPEATABLE READ (2)❌ zakázán❌ zakázán✅ povolen
SERIALIZABLE (3)❌ zakázán❌ zakázán❌ zakázán
  • SQL standard nařizuje implicitně stupeň SERIALIZABLE.
  • V praxi se nejčastěji setkáte s READ COMMITTED (Oracle, PostgreSQL — nižší stupeň neumožňují).
  • MySQL s InnoDB engine umí totéž co PostgreSQL/Oracle.

🔒 Uspořádatelnost rozvrhů a uzamykací protokoly

Rozvrh (schedule) je pořadí provádění dílčích akcí více transakcí v čase. Sériový rozvrh provádí transakce zcela za sebou. Paralelní rozvrh prokládá operace různých transakcí.

Uspořádatelnost (serializability): Paralelní rozvrh je uspořádatelný, pokud jeho výsledek je ekvivalentní výsledku nějakého sériového rozvrhu. Tato vlastnost zaručuje korektnost paralelního zpracování.

Konfliktní operace: Dvě operace na stejném objektu A jsou konfliktní, pokud jejich pořadí ovlivňuje výsledek. WRITE vs. READ nebo WRITE vs. WRITE jsou konfliktní; READ vs. READ jsou kompatibilní.

Precedenční graf: Orientovaný graf transakcí; hrana T_i → T_k pokud T_i má konfliktní operaci před T_k. Rozvrh je uspořádatelný, pokud precedenční graf neobsahuje cyklus.

🔐 Dvoufázový uzamykací protokol (2PL)

Transakce je dvoufázová, pokud:

  • Fáze 1 (rostoucí) — transakce pouze zamyká objekty, nic neodemyká.
  • Fáze 2 (klesající) — od prvního odemknutí se nic dalšího nezamyká.

Tvrzení: Pokud jsou všechny transakce dobře formované a dvoufázové, pak každý legální rozvrh je uspořádatelný.

Striktní 2PL: všechna zamčení se odemknou až na konci transakce (při COMMIT/ROLLBACK). Tím se eliminuje dirty read.

Uváznutí (Deadlock): T1 čeká na zámek drženém T2, T2 čeká na zámek drženém T1 → kruhové čekání. Řešení: ROLLBACK jedné transakce (obvykle té „mladší" nebo té, která provedla méně změn). Detekce: graf závislostí nebo timeout.

Dobře formovaná transakce:

  • Zamyká objekt, chce-li k němu přistupovat.
  • Nezamyká objekt, který již zamkla.
  • Neodemyká objekt, který nezamkla.
  • Na konci transakce nezůstane žádný objekt zamčený.

📋 Shrnutí okruhu 2

  • Transakce je logická jednotka práce (sekvence DML příkazů); buď proběhne celá, nebo vůbec.
  • ACID: Atomicity (celá nebo nic), Consistency (zachování IO), Independence (izolace od ostatních), Durability (perzistentní po COMMIT).
  • Transakční žurnál zajišťuje Atomicity (UNDO) a Durability (REDO). Obnova po pádu: Roll Forward + Roll Back.
  • Stupně izolace (0–3): READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE. V praxi nejčastěji READ COMMITTED.
  • Dvoufázový uzamykací protokol (2PL): fáze uzamykání + fáze odemykání; zaručuje uspořádatelnost rozvrhů.
🎓 Kontrolní otázky pro státnice
  • Co je transakce a proč ji potřebujeme? — Logická jednotka práce zahrnující více DML příkazů. Zajišťuje konzistenci při haváriích i souběžném přístupu (příklad: převod peněz).
  • Co znamená Atomicity? — Transakce proběhne buď celá (COMMIT), nebo vůbec (ROLLBACK). Implementováno transakčním žurnálem (UNDO).
  • Co znamená Consistency a může být databáze uvnitř transakce dočasně nekonzistentní? — C zajišťuje, že na konci transakce jsou splněna všechna IO. Uvnitř transakce dočasná nekonzistence povolena (nutné pro správnou implementaci přehlašování atd.).
  • Co znamená Independence? — Dílčí efekty transakce nejsou viditelné jiným transakcím. Implementováno uzamykacími protokoly a stupni izolace.
  • Co znamená Durability? — Potvrzené změny přežijí jakýkoli pád. Implementováno žurnálem (REDO).
  • Jaké anomálie mohou nastat při souběžném zpracování? — Ztráta aktualizace, dirty read (dočasná aktualizace), neopakovatelné čtení, fantóm.
  • Co je stupeň izolace a jaké stupně definuje SQL standard? — READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE. Standard nařizuje SERIALIZABLE; v praxi nejčastěji READ COMMITTED.
  • Co je transakční žurnál a k čemu slouží? — Sekvenční soubor změnových vektorů <transID, blockID, old, new data>. Slouží k UNDO (odvolání nepotvrzených změn) a REDO (opakování potvrzených změn) při obnově po pádu.
  • Co je uspořádatelnost rozvrhu? — Paralelní rozvrh je uspořádatelný, pokud je ekvivalentní nějakému sériovému rozvrhu. Testujeme pomocí precedenčního grafu (žádný cyklus = uspořádatelný).
  • Co je dvoufázový uzamykací protokol? — Protokol, kde transakce má fázi uzamykání a fázi odemykání. Zaručuje, že legální rozvrhy dobře formovaných dvoufázových transakcí jsou uspořádatelné.
  • Co je uváznutí a jak se řeší? — Dvě nebo více transakcí čekají navzájem na uvolnění zámků → kruhové čekání. Řeší se ROLLBACKem jedné transakce (detekce: graf závislostí nebo timeout).
  • Jak jsou jednotlivé vlastnosti ACID implementovány? — Atomicity + Durability: transakční žurnál. Consistency: algoritmy DML + vícepříkazové transakce. Independence: 2PL + stupně izolace.