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
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 = 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 modelu | Odpovídá v tabulce |
|---|---|
| Relace | Tabulka |
| Schéma relace | Záhlaví tabulky (definice sloupců) |
| Atribut | Sloupec |
| N-tice | Řádek |
| Doména atributu | Datový typ sloupce |
🔑 Klíče a integritní omezení v relačním modelu
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á 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 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 \}
| Operace | Zápis v RA | Odpovídá v SQL SELECT | Popis |
|---|---|---|---|
| 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. |
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):
- Zkonstruuj universum (kartézský součin toho, co chceme porovnávat).
- Zkonstruuj reálnou množinu (co skutečně existuje).
- Odečti reálnou od universa → získáš „nerealizované" dvojice.
- Projekcí získáš diskvalifikované prvky.
- Odečti diskvalifikované od kandidátů → výsledek.
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
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é!):
- FROM — zdroj dat
- WHERE — filtrování řádků
- GROUP BY — seskupení
- Agregační funkce (COUNT, SUM, AVG, MAX, MIN) dle skupin
- HAVING — filtrování skupin
- SELECT — výběr / výpočet sloupců
- ORDER BY — řazení výsledku
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 — 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.ANY≡SOME— 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
| Zkratka | Název | Hlavní příkazy | Co 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. |
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
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):
| Akce | Chování |
|---|---|
| NO ACTION / RESTRICT | Operace se odmítne, pokud existují závislé záznamy. |
| CASCADE | Závislé záznamy se automaticky smažou / aktualizují. |
| SET NULL | Cizí klíč v závislých záznamech se nastaví na NULL. |
| SET DEFAULT | Cizí 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.
- 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énoodvolá 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.
- 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á.
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
Klasický příklad: převod peněz z účtu A na účet B. Transakce se skládá ze dvou UPDATE příkazů:
- Odečti X z účtu A.
- Přičti X na účet B.
- 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
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.
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.
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.
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.
- 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
Ž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:
- Roll Forward (REDO) — přehraní žurnálu od posledního checkpointu; obnoví vyrovnávací paměť.
- 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:
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.
T1 provede změnu, T2 čte tuto nezávaznou (dirty) hodnotu, T1 provede ROLLBACK. T2 pracuje s daty, která nikdy nebyla platná.
T1 čte řádky, T2 změní hodnoty některých řádků, T1 čte znovu — dostane jiné hodnoty.
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 | 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
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.
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ů.
- 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.