Objektumorientlt adatbzisnyelvek Objektumler nyelv Objektumlekrdez nyelv 1 Objektumelv

Objektumorientált adatbázisnyelvek Objektumleíró nyelv Objektumlekérdező nyelv 1

Objektumelvű adatbáziskezelők u. Szabványosító csoport: ODMG = Object Data Management Group. u. ODL = Object Description Language, mint az SQL CREATE TABLE része. u. OQL = Object Query Language, az SQLt próbálja utánozni OO keretrendszerben. 2

Keretrendszer --- 1 u. Az ODMG elképurlése szerint az OODBMS gyártok megvalósítanak egy OO nyelvet, mint a C++, olyan kiterjesztésekkel (OQL), amelyekkel a programozó zökkenőmentesen átviheti az adatokat az adatbázis és a „gazdanyelv” között. 3

Keretrendszer --- 2 u. Az ODL-t tartós osztályok definiálására használjuk, amelyek objektumai maradandóan tárolhatók az adatbázisban. w Az ODL osztályok olyanok, mint az egyedhalmazok bináris kapcsolatokkal és metódusokkal. w Az ODL osztálydefiníciók a kibővített OO gazdanyelv részei. 4

ODL áttekintés u Egy osztálydeklaráció tartalmazza: 1. Az osztály nevét. 2. Választhatóan kulcsdeklaráció(ka)t. 3. Extens deklaráció = az osztály létező objektumait tartalmazó halmaz neve. 4. Elemdeklarációkat. Egy elem lehet attribútum, kapcsolat vagy metódus. 5

Osztálydefiníciók class <név> { <elemdeklarációk pontosvesszővel tagolt listája> } 6

Attribútum- és kapcsolatdeklarációk u. Az attribútumok (általában) osztályhoz nem kapcsolódó típusú elemek. attribute <típus> <név>; u. A kapcsolatok egy objektumot egy vagy több, azonos osztálybeli objektumhoz kapcsolják. relationship <típus> <név> inverse <kapcsolat>; 7

Inverz kapcsolatok u. Tegyük fel, hogy a C osztály R kapcsolatban áll a D osztállyal. u. Ekkor a D osztálynak valamilyen S kapcsolatban kell állnia a C osztállyal. u. R-nek és S-nek egymás inverzének kell lennie. w Ha a d R kapcsolatban van c-vel, akkor cnek S kapcsolatban kell lennie d-vel 8

Példa: Attribútumok és kapcsolatok class Kocsma { Az árul kapcsolat típusa attribute string név; Sör objektumok halmaza. attribute string cím; relationship Set<Sör> árul inverse Sör: : kapható; } A : : operátor összekapcsolja class Sör { a jobb oldalon álló nevet az attribute string név; azt tartalmazó környezettel, amely a bal oldalon áll. attribute string gyártó; relationship Set<Kocsma> kapható inverse Kocsma: : árul; } 9

Kapcsolatok típusai u Egy kapcsolat típusa lehet: 1. Osztály, pl. Kocsma. Ebben az esetben egy objektum csak egy Kocsma objektummal állhat kapcsolatban. 2. Set<Kocsma>: az objektum Kocsma objektumok halmazával van kapcsolatban. 3. Bag<Kocsma>, List<Kocsma>, Array<Kocsma>: az objektum Kocsma objektumokból álló zsákkal, listával vagy tömbbel van kapcsolatban. 10

Kapcsolatok multiplicitása u. Minden ODL kapcsolat bináris. u. A sok-sok kapcsolatok típusa Set<…> a kapcsolat és inverz oldalon is. u. A sok-egy kapcsolatok típusa Set<…> az „egy” oldalon és csak osztály a „sok” oldalon. u. Az egy-egy kapcsolatok típusa mindkét irányban az osztály. 11

Példa: Multiplicitások class Ivó { … relationship Set<Sör> szeret inverse Sör: : rajongók; relationship Sör kedvenc. Sör inverse Sör: : nagy. Rajongók; } Sok-sok: Set<…> mindkét irányban. class Sör { … relationship Set<Ivó> rajongók inverse Ivó: : szeret; relationship Set<Ivó> nagy. Rajongók inverse Ivó: : kedvenc. Sör; } Sok-egy: Set<…> csak az „egy” oldalon. 12

