Text pro samostudium – náhrada za přednášku a cvičení 6.4.2009
Abstraktní datové typy – Objektový přístup v Oracle Motivace Objektový přístup v Oracle je především umožněn díky uživatelem definovaným (abstraktním) datovým typům, které simulují objekty objektových databází. V čem spočívají výhody objektových přístupů v databázích a jaký vývoj na tomto poli lze sledovat se pokusíme vysvětlit v následujících odstavcích. První objektově orientované databáze se objevily již ve druhé polovině 80. let a vznikly na základě potřeby uchovávat a databázově zpracovávat v pokud možno nezměněné podobě data z programů napsaných v tehdy se rozvíjejících objektově orientovaných programovacích jazycích. Ve srovnání s relačními databázemi, které v té době byly na vrcholu vývoje, to byly systémy velmi neefektivní a málo výkonné, protože se jednalo o experimentální programy psané jako aplikace v nějakém objektovém programovacím jazyce. Po více než dvaceti letech vývoje je však situace jiná. Z praxe již známe případy, kdy nasazení objektové databáze vyřešilo problémy, které relační systém nedokázal zvládnout. Objektové databázové aplikace se objevují již i v ČR. Dnešní objektové databáze mají srovnatelný výkon s velkými relačními systémy – zvládají stovky transakcí za sekundu a tisíce současně připojených uživatelů. S objektovými databázovými aplikacemi se můžeme setkat například v informačních systémech letového provozu (např. Finair, Air France), rezervačních systémech osobní letecké dopravy (např. Fractal s.r.o. u nás v Praze, TourisNet Gran Canaria), informačních systémech pro řízení dopravy zboží (např. Orient Overseas Container Line – jeden z 3 největších dopravců mezi USA a Evropou), informačních systémech dodavatelů elektřiny (např. Floria Power & Light), rezervačních hotelových služeb (např. Navigant International Northwest Travel), systémů pro pojištění (např. povinné ručení automobilů v Argentině) a další. Objektové databáze také používá pro speciální aplikace mnoho firem v kombinaci s relačními. Jsou to například firmy Texas Instruments, BMW, Opel, Ford, JP Morgan, IBM, Hewlett Packard, AT&T a další.
Objektově orientované a objektově relační databáze
Databázové systémy jsou založené na různých datových modelech. Jde o datový model síťový (a jeho variantu hierarchický datový model), relační, objektově relační a objektově orientovaný. Dnes dominuje relační datový model, který ve většině aplikačních oblastí postupně nahradil databáze založené na síťovém datovém modelu. Dnešní praxe však ukazuje, že relační databáze začínají být postupně nahrazovány databázemi objektovými. Pod obecným označením „objektové databáze“ se však skrývají dva vzájemně odlišné datové modely:
Objektově relační datový model Objektově relační datový model představuje evoluční trend vývoje. Jde o doplnění relačního datového modelu o možnost práce s některými datovými strukturami, které známe z oblasti objektově orientovaných programovacích jazyků. Většina výrobců velkých relačních databázových systémů (např. i Oracle) zvolila tuto variantu. Objektově relační datový model ale ve svých principech zůstává původním relačním datovým modelem.
Objektově orientovaný datový model Objektově orientovaný datový model, který představuje revoluční trend vývoje. Jde o nový datový model, který není postaven jako rozšíření relačního datového modelu. Do jisté míry zde jde o renesanci původního síťového datového modelu, který je doplněn o možnost práce s objekty tak, jak je známe z objektového programování. Relačně objektová technologie je dnes rozšířenější. „Nerelační“ objektově orientovaný datový model má však následující přednosti: •
Lépe podporuje datové struktury, které známe z objektově orientovaných programovacích jazyků. Není třeba datové struktury tolik transformovat, aby byly uložitelné do databáze. Existují již prakticky použitelné systémy (např. Gemstone, ObjectStore, O2, Versant, …), které dovolují v databázi zpracovávat objekty ve stejném tvaru, jak se s nimi nakládá v objektových programovacích jazycích.
•
Protože navazuje na síťový datový model, tak má předpoklady pro efektivnější způsoby zpracování dotazů ve srovnání s relačním datovým modelem. Tato vlastnost se projevuje hlavně u složitých datových struktur, které by se podle relačního datového modelu musely rozkládat do mnoha vzájemně provázaných relačních tabulek.
Příčiny, proč jsou zatím objektové databáze méně v praxi rozšířené, než relační, jsou pravděpodobně následující: •
Malá praktická znalost objektových databází v komunitě tvůrců softwaru.
•
Dostupnost systémů na trhu a jejich cena. Velké relačně objektové systémy jsou levnější než objektové. (například komerční cena systému Gemstone je asi 2x větší než Oracle).
•
Konservativní myšlení potenciálních uživatelů a samozřejmě také potřeba zpracovávat již vytvořené báze dat v relačních systémech.
•
Chybějící standardy a nedostatečná podpora metod analýzy a návrhu. Návrh standardu ODMG 3.0 [5] není všemi výrobci respektován. Modelovací jazyk UML nepodporuje všechny konstrukce potřebné k modelování objektové databáze. Metody používané pro návrh relačních databází nejsou vhodné k plnému využití možností objektových databází.
Přes uvedené problémy však existují důvody se domnívat, že význam objektových databází v blízké budoucnosti poroste, protože již dnes existuje celá řada aplikací, kde objektové databáze prakticky prokazují svoje přednosti. Společnou vlastností těchto aplikací je velké množství komplexních datových struktur a jejich proměnlivost za chodu systému, které způsobují problémy relačním databázím. Takové systémy mohou pracovat až se stovkami a tisíci různých vzájemně poskládaných datových typů reprezentovaných třídami objektů. Dotazy nad takovými objekty ještě navíc vyžadují vysokou míru vzájemného polymorfismu. (V takových systémech kupříkladu potřebujeme klást dotazy nad množinami obsahující prvky různého typu. A zároveň očekáváme, že při přidání nového datového typu se nebudou muset přepisovat již hotové dotazy.) Typickým příkladem takových systémů jsou datové sklady, které jsou charakteristické dlouhodobým shromažďováním velkého množství nově vznikajících různorodých dat. Takové systémy jsou charakteristické nejen pro řízení velkých podniků, ale také v různých evidenčních systémech státní správy, zdravotnických systémech, informačních systémech obsahujících ekologické informace, zemědělských informačních systémech, historiografických informačních systémech atp. Na druhou stranu je třeba poznamenat, že relační databáze fungují velmi dobře v oblastech, kde během života systému nedochází k požadavku na změnu struktury databáze a na přidávání dalších datových typů. Relační systém může být výkonný i pokud se databáze
skládá z velkého množství záznamů, ale uložených v malém počtu jednoduše strukturovaných relačních tabulek. POZOR! Student by měl umět odpovědět na tyto otázky: Co to je a k čemu slouží: Objektový datový model Objektově relační datový model Objektový datový typ
Oraclovské uživatelem definované datové typy Datový typ objekt Objektové typy jsou abstrakce reálných objektů, které potřebujeme při vytváření aplikací nad reálnými aplikačními doménami. Objektový typ pracuje se třemi typy komponent: •
Jméno objektového typu, které jednoznačně identifikuje objektový typ ve schématu databáze.
•
Atributy, což jsou vestavěné datové typy nebo uživatelem definované datové typy ve schématu databáze. Pomocí atributů modelujeme strukturu reálných objektů.
•
Metody, což jsou funkce nebo procedury napsané v jazyce PL/SQL a uloženy v databázi. Mohou být rovněž napsány v jazycích jako C nebo JAVA a uloženy externě (mimo databázi). Metody implementují operace, které může aplikace provádět na objektech.
Příklad: Tento příklad ukazuje tvorbu objektového datového typu textdoc_typ a pojmenovaného tabulkového typu textdoc_tab, který se skládá z položek objektového datového typu textdoc_typ.
CREATE TYPE textdoc_typ AS OBJECT ( document_typ VARCHAR2(32) , formatted_doc BLOB ) ; CREATE TYPE textdoc_tab AS TABLE OF textdoc_typ;
Datový typ REF Identifikátor objektu (označovaný OID) jednoznačně identifikuje objekt a umožňuje nám provádět odkazy na objekt z jiného objektového typu nebo referenční tabulky. Datový typ REF je kontejnér pro ukládání identifikátorů objektů. Hodnoty REF jsou ukazatele na jednotlivé objekty. Když REF hodnota ukazuje na neexistující objekt, je označován jako "dangling" (vlající, volně visící), je to něco jiného než když hodnota REF je NULL. Pro zjištění, zda REF je "dangling" nebo ne slouží funkce IS [NOT] DANGLING Příklad: Následující select zobrazuje atribut cust_email, který je součástí tabulky oc_orders, jejíž sloupec customer_ref je datového typu REF. SELECT o.customer_ref.cust_email FROM oc_orders o WHERE o.customer_ref IS NOT DANGLING; Příklad: Datový typ REF lze použít k zobrazení nebo aktualizaci objektů, na které odkazuje. REF lze nastavit na hodnotu NULL. CREATE TYPE emp_person_typ AS OBJECT ( name VARCHAR2(30), manager REF emp_person_typ ); / CREATE TABLE emp_person_obj_table OF emp_person_typ; INSERT INTO emp_person_obj_table VALUES ( emp_person_typ ('John Smith', NULL)); INSERT INTO emp_person_obj_table SELECT emp_person_typ ('Bob Jones', REF(e)) FROM emp_person_obj_table e WHERE e.name = 'John Smith';
Příklad: Příklad demonstruje použití datového typu REF v PL/SQL bloku. Nejdříve si deklarujeme objektový datový typ person_typ (zatím pouze část atributů) a vytvoříme tabulku, která bude obsahovat atributy tohoto typu. Následně jej použijeme při deklaraci proměnné v PL/SQL bloku, do které budeme ukládat data z tabulky . 1. krok – deklarace typu CREATE TYPE person_typ AS OBJECT ( idno NUMBER, first_name VARCHAR2(20), last_name VARCHAR2(25), email VARCHAR2(25), phone VARCHAR2(20) ) / 2. krok – vytvoření tabulky
CREATE TABLE person_obj_table OF person_typ; 3. krok – PL/SQL blok DECLARE person_ref REF person_typ; BEGIN SELECT REF(p) INTO person_ref FROM person_obj_table p WHERE p.idno = 101; END;/ Dotaz musí vrátit právě jeden řádek.
Datový typ Varray Array (pole) je setříděná množina datových elementů. Všechny elementy pole musí být stejného datového typu. Každý element má index, který odkazuje na jeho pozici v poli. Počet elementů v poli určuje velikost pole. Pole v Oracle mají variabilní velikost (z toho i označení varray). Při deklaraci pole je tedy nutné specifikovat maximální velikost pole. Při deklarování pole není alokován prostor, pouze je definován typ elementů. Může být využito těchto typů: •
datový typ atributu v relační tabulce (vestavěné datové typy)
•
objektový datový typ
•
PL/SQL proměnná, parametr
Následující příkaz ukazuje vytvoření struktury phone_list_typ datového tylu Varray, která má pět elementů datového typu VARCHAR2(25). Příklad: Vytvoření datového typu pole, které bude obsahovat 5 hodnot typu VARCHAR2(25), tj. pět možných telefonních čísel. CREATE TYPE phone_list_typ AS VARRAY(5) OF VARCHAR2(25); Příklad: Příklad ukazuje vytvoření datového typu objekt se jménem cust_address. Typ se skládá z položek vestavěného datového typu jako VARCHAR2 nebo CHAR a z uživatelem vytvořeného datového typu phone_list_typ. CREATE TYPE cust_address AS OBJECT ( street_address VARCHAR2(40), postal_code VARCHAR2(10), city VARCHAR2(30), state_province VARCHAR2(10), country_id CHAR(2), phone phone_list_typ, );
Datový typ vestavěná tabulka Datový typ vestavěná tabulka modeluje množinu nesetříděných elementů. Elementy mohou být vestavěvého datového typu nebo uživatelem definovaného datového typu. Vestavěná tabulka může obsahovat jednoduché sloupce nebo, pokud je vestavěná tabulka objektového datového typu, složené sloupce z více sloupců pro každý atribut objektového datového typu. Stejně jako u pole při deklarování pole není alokován prostor, pouze je definován typ elementů. Může být využito těchto typů: •
datový typ atributu v relační tabulce (vestavěné datové typy)
•
objektový datový typ
•
PL/SQL proměnná, parametr
Příklad : Definice datového typu vestavěná tabulka. Create type adresa as table (ulice varchar2(20), cislo varchar2(10), město varchar2(20));
Typy metod Metody objektových datových typů modelují chování objektů. Obvykle jsou rozdělovány do tří kategorií. •
Member metoda je funkce nebo procedura, které má vždy implicitní SELF parametr jako svůj první parametr, který je objektového datového typu.
•
Statická metoda je funkce nebo procedura, která nemá SELF parametr. Statické metody se používají pro specifikaci uživatelem definovaného konstruktoru .
•
Metody pro uspořádání, které mohou porovnávat instance.
Každý objektový typ má jednu implicitně definovanou metodu – konstruktor objektového typu.
Konstruktory objektového typu Každý objektový typ má systémem definovanou metodu – konstruktor. Tato metoda vytváří nový objekt podle specifikace objektového datového typu. Jméno konstruktoru je stejné jako jméno objektového datového typu. Konstruktor je funkce, která vrací nový objekt jako svou hodnotu.
Metody pro uspořádání Oracle má nástroje na porovnávání dvou datových položek vestavěného datového typu (např. numer, atd.) a je schopen určit, zda jedna položka je větší, rovna nebo menší než druhá položka. Oracle však neumí porovnat dvě položky, které jsou definovány nad uživatelem definovanými datovými typy. Pro tuto činnost jsou k dispozici dvě metody (Map, Order) Metoda Map Metoda Map využívá schopnosti Oracle porovnávat položky vestavěného datového typu. Metoda je založena na principu převodu objektu na skalár. Např. miáme-li objektový typ
obdélník s atributy šířka a výška můžeme definovat metodu obsah, která vrací číslo (skalár). Dva obdélníky pak můžeme porovnávat podle jejich obsahu. Příklad: CREATE TYPE obdelnik_typ AS OBJECT ( sirka NUMBER, vyska NUMBER, MAP MEMBER FUNCTION obsah RETURN NUMBER ); CREATE TYPE BODY obdelnik_typ AS MAP MEMBER FUNCTION obsah RETURN NUMBER IS BEGIN RETURN SELF.sirka * vyska; END obsah; END;
Metoda Order Tato metoda je obecnější. Používá svou vnitřní logiku pro porovnávání objektů. Vrací hodnotu, která kóduje porovnávací vztah mezi objekty. Např. vrací -1 je-li první objekt menší, 0 jsou-li objekty rovny a 1 je-li první objekt větší. Předpokládejme, že máme objektový typ adresa s atributy ulice, město, stát, PSČ. V takovém případě nemá význam definovat porovnání větší než, resp. menší než. Můžeme však využít porovnání, zda dvě adresy jsou stejné. Při definování objektového datového typu můžeme specifikovat buď metodu Map nebo metodu Order, nikoli obě. Pokud nemá objektový datový typ definovanou metodu pro uspořádání, nedokáže zjistit, zda jeden objekt je větší nebo menší než druhý. Může se pokusit zjisti, zda objekty jsou stejné. Postupuje podle následujícího algoritmu: •
Jestliže všechny atributy nenabývají hodnoty null a jsou stejné, pak Oracle vyhodnotí oba objekty jako stejné.
•
Pokud existuje atribut, který je pro oba objekty různý a nenabývá hodnoty NULL, pak objekty nejsou stejné.
•
V ostatních případech Oracle není schopen vyhodnotit, zda objekty jsou stejné nebo různé.
Příklad: Příklad specifikuje a volá Member metodu col.get_square
a implicitní konstruktor
demo_typ2(2) 1. krok: - vytvoří datový typ, který obsahuje jeden atribut a1 a jednu metodu get_square. CREATE TYPE demo_typ2 AS OBJECT (a1 NUMBER, MEMBER FUNCTION get_square RETURN NUMBER); 2. krok – vytvoří tabulku se sloupcem col, který je vytvořeného datového typu. CREATE TABLE demo_tab2(col demo_typ2); 3. krok – vloží do tabulky hodnotu (využije konstruktor stejného jména jako je jméno objektového datového typu). INSERT INTO demo_tab2 VALUES (demo_typ2(2)); 4. krok – vytvoří Member metodu get_square a tuto metodu vyvolá. CREATE TYPE BODY demo_typ2 IS MEMBER FUNCTION get_square RETURN NUMBER IS x NUMBER; BEGIN SELECT c.col.a1*c.col.a1 INTO x FROM demo_tab2 c; RETURN (x); END; END; / SELECT t.col.get_square() FROM demo_tab2 t; 5. výsledek volání T.COL.GET_SQUARE() -----------------4 Příklad: Příklad na tvorbu statické metody
1. krok – vytvoření typu department_t a employee_t, který deklaruje statickou metodu (konstruktor) construct_emp CREATE TYPE department_t AS OBJECT ( deptno number(10), dname CHAR(30)); CREATE TYPE employee_t AS OBJECT( empid RAW(16), ename CHAR(31), dept REF department_t, STATIC function construct_emp (name VARCHAR2, dept REF department_t) RETURN employee_t ); 2. krok – vytvoří tělo metody CREATE TYPE BODY employee_t IS STATIC FUNCTION construct_emp (name varchar2, dept REF department_t) RETURN employee_t IS BEGIN return employee_t(SYS_GUID(),name,dept); END; END; 3. krok – vytvoří tabulku a vloží do ní data s využitím vytvořeného konstruktoru. CREATE TABLE emptab OF employee_t; INSERT INTO emptab VALUES (employee_t.construct_emp('John Smith', NULL)); POZOR! Student by měl umět odpovědět na tyto otázky: Co to je a k čemu slouží: Datový typ objekt Datový typ REF, operátor REF Datový typ Varray Datový typ vestavěná tabulka Konstruktor Metoda Map Metoda Order Statické metody