# 4. Databáze Principy ukládání dat, databáze. Architektura relačních databází, dotazovací jazyk SQL a jeho části (definice, manipulace, transakce). Jazyk definice datového schématu, DDL. Jazyk manipulace s daty, DML. Relační algebra, integritní omezení, řízení transakcí. Indexování, hašování. Příklady z praxe pro vše výše uvedené. (PV003, PA152) --- **Dáta** sú údaje, ktoré majú určitú výpovednú hodnotu. - Môžu byť usporiadané (štruktúrované), ale aj nemusia byť - Užívateľovi sú k dispozícií v rôznych formách - Tabulky, grafy, súbory, obrazy, vektory, matice, ... ## Princípy ukladania dát, databáze ### Princípy ukladania dát Dáta vieme ukladať do súborového systému v rámci **súborovej štruktúry** alebo do **databázového systému** (relačné, dokumentové, grafové, vektorové), ktorý dáta logicky zoskupuje a snaží sa zabezpečiť efektívny prístup k dátam z pohľadu rýchlosti a spolahlivosti a konzistencie dát. **Súborový systém** využívame zvyčajne na ukladanie neštruktúrovaných dát alebo súborov, napríklad obrázky uploadované skrz webové rozhranie. Vieme využiť cloudové úložiská (Amazon S3 Cloud Storage), lokálne HDD/SSD disky, prípadne zoskupenie diskov skrz RAID. Súborový systém nám zabezpečuje operačný systém a zvolený súborový systém - napr. FAT32, NTFS, EXT4, Btrfs. - Výhody: menšie systémové nároky, jednoduché na používanie aplikáciami - Nevýhody: náročné na zaistenie konzistencie, nutnosť riešiť zamýkanie súborov, problematický prístup k transakciám (prepisovanie súborov a riešenie prístupových práv), horšia čitateľnosť a dokumentácia súborového systému ### Databáze **Databáza** je usporiadaná množina dát. - Prístup k uloženým dátam obstaráva **databázový menežmentový systém** (DBMS) - Databáza spoločne s DBMS tvorí **databázový systém** - Dáta vieme dotazovať pomocou dotazovacieho jazyka (napr. SQL) - **Účelom** databázových systémov je **riešit problémy** efektivity, redundancie dát, inkonzistencie, integrity a bezpečnosti - Štruktúry dát sú uložené oddelene od súborov na disku - Prístup k dátam je možný len prostredníctvom DBMS - Dáta je možné vyhodnocovať pomocou vhodných jazykov alebo metód - Je umožnený prístup viacerých užívateľov, ich správa a oprávnenia - Problémy inkonzistencie riešia **transakcie** a systém ich vyhodnocovania a plánovania - Väčšinou chceme, aby transakcie spĺňali **ACID** vlastnosti [Riadenie transakcii](/4fglZcU1QnGSdEthNGIEEQ?#Riadenie-transakcií) Rozlišujeme **typy** databázových systémov: - Relačné - dáta sú štruktúrované, ukladané v tabuľkách - dáta podliehajú normálovým formám - používa jazyk SQL, ktorý vychádza z relačnej algebry - často používa dátové štruktúry ako napríklad B+ stromy, červeno-čierne stromy, R stromy - používa modelovanie schém pomocou UML ERD diagramu - Not only SQL (NoSQL) - vznikli kvôli potrebe horizontálne škálovať - XML databázy, MongoDB (document-based), Redis (caching, key-value) - grafové, vektorové, dokumentové ... - dáta nemusia mať nejakú štruktúru, nepodliehaju normám - Napríklad MongoDB poskytuje ACID transakcie, ale nie je to bežné u iných DBMS - v dnešnej dobe často podporované aj v relačných DBMS (Postgres, MSSQL) - Podpora pre neštrukturovaný JSON, BSON - CAP theorem - Pre distribuovaný systém nie je možné poskytovať zároveň konzistenciu dát naprieč clustermi (Consistency), dostupnosť odpovedí node-ov (Availability) a toleranciu prerušenia komunikácie clusterov (Partition tolerance) - NoSQL databázy používajú Eventual Consistency - ak nenastávajú po nejakú dobu zmeny, tak v tom momente sa stáva databáza konzistentnou - NewSQL - relačné DBMS, kombinuje flexibilitu NoSQL pre OLTP - Coachbase, VoltDB, CockroachDB - Hybrid Transactional-Analytical Processing (HTAP) Dáta môžu byť ukládané v rôznej orientácii, rozlišujeme kvôli efektivite operácií nad nimi: - row-oriented - OLTP (online transaction processing) - klasické RDBMS (MySQL, MSSQL, Postgres, MariaDB, SQLite) - sú vhodné na rýchly prístup k filtrovaným dátam pomocou WHERE a INSERT nových riadkov - column-oriented - sú vhodné na OLAP - analytické databázy napr. DuckDB, RedShift, R dataframes, Pandas - rýchly prístup k výsledkom projekcie - SELECT ... FROM, pridávanie stĺpcov - majú lepšiu kompresiu - používajú Run-Length encoding, bitmapy ## Architektúra relačných databáz, dotazovací jazyk SQL a jeho časti (definícia, manipulácia, transakcia) ### Architektúra relačných databáz **Model dát** je sada nástrojov pre popis dát (syntax a sémantika), vzťahov medzi dátami a podmienkami, ktoré nad nimi platia. **Relačný model dát** je databázový model založený na **predikátovej logike**. - Základným princípom je, že všetky dáta sú reprezentované pomocou $n$-árnych relácií - Na dátach sa operuje pomocou **relačnej algebry** - Databáze organizované pomocou relačného modelu sa nazývajú **relačné databáze** **Relačný model dát** sa skladá z nasledujúcich častí: - **Atribút** - charakteristika, vlastnosť objektu - Popísaný nejakou **hodnotou** - Hodnota atribútu má **dátový typ** - **Doména** - neprázdna množina hodnôt dátového typu atribútu - Súčasťou každej domény je hodnota $null$ - Doména určuje povolené hodnoty pre daný atribút - **Relácia** - podmnožina kartézskeho súčinu $n$ domén - Podmnožina $n$-tíc atribútov - Nesmie obsahovať duplicitné relácie - Pokiaľ rôzne relácie obsahujú rovnaký atribút, môže medzi nimi vzinknúť väzba - Kedže je to množina, nezávisí na poradí $n$-tíc - Prázdna relácia je validná - **Relačná schéma** - $n$-tica atribútov - Určuje názov a záhlavie tabuľky - Koľko má stĺpcov a ako sa volajú - **Tabuľka** je reprezentáciou relácie - Prázdne schéma je zakázané Relačná databáza je zložená z **tabuliek**, ktoré sú definované **relačnou schémou** a obsahujú $n$-tice **relácie**. **Kľúč** je podmnožina atribútov, ktorých úlohou je jednoznačne **identifikovať** každú $n$-ticu v relácii. Rozlišujeme nasledovné kľúče: - **Superkľúč** - každá podmnožina atribútov, ktorá dokáže splniť podmienku kľúča - **Kandidátsky kľúč** - minimálny superkľúč - **Primárny kľúč** - jeden zvolený kandidátsky kľúč - Pokiaľ sa primárny kľúč skladá z viacerých atribútov, nazýva sa **kompozitný** - **Cudzí kľúč** - množina atribútov, ktorá je superkľúčom v inej relácii ### Dotazovací jazyk SQL a jeho časti (definícia, manipulácia, transakcia) Ekvivalentom relačnej algebry je jazyk **SQL** (Structured Query Language). **SQL** (Structured Query Language) je štandardizovaný **ne**procedurálny dotazovací jazyk používaný pre prácu s dátami v relačných databázach. - Skladá sa z DDL, DML a DCL - **DDL** (Data Definition Language) - podjazyk pre definíciu dát, slúži na **špecifikáciu relačnej schémy** - **DML** (Data Manipulation Language) - podjazyk pre manipuláciu s dátami (výber, vkladanie, úpravu a mazanie = **CRUD operácie**) - **DCL** (Data Control Language) - podjazyk pre riadenie práce s dátami (**správa transakcií**, oprávnenia) SQL je často dopĺňaný o funkcionalitu v konkrétnych RDBMS - napr. MSSQL Transact-SQL, Oracle PL/SQL, Postgres PL/pgsql. Hovoríme o **dialektoch** SQL. Príkazy SQL sa skladajú z nasledujúcich komponentov: - **Príkaz** (statement) - SELECT, UPDATE, DELETE, ... - **Dotaz** (query) - Príkaz, ktorý vracia reláciu - SELECT - **Klauzula** (clause) - Jednotlivé komponenty príkazov alebo dotazov - WHERE, GROUP BY, ... - **Predikát** (predicate) - Podmienka, ktorá obmedzuje účinky príkazu alebo dotazu - Je vyhodnotená na základe troj-hodnotovej logiky (TRUE, FALSE, NULL) - Súčasťou predikátu je **operátor** - =,<,>, <=,>= - BETWEEN - LIKE - IN, NOT IN - IS, IS NOT - LIKE - **Výraz** (expression) - Konštanta alebo funkcia vracajúca skalárnu hodnotu - Textové reťazce sa uzatvárajú do jednoduchých uvodzoviek SQL pracuje s údajmi o **dátových typoch**: - char - text s pevnou dĺžkou - varchar - text s premenlivou dĺžkou - int - celé číslo - real, float - reálne číslo - date,time,timestamp - časový údaj - numeric, decimal - číslo s pevnou dĺžkou celej a desatinnej časti - uživateľsky definované (napr. Postgres) ## Jazyk definície datového schématu, DDL **DDL** (Data Definition Language) - podjazyk pre definíciu dát, slúži na **špecifikáciu relačnej schémy**. Príkazy podjazyka DDL **definujú štruktúru relačnej schémy** (a iných objektov). **Klauzula CREATE TABLE** - Vytvorí novú relačnú schému (tabuľku) v databáze - Špecifikuje názvy a typ jednotlivých atribútov $$ \text{CREATE TABLE}\ r(a\ t, \ldots) $$ **Klauzula ALTER TABLE** - Upraví existujúcu tabuľku - Operácia môže byť **ADD** alebo **DROP** - Môže upravovať buď integritné obmedzenia **CONSTRAINT** alebo stĺpec **COLUMN** $$ \text{ALTER TABLE}\ r\ \text{<ADD|DROP>}\ \text{<COLUMN|CONSTRAINT|INDEX>}\ a $$ **Klauzula DROP TABLE, DROP VIEW** - Vymaže existujúcu tabuľku, view $$ \text{DROP TABLE|VIEW}\ r $$ **Klauzula CREATE VIEW** - Vytvorí pohľad na dáta - pomenovaný SELECT uložený v databáze, virtuálna tabuľka - Možnosť vytvoriť materializovaný view - hodnota tabuľky sa vždy prepočíta vopred (pri zmene) $$ \text{CREATE <MATERIALIZED> VIEW}\ r\ \text{AS SELECT}\ \ldots $$ **Klauzula CREATE INDEX** - Vytvorí index nad stĺpcom alebo stĺpcami v tabuľke, vieme určiť explicitne aj typ - Zvyčajne vieme aj určiť, či má byt kľúč unikátny (UNIQUE) alebo parciálny (WHERE...) - V Postgres vieme aj určiť typ indexu pomocou **USING** BTREE, HASH, BRIN, GIST... $$ \text{CREATE <UNIQUE> INDEX}\ idx\ \text{ON}\ r\ (a,b,c\ldots) $$ ## Jazyk manipulácie s dátami, DML **DML** (Data Manipulation Language) - podjazyk pre manipuláciu s dátami (výber, vkladanie, úpravu a mazanie = **CRUD operácie**). Výsledkom volania DML príkazov je relácia. - Príkazy sa môžu vnorovať (SELECT FROM (SELECT FROM ...)) - Typicky využívame operátory SOME, ALL, UNIQUE, IN, NOT IN, EXISTS, NOT EXISTS ### CRUD operácie Klauzula **AS** - Zodpovedá operácii premenovania $\rho$ - Používa sa v klauzulách SELECT alebo JOIN - Premenuje danú reláciu **Klauzula SELECT** - Zodpovedá operácii projekcie $\Pi$ - Je používaná k vypísaniu požadovaných atribútov relácie uvedené v klauzli **FROM** - Zodpovedá operácii kartézskeho súčinu $\times$ - Voliteľne je možné pridať predikát **WHERE** - Zodpovedá operácii selekcie $\sigma$ - Používame matematické operátory, logické operátory, IS NULL, IS NOT NULL, LIKE, ... - Na konštanty alebo atribúty v klauzuli **SELECT** vieme aplikovať aritmetické operácie - Na rozdiel od algebry povoluje duplicity - Ak chceme vynútiť unikátne záznamy, použijeme klauzulu **SELECT DISTINCT** - Ak nie, použijeme klauzulu **SELECT ALL** (default hodnota, nemusíme písať) $$ \text{SELECT <DISTINCT|ALL>}\ a\ \text{FROM}\ r\ \text{WHERE}\ x $$ **Klauzula INSERT** - Zodpovedá operácii zjednotenie $\cup$ - Vloží záznam do tabuľky - Zadané hodnoty musia spĺňať podmienky dátového typu a integrity údajov $$ \text{INSERT INTO}\ r\ \text{VALUES}\ (a,b,c, \ldots)\ $$ **Klauzula UPDATE** - Zodpovedá operácii výberu $\sigma$ a zjednotenia $\cup$ - Upraví ľubovolný počet záznamov tabuľky - Nové hodnoty musia spĺňať podmienky dátového typu, integrity údajov - Voliteľne je možné pridať predikát **WHERE** $$ \text{UPDATE}\ r\ \text{SET}\ a=b\ \text{<WHERE}\ x \text{>} $$ **Klauzula DELETE** - Zodpovedá operácii výberu $\sigma$ - Odstráni ľubovolný počet záznamov tabuľky - Voliteľne je možné pridať predikát **WHERE** $$ \text{DELETE FROM}\ r\ \text{<WHERE}\ x \text{>} $$ ### Agregačné funkcie **Klauzula GROUP BY** - Zoskupí atribúty tabuľky, následne je možne vybrať len skupiny - Na skupinách sa môžu aplikovať agregačné funkcie - Miesto klauzule WHERE sa používa klauzula **HAVING** - Agregačné funkcie sú: - COUNT, AVG, SUM, MIN, MAX - Ak vynecháme GROUP BY, implikuje sa každý atribút $$ \text{SELECT}\ a\ \text{FROM}\ r\ \text{GROUP BY}\ a\ \text{<HAVING}\ x \text{>} $$ ### Spájanie tabuliek **Klauzula NATURAL JOIN** - Zodpovedá operácii natural join $\Join$ - Kombinácia sa robí na základe stĺpcov so spoločným názvom $$ \text{SELECT}\ a\ \text{FROM}\ r\ \text{NATURAL JOIN}\ s $$ **Klauzula INNER JOIN** - Podobné ako NATURAL JOIN, ale musíme špecifikovať cez aké atribúty sa majú tabuľky spojiť klauzulou **ON** - Duplicitné stĺpce sa premenujú automaticky $$ \text{SELECT}\ a\ \text{FROM}\ r\ \text{INNER JOIN}\ s\ \text{ON}\ r.c=s.c $$ **Klauzula OUTER JOIN** - Zodpovedá operácii OUTER JOIN $⟖$ - V závislosti na strane sa určuje správanie pri hodnotnách NULL - či sa také riadky vynechajú alebo nie - Môže byť: LEFT, RIGHT, FULL $$ \text{SELECT}\ a\ \text{FROM}\ r\ \text{<LEFT|RIGHT|FULL>}\ \text{OUTER JOIN}\ s\ \text{ON}\ r.c=s.c $$ ### Ostatné **Trigger** (spúštač) v databázi špecifikuje činnosti, ktoré sa majú previesť nad databázovou tabuľkou v prípade definovanej udalosti. - Udalosťou je zvyčajne vloženie alebo zmazanie dát - Klauzula UPDATE, DELETE, INSERT - Prípadne ich kombinácia - Volitelne sa môže špecifikovať podmienka **WHEN** - Môže byť INSERTING, UPDATING, DELETING - Procedúru, ktorá sa má spustiť začína klauzulou **BEGIN** a končí **END** - Ak chceme aby sa vykonala pre každý riadok tabuľky, navyše vložíme klauzulu **FOR EACH ROW** - Slúžia na zabezpečenie integrity dát v zložitých databázach - Je to typ uloženej procedúry $$ \text{CREATE TRIGGER}\ a\ \text{<BEFORE|AFTER|INSTEAD OF>}\ u\ \text{ON}\ r\ \text{WHEN}\ x $$ **Uložená procedúra** je užívateľom zadefinovaný príkaz alebo dotaz, ktorý je uložený v databáze a je možné ho kedykoľvek zavolať. - Majú svoje parametre a lokálne premenné (označované zavináčom) - Voláme ich klauzulou **EXEC** - Syntax je závislá na konkrétnom jadre databázy - Výhody: potenciálne zrýchlenie vďaka plánovaniu, zaistenie transakcie, bezpečnosť $$ \text{CREATE PROCEDURE}\ a\ @p=\ldots\ \text{AS}\ (...)\ \text{GO} $$ ## Relačná algebra, integritné obmedzenia, riadenie transakcií ### Relačná algebra **Relačná algebra** je formálny dotazovací jazyk. - Využíva **6 základných operácií** - Vstupom operácií môže byť jedna alebo viac relácií a **výstupom je vždy jedna relácia** - To znamená, že operácie sa dajú reťaziť alebo vnárať **Operácie**: - **Selekcia** $\sigma_p(r)=\{ t | t \in r \land P(t) \}$ - Výsledkom je relácia, ktorá spĺňa zadaný predikát $P$ - **Projekcia** $\Pi_{A_1...A_n}(R)$ - Výsledkom je relácia vymenovaných $n$ stĺpcov - Operácia mení relačnú schému výstupnej tabuľky - Duplicitné riadky sú odstránené - **Zjednotenie** $r \cup s = \{ t | t \in r \lor t \in s \}$ - Výsledkom je zjednotenie obidvoch relácií - Musí platiť, že relácie majú rovnakú aritu (počet atribútov) a kompatibilné domény - **Rozdiel** $r - s = \{ t | t \in r \land t \notin s \}$ - Výsledkom je rozdiel dvoch relácií - Musí platiť, že relácie majú rovnakú aritu (počet atribútov) a kompatibilné domény - **Kartézsky súčin** $r \times s = \{ tq | t \in r \land q \in s \}$ - Výsledkom je kartézsky súčin dvoch relácií - Musí platiť, že atribúty sú disjunktné - ak majú niektoré atribúty rovnaké meno, musia sa premenovať - **Premenovanie** $\rho_x(r)$ - Vráti reláciu, ktorej meno a názvy stĺpcov sú potenciálne zmenené podľa $x$ - Príklad $\rho_{m(a,b,c,d)}(r)$ - premenuje $r$ na $m$ a stĺpce na $a,b,c,d$ - Musí platiť, že sa vždy vymenujú všetky názvy stĺpcov, aj keď nemeníme ich meno **Rozšírené operácie**: - **Zobecnená projekcia** - Umožňuje používať v zozname projekcie aritmetické funkcie - **Agregácia** ${}_{G_1...G_n}\ \mathcal{G}_{F_1(A_1)...F_m(A_m)}(r)$ - Aplikuje agregačnú funkciu $F$ na atribút $A$, pričom atribúty sa zoskupia podľa $G$ - Výsledkom je relácia, ktorá obsahuje pre každú skupinu iba jednu hodnotu - V prípade, že všetky atribúty $G$ sú $null$, zoskupia sa podľa $null$ - Všetky operácie okrem $count$ vracajú na $null$ číslo $0$ - Agregačné funkcie: avg, min, max, sum, count ### Spojovanie relácií Relácie spájame pomocou tzv. JOINov (spojení). - JOIN zjednocuje $n$-tice relácií na základe prieniku hodnôt atribútov Rozlišujeme druhy JOINov: - **Natural join** $r \Join s$ - $n$-tice sa zjednotia na základe rovnako pomenovaných atribútov - Príklad pre $R=(A,B,C,D)$ a $S=(E,B,D)$ - $R \Join S = (A,B,C,D,E)$ - $R \Join S = \Pi_{r.A,r.B,r.C,r.D,s.E}(\sigma_{r.B=s.B \land r.D =s.D}(r \times s))$ - **Outer join** - Rozšírenie operácie Natural join - Zabraňuje strate informácií tak, že pridá do výslednej relácie aj $n$-tice ktoré nepatria do spoločného prieniku - Hodnoty nahradí za $null$ - Môže byť: Left $⟕$, Right $⟖$, Full $⟗$ ### Integritné obmedzenia **Integritné obmedzenie** chráni databázu voči náhodnému poškodeniu. - Zabezpečujú, že oprávnené zmeny v databáze nevedú k stráte **konzistencie dát** Zoznam integritných obmedzení: - NOT NULL - atribút nemôže mať hodnotu NULL - UNIQUE - každá hodnota atribútu musí byť unikátna - PRIMARY KEY - definuje primárny kľúč tabuľky - FOREIGN KEY - zaistí, aby hodnota zodpovedala hodnote kľúča v inej tabuľke - Zabezpečuje referenčnú integritu - CHECK - každá hodnota sa skontroluje zadanou podmienkou - DEFAULT - implicitná hodnota atribútu - INDEX - pomáha urýchliť databázu, ak často podľa hodnoty vyhľadávame Príklad (MSSQL T-SQL): ```tsql CREATE TABLE person ( p_id int NOT NULL PRIMARY KEY, op char(10) UNIQUE NOT NULL, name varchar(255) NOT NULL, species varchar(255) DEFAULT ‘human’, j_id int FOREIGN KEY REFERENCES job_table (j_id), CHECK (p_id > 0) ) ``` Integritu vieme obmedziť aj definovaním vlastného dátového typu pomocou **CREATE DOMAIN**. ### Riadenie transakcií **Transakcia** je postupnosť operácií (DML príkazov), ktoré prevedú dátovú schému z jedného konzistentného stavu do druhého. - Transakcia pracuje s databázou vždy v konzistentnom stave - Počas vykonávania transakcie sa môže databáza dostať do nekonzistentného stavu ale na konci jej vyhodnotenia platí, že v konzistentnom stave zostane Transakcia sa riadi pravidlami **ACID**: - **A**tomicity - príkazy nad DB sa vykonajú všetky úspešne, alebo sa nevykonajú žiadne (COMMIT/ROLLBACK) - **C**onsistency - po vykonaní príkazov sa neporušia žiadne integritné obmedzenia - **I**solation - transakcie sú navzájom izolované, zvyčajne určujeme izolačné úrovne podľa potreby - **D**urability - uložené dáta sa budú dať znova načítať v konzistentnom stave, aj po výskytu chyby (napr. výpadok elektriky, crash) - zvyčajne zaručené uložením na disk Transakcia sa môže dostať do nasledujúcich **stavov**: - **Aktívna** (Active) - Transakcia je v tomto stave na začiatku vyhodnotenia - Pokiaľ beží, tak v tomto stave zostáva - **Čiastočne potvrdená** (Partially commited) - Akonáhle bola vykonaná posledná operácia transakcie - **Chybujúca** (Failed) - Po zistení, že beh transakcie nemôže pokračovať - **Zrušená** (Aborted) - Potom, čo bola transakcia zrušená a databáza bola vrátená do pôvodného stavu - **Potvrdená** (Commited) - Po úspešnom dokončení Transakcie vieme izolovať v rôznych **úrovniach izolácie**: - **Read Uncommited** - Najtolerantnejšia úroveň - Transakcia vidí zmeny ostatných transakcií okamžite - Môže nastať problém čítania SELECT nepotvrdených (uncommited) údajov - **dirty read** - Dva po sebe volané dotazy SELECT vrátia rôzne výsledky - **problém neopakovateľného čítania** (non-repeatable read) - Po opakovam volaní SELECT nám pribúdaj/miznú riadky - **fantómové dáta** (phantom data) - **Read Commited** - Transakcia vidí dáta zmenené konkurentnou transakciou až po potvrdení (commited transaction) - Rieši problém s **dirty read**s - **Repeatable Read** - Je zaručené, že v priebehu transakcie nemôže dojsť k problému neopakovateľného čítania - Rieši **non-repeatable read** - **Serializable** - Najvyššia úroveň zabezpečenia izolácie transakcií - Pokiaľ sa detekuje, že iná konkurentná transakcia je nad objektom (row, column, table) už potvrdená (commited), zruší sa (rollback) - Transakcie teda bežia v podstate jedna po druhej (serialized) - Opravuje **problém fantómov**, ale zamedzuje urýchlovacie triky (read-locking, write-locking, snapshotting) Vlastnosti transakcií atomickosti (Atomic) a trvanlivosti (Durability) sú implementované pomocou **tieňovej databázy** (shadowing). - Transakcia sa vykonáva na tieňovej verzii - V prípade chyby sa tieňová vymaže, inak sa stane tou skutočnou Transakcie sa môžu spracovávať **paralelne** (súbežne). - Databáza vytvára pre súbežné transakcie **plán** (schedule) ich spracovania, ktorý musí byť serializovateľný - Plán môže byť conflict alebo view serializable - Conflict serializable - kontroluje sa graf závislostí čítaní a zápisov, ak existuje sériový plán volania transakcií (neexistuje cyklus), tak máme garantované, že po vykonaní akéhokoľvek sériového plánu budú dáta v konzistentnom stave a s minimálnym lockovaním objektov databázy (vysoká priepustnosť operácií) - View serializable - relaxuje podmienku cyklov v conflict serializable pláne, kontroluje sa iba poradie read-write operácií na začiatku, počas behu, a na konci transakcií - V plánoch nás zaujímajú iba operácie čítania a zápisu - Paralelný výpočet je rýchlejší, ale môže dojsť k problémom ako napr. deadlock (cyklická závislosť) ## Indexovanie a hashovanie ### Indexovanie **Indexovanie** je proces, vďaka ktorému zrýchlime prístup k údajom za cenu spomalenia operácií vkladania či odstránenia, ktoré menia dáta indexovaných sĺpcov. Algoritmicky redukujeme počet sekvenčných alebo náhodných prístupov na diskové médium. - Indexovaný stĺpec má priradenú **indexovaciu tabuľku** - zvyčajne omnoho menšiu než súbor celej tabuľky - Indexy môžu byť buď **zoradené** (ordered) alebo **hashované** (hashed) ### Zoradené indexy (ordered index) - Indexové záznamy sú uložené podľa vyhľadávacieho kľúča - **Primárny index** (primary index) - zoradený sekvenčný súbor - Vyhľadávací kľúč určuje poradie záznamu v súbore - Nazývaný aj ako zhlukujúci index (clustering index) - sú podľa neho fyzicky zoradené súbory na disku a môže byť iba jeden v tabuľke - Nemusí byť vo všetkých prípadoch primárnym kľúčom - Môže byť hustý (dense) a riedky (sparse) - **Sekundárny index** (secondary index) - Vyhľadávací kľúč určuje iné poradie než v zoradenom sekvenčnom súbore - Nazývaný nezhlukujúci index (non-clustering index) - Môže byť iba hustý (dense) Index je **hustý (dense)** práve vtedy, ak existuje indexový záznam pre každú hodnotu v tabuľke. - Rovnaké hodnoty sa v indexe neopakujú - Má za následok veľký overhead pri INSERT a DELETE operáciách - Na druhú stranu je rýchlejší pri operáciách JOIN, WHERE oproti sparse index Index je **riedky (sparse)** práve vtedy, ak indexový záznam existuje iba pre niektoré hodnoty v tabuľke. - Musíme najprv nájsť najbližší indexový záznam k našej vyhľadávanej položke - Následne musíme prechádzať tabuľku sekvenčne - Zvyčajne pomalší ako dense index ale zaberá menej miesta na disku (ale viacej v RAM) **Viacúrovňový index (hierarchical index)** používame vtedy, ak sa primárny index nevojde do operačnej pamäte RAM. - Z primárneho indexu sa spraví niekoľko riedkych (sparse) indexov - Proces opakujeme ľubovolne-krát Najpoužívanejšou indexovou štruktúrou v databázach sú **B+ stromy**. - Jedná sa o viacúrovňový index (hierarchical index) v tvare vyváženého $n$-árneho stromu Samotné dáta sa ukladajú rôznym spôsobom - napr. v Postgres sú to 8KB stránkovacie súbory, ktoré sú indexované zvoleným indexom. ### Hashované indexy (hash index) Pri **hashovanom indexe** získavame **kyblíky** (buckets), do ktorých spadajú vyhľadávacie kľúče. - Sú neefektívne pri vyhľadávaní rozsahov (WHERE a.x BIGGER, LESS THAN b.y) - Rozlišujeme dynamické a statické hashovanie - Dynamické umožňuje dynamicky meniť svoju hashovaciu funkciu podľa potrieb velkosti databázy - Vzniká problém pretečenia kyblíkov (overflow) a kolízií (collisions) - Riešené cez overflow chaining - closed hashing **Hashovacia funkcia** je funkcia, ktorá prevádza množinu vyhľadávacích kľúčov na množinu adries jednotlivých kyblíkov. - Používa sa ako pri vyhľadávaní, tak aj pri pridávaní a mazaní záznamov - Ideálna hashovacia funkcia je rovnomerná, každý kýblik ma rovnaký počet priradených záznamov - Snažíme sa minimalizovať možnosť kolízií (slabá, silná bezkolíznosť) ### Využitie pri JOIN operáciách Indexovanie sa používa pri operáciách: - Indexed nested-loop join - Každej $n$-tici nájde druhú pomocou indexu - Na rozdiel od naivného nested loop joinu nám zlepšuje zložitosť na $O(|R|log|S|)$ - Vhodné aj pre non-equi joins (ON a = b WHERE a.x BIGGER, LESS THAN b.y) - Merge join - Relácie sa zoradia podľa indexov a potom sa spoja - Používa sa na equi-join - podmienky WHERE a = b Hashovanie sa využíva pri operácii Hash join. - $n$-tice sa navzájom porovnávajú pomocou obsahu kyblíkov - Vhodné pre JOIN veľkých tabuliek, dobrá zložitosť $O(R+S)$ ale veľký overhead (najmä RAM) - Dá sa paralelizovať - Nevyžaduje indexy na porovnávaných stĺpcoch