Másik példa multiplicitásra férj és feleség: egy-egy kapcsolatok és egymás inverzei class Ivó { attribute … ; relationship Ivó férj inverse feleség; relationship Ivó feleség inverse férj; relationship Set<Ivó> haverok inverse haverok; } haverok: sok-sok kapcsolat és a saját inverze. Nem kell a : : , ha az inverz ugyanabban az osztályban van. 13

Többirányú kapcsolat kezelése u. Az ODL nem támogatja a 3 - vagy többirányú kapcsolatokat. u. Szimulálhatjuk a többirányú kapcsolatokat egy „kapcsoló” osztállyal, amelynek objektumai reprezentálják az összekapcsolandó objektum n-eseket. 14

Kapcsoló osztályok u. Tegyük fel, hogy az X, Y és Z osztályokat akarjuk összekapcsolni R kapcsolattal. u. Vegyünk fel egy C osztályt, amelynek objektumai az (x, y, z) hármasokat reprezentálják az X, Y, Z osztályokból. u. Három sok-egy kapcsolatra lesz szükségünk (x, y, z)-ből x, y és z mindegyikéhez. 15

Példa: Kapcsoló osztály u. Tegyük fel, hogy van Kocsma és Sör osztályunk és szeretnénk reprezentálni, hogy melyik kocsma milyen áron adja a söröket. w A Kocsma és Sör közti sok-sok kapcsolatnak nem lehet ár attribútuma, szemben az E/K modellel. u. Egy megoldás: készítsünk egy Ár osztályt és egy összekapcsoló BBP osztályt, amely az egymáshoz kapcsolódó kocsmákat, söröket és árakat reprezentálja. 16

Példa, folytatás u Mivel az Ár objektumok csak számok, egy jobb megoldás: 1. Adjunk a BBP objektumokhoz egy ár attribútumot. 2. Használjunk két sok-egy kapcsolatot a BBP objektum és az általa reprezentált Kocsma és Sör objektumok között. 17

Példa, befejezés u. Itt a BBP definíciója: class BBP { attribute ár: real; relationship Kocsma a. Kocsma inverse Kocsma: : to. BBP; relationship Sör a. Sör inverse Beer: : to. BBP; } u. A Kocsma és Sör osztályokat módosítsuk, hogy mindkettőnek legyen to. BBP tulajdonsága, amelyek típusa Set<BBP>. 18

Struktúrák és felsorolások u. Az attribútumok lehetnek struktúrák (mint a C-ben) vagy felsorolások. uÍgy deklaráljuk: attribute [Struct vagy Enum] <struct vagy enum neve> { <részletek> } <attribútum neve>; u. A részletek mezőnevek és -típusok Struct -nál, konstansok listája Enum-nál. 19

Példa: Struct és Enum A struktura és class Kocsma { felsorolás neve attribute string név; attribute Struct Cím. T {int irsz, string város, string utca} cím; attribute Enum Eng { MINDEN, SÖR, SEMMI } engedély; relationship … attribútumok neve } 20

