Warning
This page is located in archive.

This is an old revision of the document!


Pokročilé databázové techniky

Pokročilé databázové systémy umožňují zjednodušit dotazování nad daty pomocí pohledů, použití uložených procedur. Zárověň pomocí triggerů (spouštěčů) umožňují ovlivňovat výsledky zapisovacíh operací (INSERT, UPDATE,DELETE), případně jejich prostřednictvím vyjádřit složitější integritní omezení (včetně minimálních a maximálních parcialit)

Pohledy

Pokud se při různých dotazech opakují spojování tabulek, podmínky či agregace; nebo je-li účelné zviditělnit některou (pod)sestavu, je možné tuto opakující se část nahradit pohledem. Pohled typicky koncovému uživateli umožňuje náhled na data bez použití denormalizace, zatímco data jsou bezpečně uložena v normovaném tvaru.

Pohled může být

  • nematerilizovaný - v takovém případě se chová jako v prostoru deklarací tabulek vnořený SELECT, t.j. zejména je evaluován v okamžiku volání dotazu
  • materilizovaný - je to tabulka prostředky databázového systému (zejména triggery) svázaná se “zdrojovými” tabulkami

Nematerializované pohledy se vytvářejí pomocí CREATE VIEW . Pro vytváření materializovaných pohledů lze standardně použít konstrukce CREATE TABLE AS a následně ji doplnit o volání triggerů nad zdrojovými tabulkami zajištující aktuálnost dat pohledu; některé databáze umožňují tento proces zautomatizovat pomocí konstrukce CREATE MATERIALIZED VIEW .

Ačkoliv do pohledu nelze zapisovat, lze tuto funkcionalitu doplnit pomocí tzv. pravidel, viz CREATE RULE. Některé databázové systémy tyto pravidla zavádějí defaultně při založení pohledu

Příklad

Vytvořte sestavu pro vypsání položek na faktuře:

CREATE VIEW fakturalist AS SELECT
  id_faktura,
  zbozi.nazev, ks,
  fakturazbozi.cena AS cena_ks, fakturazbozi.sleva AS sleva, 
  fakturazbozi.cena * fakturazbozi.ks * (CASE WHEN fakturazbozi.sleva IS NULL THEN 1 ELSE 1-fakturazbozi.sleva END) as cenacelkem

FROM zbozi
  JOIN zbozifaktura USING (id_zbozi)

Uložené procedury

Uložené procedury, někdy označované jako databázové funkce, umožňují definovat složitější uživatelské výpočty. Různé databázové systémy podporují různé procedurální jazyky.

Pro vytváření uložených procedur použijte CREATE FUNCTION , z důvodu optimalizace nezapomeňte na modifikátory jako IMMUTABLE, STABLE, VOLATILE nebo RETURNS NULL ON NULL INPUT.

Příklad

Vytvořte funkci pro exponenciální zapomínání.

CREATE OR REPLACE FUNCTION oblivion(timestamp with time zone) RETURNS float AS $_$
  SELECT exp((extract(epoch from $1) - extract (epoch from now()))/(3600*24*2)); $_$ LANGUAGE 'sql';

Všimněte si, že je bezpodíněčně nutné, aby SELECT vrátil pouze jednu hodnotu (identicky se vnořeným SELECTem na pozici hodnot). U uložených procedur je navíc kontrolována shoda mezi deklarovaným a vráceným typem.

Příklad

Vytvořte funkci nahrazující funkcionalitu jednoatributového textového primárního klíče (t.j. funkci, která převede textový primární klíč na int)

CREATE OR REPLACE FUNCTION indexzbozi(varchar) RETURNS int AS $_$
DECLARE
ret	int;
BEGIN
ret = (SELECT id_zbozi FROM zbozi WHERE nazev=$1);
IF ret IS NULL THEN 
    ret=nextval('seq_zbozi');
    INSERT INTO zbozi(id_zbozi,nazev) VALUES (ret,$1);
    RAISE NOTICE 'indexzbozi (%) - nove id=%',$1, ret;
ELSE
    RAISE NOTICE 'indexzbozi (%) = %',$1,ret ;
END IF;
RETURN ret;
END; $_$ LANGUAGE 'plpgsql' ;

Použití:

SELECT indexzbozi('ponozky');

Jazyk plpgsql umožňuje zejména větvení, cykly i obsluhu vyjímek.

Tabulkové uložené procedury

Uložené procedury nemusejí vracet pouze jednu hodnotu, ale i celou tabulku.

Příklad

Vytvořte tabulkovou uloženou proceduru na výtisk faktury.

CREATE OR REPLACE FUNCTION polozkyfaktury(int) RETURNS set of fakturalist AS $_$
  SELECT * FROM fakturalist WHERE id_faktura = $1; $_$ LANGUAGE 'sql';

Použití:

SELECT * FROM polozkyfaktury(10) AS seznam;

Pokud vrácený výsledek neodpovídá žádnému existujícímu typu, pohledu či tabulce, je možné použít generický typ RECORD. Při dotazování je však nezbytně v SELECTu mnutné provést výčet atributů včetně jejich typů.

Triggery

Se zapisovacími operacemi lze svázat volání uložených procedur pomocí triggerů.

Trigger může být volán

  • před nebo po provedení operace
  • pro každý záznam nebo pro každý příkaz (příkaz může ovlivnit více záznamů)

Pokud obslužná procedura triggeru před voláním operace vrátí NULL, operace je zrušena (t.j. neprovede se). Podobně obslužná procedura může vyvolat vyjímku - opět dochází k přerušení operace.

Příklad:

CREATE OR REPLACE FUNCTION trg_odectizeskladuzbozi() RETURNS TRIGGER AS $_$
BEGIN
  UPDATE sklad SET ks = ks - NEW.ks WHERE id_zbozi = NEW.id_zbozi;
  RETURN NEW;
END;  $_$ LANGUAGE 'plpgsql' 

CREATE TRIGGER trg_odectizeskladuzbozi BEFORE INSERT TO fakturazbozi FOR EACH ROW EXECUTE PROCEDURE trg_odectizeskladuzbozi;

Dalsi priklad triggeru realizujici slozitejsi integritni omezeni - viz http://www.postgresql.org/docs/current/static/plpgsql-trigger.html

courses/a4b33ds/cviceni-8.1487175025.txt.gz · Last modified: 2017/02/15 17:10 by komenant