Struct és Enum újrahasznosítása u. Hivatkozhatunk egy Struct vagy Enum nevére másik osztálydefinícióban. w Használjuk a : : operátort a forrásosztály jelölésére. u. Példa: Ugyanazt az irsz-város-utca class Ivó { címtípust használjuk attribute string név; attribute Struct Kocsma: : Cím. T cím; … 21

Metódusdeklarációk u Egy osztálydefiníció tartalmazhatja az osztályban levő metódusok deklarációit. u Az információ tartalma: 1. Visszatérésí érték típusa, ha van. 2. Metódus neve. 3. Argumentumok módja és típusa (nincs név). w A mód lehet in, out és inout. 4. Kivételek, amelyeket a metódus kiválthat. 22

Példa: Metódusok real átlag(in string)raises(nincs. Jegy); 1. Az átlag függvény egy valós számot ad vissza (feltehetőleg egy hallgató átlagát). 2. Az átlagnak egy argumentuma van, egy string (feltehetőleg a hallgató neve) és nem módosítja az argumentumát. 3. Az átlag kiválthatja a nincs. Jegy 23 kivételt.

Az ODL típusrendszer u. Alaptípusok: int, real/float, string, felsorolás típusok és osztályok. u. Típuskonstruktorok: w Struct a struktúrákhoz. w Kollekció típusok : Set, Bag, List, Array és Dictionary ( = leképezés egy értelmezési tartományból egy képhalmazba). u. A kapcsolatok típusa csak osztály vagy egy osztályra alkalmazott kollekció lehet. 24

ODL alosztályok u. A szokásos objektumorientált alosztályok. u. A szülőosztályt kettősponttal és névvel jelöljük. u. Az alosztályban csak az egyedi tulajdonságait soroljuk fel. w Megörökli a szülőosztály tulajdonságait is. 25

Példa: Alosztályok u. Az ale a sör alosztálya: class Ale: Sör { attribute string szín; } 26

ODL kulcsok u. Deklarálhat akárhány kulcsot egy osztályhoz. u. Az osztály neve után adjuk meg: (key <kulcslista>) u. Egynél több attribútumot tartalmazó kulcsot az attribútumok köré tett külön zárójellel jelöljük. 27

Példa: Kulcsok class Sör (key név) { … ua név a sör kulcsa. class Kurzus (key (tanszék, szám), (hely, idő)){ ua tanszék és szám az egyik kulcs, a hely és idő a másik. 28

Extensek u. Minden osztályhoz tartozik egy extens, amely az osztályhoz tartozó létező objektumokat tartalmazó halmaz. w Az extens hasonló egy relációhoz, amelynek az osztály a sémája. u. Az extenst az osztály neve után tüntetjük fel a kulcsokkal együtt, így: (extent <extens neve> … ) 29

Példa: Extensek class Sör (extent Sörök key név) { … } u. Konvenció szerint egyes számot használunk az osztály nevének, többes számot a hozzá tartozó extensnek. 30

OQL u. Az OQL az objektumorientált lekérdezés szabványa. u. Az ODL-t használja sémadefiníciós nyelvként. u. Az OQL típusai olyanok, mint az ODL-ben. u. A relációk szerepét a Set(Struct) és a Bag(Struct) játssza. 31

Útvonal-kifejezések u Legyen x a C osztály egy objektuma. 1. Ha a egy attribútuma C-nek, akkor x. a az attribútum értéke. 2. Ha r egy kapcsolata C-nek, akkor x. r az az érték, amelyhez x kapcsolódik r által. w Lehet egy objektum vagy objektumok halmaza, r típusától függően. 3. Ha m egy metódusa C-nek, akkor x. m(…) az m x-re való alkalmazásának eredménye. 32

Futó példa class Eladás (extent Eladások) { attribute real ár; relationship Kocsma kocsma inverse Kocsma: : eladott. Sörök; relationship Sör sör inverse Sör: : eladói; } class Kocsma (extent Kocsmák) { attribute string név; attribute string cím; relationship Set<Eladás> eladott. Sörök inverse Eladás: : kocsma; } 33

Futó példa, befejezés class Sör (extent Sörök) { attribute string név; attribute string gyártó; relationship Set<Eladás> eladói inverse Eladás: : sör; } 34

Példa: Útvonal-kifejezések u Legyen s egy Eladás típusú változó, azaz kocsma-sör-ár objektum. 1. s. ár = az ár az s objektumban. 2. s. kocsma. cím = s-ből a kocsma kapcsolat mentén elért kocsma címe w Itt a pontok egymásba ágyazása helyes, mert s. bar egy objektum, nem objektumok kollekciója. 35

Példa: A pont helytelen használata u. Nem használhatjuk a pontot, ha a bal oldalon egy kollekció áll, hanem csak akkor, ha egyetlen objektum. u. Példa (helytelen), ahol b egy Kocsma: b. eladott. Sörök. ár Ez a kifejezés Eladás típusú objektumok halmaza. Nincs neki ára. 36

OQL Select-From-Where u. Relációjellegű kollekciókat számolhatunk ki OQL utasítással: SELECT <értéklista> FROM <kollekciók és típusjellemzők listája> WHERE <feltétel> 37

FROM részmondat u Minden tagja az alábbi formájú: <kollekció> <tag neve> u Kollekció lehet: 1. Valamelyik osztály extense. 2. Egy kifejezés, amelynek értéke kollekció, pl. b. eladott. Sörök. 38

Példa u. Kérdezzük le Józsi kocsmájában az itallapot. SELECT s. sör. név, s. ár FROM Eladások s WHERE s. kocsma. név = "Józsi kocsmája" Az Eladások az összes Eladás objektumot tartalmazó extens. s sorra felveszi mindegyik objektum értékét. Helyes kifejezések. s. sör egy sör objektum, s. kocsma egy Kocsma objektum. Az OQL idézőjeleket használ. 39

Másik példa u Ez is megszerzi Józsi itallapját: SELECT s. sör. név, s. ár FROM Kocsmák b, b. eladott. Sörök s WHERE b. név = "Józsi kocsmája" b. eladott. Sörök egy Eladás objektumokból álló halmaz, most pedig egy tipikus eladás objektum, amely Józsi kocsmájával kapcsolatos. 40

Trükkök útvonal-kifejezésekkel u. Ha egy útvonal-kifejezés egy objektumot jelöl, akkor kiterjesztheti egy ponttal és az objektum egy tulajdonságával. w Példa: s, s. kocsma. név u. H a egy útkifejezése kollekciót jelöl, akkor nem terjesztheti ki, de felhasználhatja a FROM részmondatban. w Példa: b. eladott. Sörök 41

Az eredmény típusa u. Alapértelmezésben a select-from-where eredményének típusa egy struktúrákból álló zsák. w A struktúrának egy-egy mezője van a SELECT részmondat minden tagjához. A neve és típusa megegyezik az útvonal-kifejezés utolsó elemével. u. Ha a SELECT csak egytagú, akkor technikailag az eredmény egymezős struktúra. w Viszont az egyelemű struktúra azonosítható az egy elemmel. 42

Példa: Eredménytípus SELECT s. sör. név, s. ár FROM Kocsmák b, b. eladott. Sörök s WHERE b. név = "Józsi kocsmája" u. Típusa: Bag(Struct(név: string, ár: real)) 43

Mezők átnevezése u. Mezők átnevezéséhez tegyük elé az új nevet és egy kettőspontot. u. Példa: SELECT sör: s. sör. név, s. ár FROM Kocsmák b, b. eladott. Sörök s WHERE b. név = "Józsi kocsmája" u. Az eredmény típusa: Bag(Struct(sör: string, ár: real)). 44

Struktúrák halmazának előállítása u. Adjuk hozzá a DISTINCT kulcsszót a SELECT után, így az eredmény egy halmaz lesz és a duplikált elemek törlődnek. u. Példa: SELECT DISTINCT s. sör. név, s. ár FROM Kocsmák b, b. eladott. Sörök s WHERE b. név = "Józsi kocsmája" u. Az eredmény típusa: Set(Struct(név: string, ár: string)) 45

Struktúrák listájának előállítása u. Használjuk az ORDER BY részmondatot, mint az SQL-ben, így az eredmény egy lista lesz, amelyben a struktúrák az ORDER BY-ban felsorolt mezők szerinti sorrendben lesznek. w Növekvő (ASC) az alapértelmezett; csökkenő (DESC) is lehetséges. u. A lista elemeit indexekkel érhetjük el: [1], [2], … u. Az SQL kurzorokhoz hasonló lehetőségeket ad. 46

Példa: Listák u. Legyen joe. Menu egy gazdanyelvi változó ezzel a típussal: List(Struct(név: string, ár: real)) joe. Menu = SELECT s. sör. név, s. ár FROM Kocsmák b, b. eladott. Sörök s WHERE b. név = "Józsi kocsmája" ORDER BY s. ár; 47

Példa, folytatás u. Most a joe. Menu értéke egy lista, amelynek elemei a Józsi által eladott sörök név-ár párjai. u. Elérhetjük az első (legolcsóbb) elemet joe. Menu[1], a következőt joe. Menu[2] alakban stb. u. Példa: Józsi legolcsóbb sörének neve: legolcsóbb = joe. Menu[1]. név; 48

Példa, befejezés u. Miután kiértékeltük a joe. Menu-t, kiírhatjuk Józsi itallapját efféle kóddal: cout << "SörtÁrnn"; for (i=1; i<=COUNT(joe. Menu); i++) cout << joe. Menu[i]. name << “t” << joe. Menu[i]. price << “n”; COUNT megadja a kollekció elemszámát. 49

Alkérdések u Egy select-from-where kifejezés körülvehető zárójelekkel és felhasználható alkérdésként többféle módon, pl. 1. FROM részmondatban kollekcióként. 2. EXISTS és FOR ALL kifejezésben. 50

Példa: Alkérdés FROM-ban u. Keressük meg a Józsi által kínált sörök gyártóit: Sör objektumok SELECT DISTINCT b. gyártó zsákja, a Józsi által eladott sörökkel FROM ( SELECT s. sör FROM Eladások s WHERE s. kocsma. név = "Józsi kocsmája" )b Technikailag egytagú struktúra Sör objektummal, de azonosítható magával az objektummal 51

Kvantorok u. Két logikai értékű kifejezés, amely a WHERE részmondatban használható: FOR ALL x IN <kollekció> : <feltétel> EXISTS x IN <kollekció> : <feltétel> u. Igaz akkor és csak akkor, ha minden (ill. legalább egy) eleme a kollekciónak kielégíti a feltételt. 52

Példa: EXISTS u. Keressük meg azoknak a kocsmáknak a nevét, amelyeknél kapható legalább egy 1000 Ft-nál drágább sör. SELECT b. név FROM Kocsmák b WHERE EXISTS s IN b. eladott. Sörök : s. ár > 1000 Legalább egy b-hez tartozó Eladás objektum ára nagyobb, mint 1000 53

Másik kvantoros példa u. Keressük meg azoknak a kocsmáknak a nevét, amelyek összes 1000 Ft-nál drágább sörét a Pete’s gyártja. SELECT b. név FROM Kocsmák b WHERE FOR ALL be IN ( SELECT s. sör FROM b. eladott. Sörök s WHERE s. ár > 1000 ) : be. gyártó = "Pete’s" Sör objektumok zsákja (struktúrákon belül), b bár 1000 Ft-nál drágább söreivel. Az egytagú struktúrák automatikusan kibontásra kerülnek, így be tekinthető Sör objektumnak. 54

Egyszerű kényszerítések u. Ahogy már láttuk, az egytagú struktúra automatikusan konvertálódik az egy tag értékévé. w Struct(f : x) kényszerül x-szé. u. Az egyetlen elemet tartalmazó kollekció kényszeríthető az elemmé, de ehhez szükséges az ELEMENT operátor. w Pl. ELEMENT(Bag(x )) = x. 55

Példa: ELEMENT u. Adjuk értékül a valós típusú p-nek, hogy mennyiért adja Józsi a Bud-ot. p = ELEMENT( SELECT s. ár FROM Eladások s WHERE s. kocsma. név = "Józsi kocsmája" AND s. sör. név = "Bud" ); Egyelemű zsák egy struktúrával, amelynek egyetlen tagja a Bud ára Józsinál 56

Aggregációk u. AVG, SUM, MIN, MAX és COUNT használható minden kollekcióra, ha van értelme. u. Példa: Számítsuk ki a Józsi által eladott sörök átlagárát. x = AVG( SELECT s. ár FROM Eladások s WHERE s. kocsma. név = "Józsi kocsmája" ); Zsák olyan struktúrákkal, amelyek a Józsi által eladott sörök árait tartalmazzák 57

Csoportosítás u Emlékezzünk az SQL csoportosításra: 1. Rekordok csoportjai bizonyos (csoportosító) attribútumok alapján 2. A SELECT részmondat csak olyan elemeket tud kivenni a csoportból, amelyeknek van értelme: w Csoporton belüli aggregáció. w Csoportosító attribútumok, amelyek értéke a csoporton belül konstans. 58

OQL csoportosítás u Az OQL többféle módon kibővíti a csoportosítás fogalmát: 1. Bármilyen kollekció csoportokra bontható. 2. A csoportok az eredeti kollekció objektumainak tetszőleges függvénye alapján létrejöhetnek. 3. A lekérdezés eredménye a csoportok bármilyen függvénye lehet. 59

Az OQL GROUP BY vázlata Kezdeti kollekció FROM, WHERE alapján Csoportosítás függvényérték szerint Köztes kollekció, függvényértékekkel és partíciókkal SELECT részmondat tagjai Kimeneti kollekció 60

Példa: GROUP BY u. Ezeket a fogalmakat egy példán keresztül nézzük át: „Határozzuk meg minden kocsmában a sörök átlagárát. ” SELECT kocsma. Név, átlagÁr: AVG( SELECT p. s. ár FROM partition p) FROM Eladások s GROUP BY kocsma. Név: s. kocsma. név 61

Kezdeti kollekció u. A FROM és WHERE (itt hiányzik) alapján: FROM Eladások s u. A kezdeti kollekció egy zsák struktúrákkal, amelyek egyetlen mezője a FROM részmondat „tipikus eleme”. u. Itt egy zsák Struct(s: obj ) alakú struktúrákkal, ahol obj is egy Eladás objektum. 62

Köztes kollekció uÁltalában egy zsák struktúrákkal, amelyek rendelkeznek egy-egy taggal a GROUP BY részmondat minden függvényéhez, ezenkívül egy partition nevű taggal. u. A partíció értéke az eredeti kollekció azon elemeinek halmaza, amelyek a vizsgált struktúrával azonos csoportba tartoznak. 63

Példa: Köztes kollekció SELECT kocsma. Név, átlagÁr: AVG( SELECT p. s. ár FROM partition p) FROM Eladások s GROUP BY kocsma. Név: s. kocsma. név Egy csoportosító függvény. A neve kocsma. Név, típusa string. A köztes kollekció struktúrák halmaza, ahol a mezők kocsma. Név: string és partition: Set<Struct{s: Eladás}> 64

Példa: Tipikus tag u. Egy tipikus tag a köztes kollekcióban a példánkban: Struct(kocsma. Név = "Józsi kocsmája", partition = {s 1, s 2, …, sn }) u. A partíció minden eleme egy si Eladás objektum, ahol si. kocsma. név értéke „Józsi kocsmája”. 65

A kimeneti kollekció u. A kimeneti kollekciót a SELECT részmondat számolja ki, szokás szerint. u. GROUP BY részmondat nélkül a SELECT részmondat a kezdeti kollekcióból állítja elő a kimenetét. u. GROUP BY esetén a SELECT eredménye a köztes kollekcióból számítódik ki. 66

Példa: Kimeneti kollekció SELECT kocsma. Név, átlagÁr: AVG( SELECT p. s. ár FROM partition p) Kiveszi a kocsma. Név mezőt a csoport struktúrájából. A csoport partíció minden p tagjából kiveszi az s mezőt (az Eladás objektumot), abból pedig az árat. Átlagolja az árakat, ezáltal létrehozza a kimeneti kollekció struktúráiban az átlagÁr mező értékeit Tipikus kimeneti struktúra: Struct(kocsme. Név = "Józsi kocsmája", átlagÁr = 2. 83) 67

Kevésbé tipikus példa u Minden sörhöz számoljuk össze, hány kocsma kér érte „alacsony” (<400 Ft) és hány „magas” (>800 Ft) árat. u Stratégia --- csoportosítsunk három érték szerint: 1. A sör neve. 2. Egy logikai függvény, amely igazat ad vissza akkor és csak akkor, ha az ár alacsony. 3. Egy logikai függvény, amely igazat ad vissza akkor és csak akkor, ha az ár magas. 68

A lekérdezés SELECT sör. Név, alacsony, magas, darab: COUNT(partition) FROM Sörök b, b. eladói s GROUP BY sör. Név: b. név, alacsony: s. ár < 2. 00, magas: s. ár > 4. 00 Kezdeti kollekció: struktúrák az alábbi formában: Struct(b: Sör objektum, s: Eladás objektum), ahol s. sör = b. 69

A köztes kollekció u Egy halmaz az alábbi szerkezetű struktúrákkal: 1. 2. 3. 4. sör. Név: string alacsony: boolean magas: boolean partition: Set<Struct{b: Sör, s: Eladás}> 70

Tipikus struktúra a köztes kollekcióban sör. Név alacsony magas partition Bud TRUE FALSE Salacsony Bud FALSE TRUE Smagas Bud FALSE Sközép u. Salacsony stb. Sör-Eladás párok halmazai. u. Az alacsony és magas nem lehet egyszerre igaz, így az a csoport mindig üres lesz. 71

A kimeneti kollekció SELECT sör. Név, alacsony, magas, darab: COUNT(partition) u. Lemásolja a köztes struktúrák első három komponensét és számoljuk meg a partícióban levő párokat, pl. sör. Név alacsony magas Darab Bud TRUE 27 FALSE 72
- Slides: 72