KAKO (NE KORISTITI OBJEKTNO-RELACIJSKE MOGUĆNOSTI ORACLE DBMS-a Zlatko Sirotić Istra informatički inženjering d.o.o., Pula e-mail: zlatko.sirotic@iii.hr SAŽETAK Kasnih 80-tih i ranih 90-tih godina prošlog stoljeća počeli su se pojavljivati prvi objektni DBMS sustavi, a kasnih 90-tih prvi objektno-relacijski DBMS sustavi. Danas skoro svi RDBMS proizvodi imaju prefiks "O", tj. predstavljaju se kao ORDBMS (objektno-relacijski DBMS, podržavajući (barem neke objektno-relacijske mogućnosti definirane u SQL:1999 i SQL:2003 standardu. No, poznati znanstvenik na području relacijskog modela i relacijskih sustava C.J.Date napisao je u svojoj knjizi "Database in Depth" (2005, str. 32: "After all, the whole point of an "objectrelational" system is precisely that we can have attribute values in relations that are of arbitrary complexity. Perhaps a better way to say it is this: a proper objectrelational system is just a relational system with proper type support - which just means it's a proper relational system, no more and no less.". U radu se prikazuju objektno-relacijske mogućnosti Oracle 11g (i 10g DBMS-a i daju se preporuke na koji bi se način te mogućnosti trebale koristiti (također, na koji način se ne bi trebale koristiti! u skladu s Dateovim radovima. UVOD Relacijski model podataka teoretski je razradio E.F.Codd i prvi put ga opisao u radu "A Relational Model of Data for Large Shared Data Banks", CACM 13, No. 6 (June 1970. Date (2004, str. 170 navodi da je taj rad i danas vrijedan proučavanja, iako su, naravno, neke ideje u međuvremenu doživjele promjene, ali su te promjene više evolucijske nego revolucionarne. Na temelju relacijskog modela, u desetljeću 1970.-1979. intenzivno se radilo na dizajniranju RDBMS sustava - relacijskih sustava za upravljanje bazama podataka. Prvi ("laboratorijski" sustav razvijen je 1974. u IBM-u (u kojem je tada radio i E.F.Codd, u okviru projekta System R. U tom projektu stvoren je i jezik SEQUEL (Structured English Query Language, čije je ime kasnije skraćeno na SQL. Taj je projekt potaknuo šire zanimanje za relacijski model i za jezik SQL. Prvi komercijalni RDBMS sustav pod imenom Oracle ponudila je 1979. godine kompanija Relational Software Inc. (osnovana je 1977., kasnije je preimenovana u Oracle Corporation. RDBMS sustavi nisu prvi DBMS sustavi na tržištu. Prije njih postojali su hijerarhijski i mrežni DBMS. Međutim, Date ističe (2004, str. 27 da je neprimjereno govoriti o hijerarhijskom i mrežnom modelu podataka, jer su, za razliku od relacijskog modela, hijerarhijski i mrežni "model" nastali nakon pojave tržišnih hijerarhijskih i mrežnih DBMS sustava, pa su "modeli" prikazivali ono što je bilo realizirano u tržišnim produktima. Prvi objektno-orijentirani programski jezik (OOPL Simula 67 nastao je daleke 1967. godine (autori su mu Kristen Nygaard i Ole-Johan Dahl dakle, prije pojave relacijskog modela! Jezik Simula 67 inspirirao je kreatore drugih OOPL jezika (npr. jezika Smalltalk, C++, Eiffel. Do naglog razvoja OOPL jezika došlo je početkom i sredinom 80-tih godina prošlog stoljeća. Na krilima uspjeha OOPL-a, kasnih 80-tih i ranih 90-tih godina prošlog stoljeća počeli su se pojavljivati prvi objektni DBMS sustavi, a kasnih 90-tih prvi objektno-relacijski DBMS sustavi. 1. TIPOVI PODATAKA Da bi se prikazao relacijski model, a posebno onaj dio koji govori o strukturi podataka, vrlo je važno definirati tip podataka. Prema (Date 2004, str. 136 tip podataka je imenovani skup vrijednosti koje zadovoljavaju određena ograničenja nad tipom (type constraint. Svakom tipu podataka pridruženi su operatori (read-only i update za operiranje nad vrijednostima i varijablama toga tipa. Date naglašava da je potrebno uvijek voditi brigu o razlici između vrijednosti i varijable za razliku od vrijednosti, varijabla se može mijenjati, tj. tekuća vrijednost varijable može se zamijeniti nekom drugom vrijednošću. Vrijednosti i varijable uvijek moraju biti određenog tipa. 1
Tipovi podataka mogu biti sistemski ili korisnički-definirani. Tipovi podataka mogu biti i skalarni ili neskalarni - skalarni tip nema korisnički-vidljivih komponenti. Tip podataka mora imati jednu (ili više mogućih (potencijalnih fizičkih reprezentacija (possible physical representation. Fizička reprezentacija trebala bi korisniku biti sakrivena. Date na puno mjesta u (2004 i (2005 navodi da je jezik SQL dosta loša realizacija relacijskog jezika. Zbog lakšeg objašnjavanja relacijskog modela, Date je razvio vlastiti relacijski jezik Tutorial D. Evo kako u jeziku Tutorial D izgleda definicija tipa POINT (geometrijska točka u dvodimenzionalnom prostoru sa dvije moguće fizičke reprezentacije: TYPE POINT POSSREP CARTESIAN {X RATIONAL, Y RATIONAL} POSSREP POLAR {R RATIONAL, ALFA RATIONAL}; Date naglašava (2004, str. 116 da je tip POINT skalaran, iako moguće fizičke reprezentacije imaju više komponenti (u ovom slučaju obje reprezentacije imaju po dvije komponente. Evo kako u jeziku Tutorial D izgleda definicija ograničenja nad tipom: TYPE WEIGHT POSSREP {D DECIMAL (5, 1 CONSTRAINT D > 0.0 AND D < 5000.0}; Osim tipova podataka, Date (2004, str 127 navodi potrebu za postojanjem generatora tipova (type generators. Npr. u Tutorial D možemo napisati VAR SALES ARRAY INTEGER 12 ; Varijabla SALES je tipa ARRAY INTEGER 12, a ARRAY je generator tipa. U ovom je slučaju ARRAY sistemski generator tipa, ali generatori tipa mogu biti i korisnički-definirani. Generatori tipa poznati su u literaturi i pod drugim imenima, npr. generički tipovi. Meyer (1997, str. 318 ih naziva generičkim apstraktnim tipovima podataka, u Java jeziku zovu se generics, u C++ jeziku zovu se template(s. Date (2004, str. 115 navodi da pojam apstraktni tip podataka (ADT nije adekvatan, jer na neki način upućuje da postoje i "ne-apstraktni" tipovi podataka, a tip se, po njemu, uvijek treba razlikovati od moguće fizičke reprezentacije. Ipak, držimo da Dateova definicija tipa podataka ima nekih dodirnih točaka sa definicijom ADT-a koju prikazuje Meyer u (1997, poglavlje 6. Meyer kaže da apstraktni tipovi podataka predstavljaju teorijsku (matematičku osnovu za njegovu DBC metodu, pa i za cijeli Eiffel jezik (koji je on dizajnirao i da nam apstraktni tipovi podataka omogućavaju specificiranje softverskog sustava na precizan i kompletan (koliko je to potrebno način, ali bez prespecifikacije (overspecification, tj. bez ulaženja u detalje softverskog rješenja. Drugim riječima, ADT omogućavaju da se precizno definira što se želi dobiti, a da se ne mora ulaziti u detalje kako to postići (aplikativni, a ne imperativni pristup. Meyer prikazuje da se definicija ADT-a sastoji od definicije tipova, funkcija, aksioma i pretkondicija. Npr. kompletna ADS specifikacija za stog (stack izgleda ovako (Meyer, 1997, str. 139: TYPES STACK G FUNCTIONS put: STACK G X G STACK G remove: STACK G - STACK G item: STACK G - G empty: STACK G BOOLEAN make: STACK G AXIOMS For any x: G, s: STACK G A1: item (put (s, x = x A2: remove (put (s, x = s A3: empty (make A4: not empty (put (s, x PRECONDITIONS remove (s: STACK G require not empty (s item (s: STACK G require not empty (s 2
Slično kao što Dateov Tutorial D jezik ima ograničenja nad tipovima podataka (TYPE CONSTRAINT, tako Meyer-ov ADT prikazuje ograničenja kroz aksiome i pretkondicije. Date naglašava (2004, str. 129-136 da, za razliku od jezika Tutorial D, SQL nema nešto slično CONSTRAINT specifikaciji, pa bi SQL standard definicija skalarnog tipa WEIGHT bila: CREATE TYPE weight AS DECIMAL (5, 1; Dalje, SQL ne podržava niti specifikaciju moguće fizičke reprezentacije, već se u SQL-u uvijek definira aktualna fizička reprezentacija. Zato će prije navedeni tip POINT, koji je u jeziku Tutorial D bio skalarni tip, u SQL-u biti neskalarni (strukturirani tip: CREATE TYPE point AS ( x FLOAT, y FLOAT NOT FINAL; Napomena: prethodna naredba ima SQL standard sintaksu, a Oracle varijanta iza AS obavezno mora imati riječ OBJECT. 2. RELACIJSKI MODEL PODATAKA Relacijski model je (matematički temelj moderne tehnologije baza podataka. Kako kaže Date (2005, str. 1-4 poznavanje osnova relacijskog modela važno je za svakog tko se profesionalno bavi bazama podataka, jer profesionalci u svakoj disciplini moraju poznavati temelje svog polja rada. Pritom su važni principi, a ne samo konkretni produkti i tehnologije, jer se principi mijenjaju daleko sporije nego konkretni produkti i tehnologije. Danas postoji mnoštvo knjiga koje objašnjavaju relacijski model. Npr. (Date, 2004, 8.izdanje je fundamentalna (i voluminozna knjiga koja se široko koristi na sveučilištima širom svijeta i prodana je u preko 750.000 primjeraka. (Date, 2005 je relativno kratka (nešto preko 200 stranica knjiga namijenjena profesionalcima koji bi htjeli svoje praktično znanje učvrstiti teoretskim temeljima. I na našem jeziku postoji dobra literatura iz tog područja, npr. (Radovan, 1993 i (Varga, 1994. Relacijski model (Date, 2004, str. 109 bavi se strukturom podataka (data structure, operacijama nad podacima (data manipulation i integritetom podataka (data integrity. Ovdje ćemo operacije nad podacima i integritet podataka samo ukratko prikazati. Nešto detaljnije će biti prikazana struktura podataka, jer je to važno za razumijevanje Dateove kritike nekih objektnorelacijskih aspekata SQL:1999 i SQL:2003 standarda (i konkretnih tržišnih ORDBMS sustava koji to podržavaju. Najvažniji koncepti u relacijskom modelu jesu relacijska vrijednost ili relacija i relacijska varijabla. No, prvo treba definirati pojam (koristit ćemo engleski termin tuple vrijednost (tuple value ili samo tuple. (Date 2004, str. 141 definira tuple (value kao skup uređenih trojki u obliku <Ai, Ti, vi>, gdje i poprima vrijednost 1..n, Ai je ime atributa, Ti je ime tipa, a vi je vrijednost (koja je tipa Ti. Uređeni par <Ai, Ti> je atribut tuple-a. Skup svih atributa je zaglavlje (heading tuple-a. Tuple tip (tuple type je determiniran tim zaglavljem. Za razliku od tuple vrijednosti, tuple varijable (tuple variables nisu dio relacijskog modela, ali su tuple varijable važne za korištenje u host programskom jeziku koji koristimo za pisanje aplikacije (Date 2004, str. 143. Relacijska vrijednost (relational value ili relacija (Date 2004, str. 146 sastoji se od zaglavlja (heading i tijela (body. Zaglavlje relacije je isto kao i zaglavlje tuple-a. Tijelo relacije je skup svih tuple-a koji imaju isto zaglavlje. Relacijski tip (relational type je determiniran zaglavljem relacije. Date (2004, str. 149 navodi neke važne osobine relacije, koje proizlaze iz činjenice da (matematički skup po definiciji nema uređenja elemenata i nema duplih elemenata: 1. atributi su neuređeni u smislu lijevo-desno, 2. tuple-ovi su neuređeni u smislu gore-dolje, 3. relacija nema duplih tuple-ova. Za razliku od prethodno navedenih pojmova relacija, tuple i atribut, SQL koristi pojmove tablica, redak i stupac, ali ti pojmovi nisu (potpuno ekvivalentni. Npr., za razliku od prethodno navedenih osobina relacije, SQL tablica ima uređene stupce, ima uređene retke i može imati duple retke. Date naročito kritizira ovo zadnje. 3
Osim prethodnog, Date (2004, str. 149 naglašava da su relacije uvijek u 1.normalnoj formi, tj. (suprotno onome što smo uobičajeno učili vrijednosti u atributima relacije mogu biti druge relacije to su tzv. RVA (relational-valued attributes. No, to ne znači da Date preporuča takav dizajn relacija uglavnom preporuča upravo suprotno (2005, str. 143, ali činjenica je da relacijski model to dozvoljava. Osim relacija (relacijskih vrijednosti, relacijski model čine i relacijske varijable ili relvar. Date ih (2004, str. 156 dijeli u bazne relvar-e i virtualne relvar-e ili poglede (view. U jeziku Tutorial D sintaksa za deifniranje baznog relvar-a je sljedeća: VAR <relvar name> BASE <relation type> <candidate key def list> <foreign key def list> SQL koristi isti termin tablica i za "tablične vrijednosti" i za "tablične varijable" (Date 2004, str. 163. Osim strukture podataka, relacijski model definira i operacije nad podacima, bilo kroz relacijsku algebru, bilo kroz njoj ekvivalentan relacijski račun, ili kroz račun domena (Date 2004, poglavlje 7 i 8, (Radovan 1993, poglavlje 5. Što se tiče SQL-a Date (2004, str. 231 napominje da SQL nije baziran niti na relacijskoj algebri, niti na relacijskom računu, već malo na jednome, malo na drugome (a malo ni na jednom, ni na drugom. Dakle, nikako ne stoji da "relacijski model = SQL". No, Date je svjestan (2005, str. 175-176 da se SQL ne može tek tako izbaciti (on vidi SQL kao database COBOL, pa preporuča da se SQL izgradi na temelju (on top nekog pravog relacijskog jezika i da se, naravno, korisnicima (programerima ili krajnjim korisnicima dozvoli upotreba (uz SQL i tog pravog relacijskog jezika. Treći dio relacijskog modela, integritet podataka, najviše je zanemaren od strane proizvođača RDBMS sustava, ali je (Date 2004, str. 164 doživio i najveće (evolucijske, ne revolucionarne promjene u okviru relacijskog modela. Integritetna ograničenja ili samo ograničenja (constraints Date (2004, str 266 dijeli u 4 kategorije: 1. ograničenja na razini baze, 2. ograničenja na razini relacijske varijable, 3. ograničenja na razini atributa, 4. ograničenja nad tipom (type constraint. Današnji RDBMS sustavi uz deklarativna ograničenja: PK za primarni ključ, UK za jedinstveni ključ, FK za strani ključ, CK za provjeru vrijednosti u jednom retku i NOT NULL (što bi po Dateu trebalo biti obavezno podržavaju i okidače (triggers. Okidači su u biti procedure i mogu služiti i za druge namjene, a ne samo za očuvanje integriteta podataka. Date preferira deklarativna ograničenja. To ne znači da je on protiv okidača trebamo ih koristiti dok nemamo (deklarativne alternative. Date (2004, str 293 navodi da su u zadnje vrijeme integritetna ograničenja ponovno postala zanimljiva ovaj put pod imenom poslovna pravila (business rules. Poslovna pravila su zapravo user-friendly (tj. manje formalan ili neakademski način govora o integritetu baze podataka. Date drži taj trend pozitivnim, te preporuča knjige koje je napisao R.G.Ross, jedan od autoriteta na području poslovnih pravila. Dobra knjiga iz područja poslovnih pravila je i Von Halle (2002. Još je jedna Dateova napomena (2005, str. 122 vezana je za integritetna ograničenja - ona ne bi trebala biti odgođena (deferred, npr. odgođena do pred kraj transakcije. Naime, za razliku od uobičajenog mišljenja da je transakcija jedinica integriteta (u akronimu ACID - Atomicity, Consistency, Isolation, Durability - to predstavlja Consistency, Date drži da bi naredba (statement trebala biti jedinica integriteta, pa integritetna ograničenja ne bi smjela biti odgođena. Što se tiče teorije dizajna baze podataka (database design teory, koju čine prije svega pravila za normalizaciju podataka, Date joj posvećuje dosta prostora u (2004, poglavlja 11-14 i (2005, poglavlje 7, ali u (2005, str. 136 navodi da teorija dizajna baze podataka nije dio relacijskog modela, već da je ona posebna teorija temeljena (on top na relacijskom modelu. Vezano za normalizaciju podataka, Date navodi (2004, str. 704-709 da se u području skladišta podataka često koriste zvjezdaste sheme (star schema koje po njegovom mišljenju imaju dosta problema, između ostalog i problema sa normalizacijom. Date ističe (kao negativnu preporuku "odoli normalizaciji" koju npr. u svojoj knjizi (Kimball, 2002 navodi jedan od autoriteta na području skladišta podataka. 4
3. NASLJEĐIVANJE TIPOVA Nasljeđivanje tipova (type inheritance ili nasljeđivanje klasa svakako je važno za objektnoorijentirane programske jezike i za objektne DBMS sustave, ali kako tvrdi Date - i za relacijski model i za relacijske DBMS sustave. Kod relacijskog modela Date (2004, str. 609 navodi da nas zanima ono što se inače naziva nasljeđivanje domena, što je isto što i nasljeđivanje tipova (podataka, jer su po njemu domena (termin koji se nekad često koristio u okviru relacijskog modela i tip jedno te isto. Dakle, vrijedi "domena = tip". S druge strane, Date smatra i da su tip i klasa jedno te isto. B.Meyer, autoritet na području OOPL-a slaže se da je klasa (i tip, ali je i modul (1997, str. 170: "U pristupu koji nije objektno orijentiran, koncepti modula i klase jasno su odvojeni. Najvažnije svojstvo pojma klasa je da obuhvaća oba koncepta, stapajući ih u jednu lingvističku tvorevinu. Klasa je modul, ili jedinica dekompozicije softvera. Međutim, klasa je također i tip (ili, u slučajevima u kojima učestvuje generičnost, uzorak tipa.". Dakle, vrijedi "klasa = tip = modul". Napomenimo da je u prethodnom citatu Meyer koristio izraz uzorak (pattern tipa za ono što Date naziva generator tipa. Za razliku od nasljeđivanja tipova (nasljeđivanja domena što smatra korisnim, Date (2004, str. 609 navodi da je skeptičan prema ideji nasljeđivanja tablica, tj. postojanja (kako ih SQL standard naziva podtablica i nadtablica (subtables, supertables, s osobinom da podtablica nasljeđuje sve stupce nadtablice i dodaje nove. U jeziku Tutorial D, ovako se prikazuje hijerarhija tipova PLANE_FIGURE, ELLIPSE, CIRCLE: TYPE PLANE_FIGURE ; TYPE ELLIPSE IS PLANE_FIGURE POSSREP { A LENGTH, B LENGTH, CTR POINT CONSTRAINT A >= B }; TYPE CIRCLE IS ELIPSE CONSTRAINT THE_A (ELLIPSE = THE_B (ELLIPSE POSSREP { R = THE_A (ELLIPSE CTR = THE_CTR (ELLIPSE }; Tip ELLIPSE je definiran kao pravi podtip tipa PLANE_FIGURE (PLANE_FIGURE je pravi nadtip tipa ELLIPSE. Tip CIRCLE je podtip tipa ELLIPSE, ali mu je uvedeno ograničenje da je poluos A jednaka poluosi B (tj. ima polumjer R. Date (2004, str. 613 navodi da je pravi smisao nasljeđivanja u tome da ako je B podtip tipa A, tada svi operatori (ili, drugim riječima: procedure, funkcije, metode koji su primjenjivi na tip A istovremeno primjenjivi i na tip B. Dakle, parametri (u drugoj terminologiji - formalni parametri operatora mogu biti jednog deklariranog tipa, a argumenti (u drugoj terminologiji aktualni parametri kod poziva operatora mogu biti ili deklariranog tipa, ili njegovog podtipa. Kaže se (Date 2004, str. 615 da je operator polimorfan. Međutim, u ovom slučaju govorimo o tzv. inkluzijskom polimorfizmu, a postoji i polimorfizam sa preopterećenjem (overloading operatora, kod kojeg dva ili više operatora imaju isto ime i različite parametre. Međutim, kada se govori o nasljeđivanja tipova (ili nasljeđivanju klasa pod pojmom polimorfizam misli se na inkluzijski polimorfizam. Slično kao kod parametara i argumenata operatora, polimorfnost se manifestira i kod rada sa varijablama. Npr. varijabli E čiji je deklarirani tip ELLIPSE može se pridružiti varijabla C čiji je deklarirani tip CIRCLE. Meyer (1997, str. 467 takvo pridruživanje naziva polimorfno pridruživanje. Kod nasljeđivanja tipova, podtip može imati specifičnu implementacijsku verziju određenog operatora. U toku poziva operatora, sistem će sam pozvati odgovarajuću verziju operatora (Date 2004, str. 616, na temelju run-time vezivanja (run-time binding ili (drugi naziv dinamičkog vezivanja. 5
Vezano za nasljeđivanje klasa, Meyer (1997, str. 494 naglašava dvojako značenje nasljeđivanja, koje proizlazi iz dvojne uloge klase kao tipa i kao modula. Sa stanovišta modula, najvažnija je prednost nasljeđivanja u tome da modul može biti istovremeno i zatvoren i otvoren za mijenjanje (princip otvoren-zatvoren. Naime, metode nadklase mogu biti zatvorene za mijenjanje, ali možemo napraviti podklasu u kojoj ćemo nadjačati (Meyer kaže redefinirati neku metodu i time je modul postao otvoren. Navedimo sada analogan primjer definiranja hijerarhije tipova po SQL standardu (bez definiranja operatora: CREATE TYPE plane_figure NOT INSTANTIABLE NOT FINAL; CREATE TYPE ellipse UNDER plane_figure AS ( a LENGTH, b LENGTH, ctr POINT INSTANTIABLE NOT FINAL; CREATE TYPE circle UNDER ellipse AS ( r LENGTH INSTANTIABLE NOT FINAL; Kako je rečeno i prije, za razliku od jezika Tutorial D, SQL ne podržava ograničenja tipa i moguće fizičke reprezentacije. Zbog toga u SQL-u tip ELLIPSE ima tri atributa (što je u redu, ali podtip CIRCLE ima četiri atributa, a ne dva, koliko bi ih trebao imati. Naravno, atributi a, b, i r u podtipu CIRCLE morali bi imati uvijek jednaku vrijednost, inače dobijamo "ne-okrugli krug". Možemo primijetiti da je ovaj nedostatak SQL jezika u odnosu na Tutorial D sličan nedostatku DBC metode (posebno nedostatku invarijanti klase u OOPL jezicima (npr. C++ i Java u odnosu na jezik Eiffel (koji podržava DBC. 4. OBJEKTNO-ORIJENTIRANI (OODBMS I OBJEKTNO-RELACIJSKI (ORDBMS SUSTAVI Date (2004, str. 813 navodi kako se kasnih 80-tih i ranih 90-tih godina prošlog stoljeća javio velik interes za objektno-orijentirane (ili kraće: objektne DBMS sustave. Jedan od razloga bio je taj što su SQL produkti tada sigurno bili neadekvatni za rješavanje nekih specifičnih aplikacijskih područja kao što su npr. CADCAM i CIM sustavi, CASE sustavi, GIS sustavi, specifične znanstvene i medicinske aplikacije, sustavi za pohranu i pretraživanje dokumenata i sl. S druge strane, tada su se u upotrebi već dokazali objektno-orijentirani programski jezici, kao što su npr. Smaltalk ili C++. Objektni DBMS sustavi imaju svoj izvor u objektnim programskim jezicima. Kao i objektni programski jezici, tako i objektni DBMS djeluju obećavajuće u smislu povećavanja razine apstrakcije na kojoj se programira. Često se tvrdi da je objektni pristup bliži realnom svijetu, tj. da su softverski objekti slika objekata realnog svijeta. Međutim, kako ističe Meyer (1997, str. 231: "Softverski sistem nije model stvarnosti; u najboljem slučaju to je model modela nekog dijela stvarnosti. Sistem za praćenje pacijenata u bolnici nije model bolnice, već model modela podskupa bolničke stvarnosti.". Treći razlog povećane potrebe (ili želje za objektnim DBMS sustavom proizlazi također kao posljedica povećane upotrebe OOPL jezika. Naime, programerima je potreban neki sistem perzistencije, koji će omogućiti da se tranzijentni objekti sačuvaju i nakon kraja izvršenja programa, tj. da postanu perzistentni objekti. Naravno, kao mehanizam perzistencije mogu poslužiti (i najčešće to jesu relacijski DBMS sustavi. Međutim, RDBMS sustavi nisu (ili nisu bili dobro prilagođeni za pohranjivanje kompleksnih struktura objekata, što se naziva (Meyer 1997, str. 1050 neslaganje impedancije (impedance mismatch između objektnog modela podataka (objektnog programskog jezika i relacijskog modela podataka (relacijskog DBMS sustava. Za rješavanje tog problema često se (Larman 2002, poglavlje 34 koriste (softverski okviri za perzistenciju (persistence framework, kao skup apstraktnih i konkretnih klasa koje služe za realiziranje servisa za perzistenciju objekata. Što se tiče navedena tri razloga za upotrebu ODBMS sustava umjesto RDBMS sustava, može se reći da su današnji RDBMS sustavi puno prilagođeniji za rad sa CADCAM i ostalim prije navedenim specifičnim sustavima, jer današnji RDBMS sustavi podržavaju različite tipove podataka koje prije nisu podržavali. 6
S druge strane, uvođenjem korisnički definiranih tipova podataka i nasljeđivanja tipova, RDBMS sustavi približili su se objektnim sustavima, što znači da je i kod njih povećana razina apstrakcije, a u radu s OOPL jezicima smanjeno je (ali ne i potpuno uklonjeno neslaganje impedancije. Meyer (1997, str. 1053 navodi da je minimalan skup osobina koje objektni DBMS sustav treba imati sljedeći: treba imati one osobine koje ima (relacijska baza podataka, treba podržavati učahurivanje, identitet objekata i reference. Meyer nasljeđivanje (jednostruko ili višestruko drži dodatnom, korisnom, ali ne i nužnom osobinom. Osim nasljeđivanja, Meyer kao dodatne mogućnosti navodi: praćenje verzija objekata, praćenje verzija klasa i evolucija sheme, dugačke transakcije, zaključavanje, upite. Blaha i Premerlani (1998, poglavlje 15 ne navodi opće osobine koje treba imati ODBMS sustav, već navodi osobine produkta ObjectStore. Meyer (1997, str. 1056-1057 ukratko opisuje ODBMS sustave Matisse i Versant. Zanimljivo je napomenuti da informativno-propagandni materijali firme Matisse Software (www.matisse.com naglašavaju kako njihov DBMS sustav Matisse predstavlja "Object-SQL Database" (na početnoj web stranici piše da je "Post-Relational SQL Database". U materijalima ističu da je greška ranih ODBMS sustava upravo u tome što perzistenciju objekata omogućavaju na "prelagan" (tj. nekontroliran način, te da nijedan DBMS sustav ne može biti uspješan ako ne podržava SQL, i to u samoj jezgri (kernel DBMS sustava. Ističu kako je njihovo rješenje, tj. objektna-sql baza, fuzija najboljeg iz oba svijeta lakoće objektnog razvoja i sveprisutnosti SQL jezika. Možemo primijetiti da se proizvođači RDBMS i ODBMS sustava sve više trude da svoje sustave naprave kao hibridne. Što se tiče ODBMS sustava, postojala je organizacija za njihovu standardizaciju Object Data Management Group (ODMG, u kojoj su se nalazili manje-više svi proizvođači ODBMS sustava. ODMG je napravio standard poznat kao ODMG Object Model, čija je zadnja verzija 3.0 napravljena 2001. godine. ODMG 3.0 definira Object Model, Object Definition Language (ODL, Object Query Language (OQL, ali ne definira nešto kao "Object Manipulation Language", već se manipulacija objektima radi sa programskim jezicima za koje ODMG standard pruža podršku vezivanja jezika (language bindings: C++, Smalltalk i Java. Organizacija ODMG se rasformirala, a pravo na njihov standard preuzela je poznata organizacija (sličnog naziva Object Management Group (OMG, koja je 2006. objavila da će napraviti "4th generation" standard za objektne baze podataka. Treba napomenuti da postoje i razmišljanja o tome da ODBMS (pa ni RDBMS sustavi uopće nisu potrebni, jer se perzistencija može učiniti dovoljno snažnom već u okviru određenog OOPL jezika. Npr. kod jezika Java poznat je standard Java Data Objects (JDO. Larman (2002, str. 537 mišljenja je da "tehnologije kao one bazirane na JDO specifikaciji nude parcijalna rješenja". Meyer (1997, str. 1058-1060 navodi jedan mehanizam (u jeziku Eiffel koji bi omogućio da svi objekti budu predefinirani kao perzistentni, a da tranzijentni objekti budu izuzetak. Po njemu, taj mehanizam nalazi potporu u rastućoj dostupnosti 64-bitnog virtualnog adresnog prostora. No, ipak kaže: "Sve je ovo spekulativno i ne pruža nikakav dokaz da bi se trebalo odreći tradicionalnog pojma baze podataka.". Prije desetak godina, skoro svi proizvođači relacijskih DBMS sustava izašli su na tržište sa objektno-relacijskim nadogradnjama (ili opcijama. Kako navodi Date (2004, str. 859 jasna ideja bila je da njihovi proizvodi trebaju podržavati i objektne i relacijske mogućnosti, tj. proizvodi predstavljaju približavanje između te dvije tehnologije. Dateovo strogo mišljenje je da to približavanje treba ići tako da se zadrže temelji relacijskog modela, koji bi trebao evoluirati tako da uključi dobre osobine objektnih sustava. Date je mišljenja da je najvažnija (i možda jedina dobra ideja koja je uvedena u relacijski model iz objektnog svijeta odgovarajuća podrška za tipove podataka. Druga dobra ideja (ako se računa odvojeno je podrška za nasljeđivanje tipova. Zapravo, riječ je o tome da RDBMS sustavi konačno implementiraju nešto što je u relacijskom modelu davno predviđeno, a to su domene, koje jednostavno možemo zvati tipovi podataka. Relacijski sustav koji na pravilan način podržava domene (tj. tipove može podržavati sve one vrste podataka za koje se prije koristilo ODBMS sustave (CADCAM podaci, GIS podaci, multimedija, biomedicinski podaci i dr.. Vezano za približavanje između objekata i relacija, Date (2004, str 862 postavlja jedno krucijalno pitanje: "Koji je koncept u relacijskom svijetu blizanac konceptu (objektna klasa u objektnom svijetu?". Date nudi dva moguća odgovora: 1. domena = (objektna klasa, 2. relvar (relacijska varijabla = klasa. Date kaže da je jedini ispravan odgovor prvi, jer i domena i klasa su zapravo tip. Budući je relvar varijabla, a varijable nisu tipovi, drugi odgovor mora biti očito pogrešan. 7
No, neki produkti polaze od tog pogrešnog odgovora i takvu grešku Date naziva (slobodno prevedeno prva gruba greška (The First Great Blunder. Iz te greške proizlaze mnoge posljedice pa i ta da se u nekim produktima javlja koncept nadtablice i podtablice (gdje se podtablica kreira kao podklasa nadtablice. Date (2004, str. 869 pretpostavlja da prva gruba greška ima korijenje u nedostatku konsenzusa oko značenja nekih temeljnih termina u objektnom svijetu, a naročito ističe upotrebu termina objekt u "objektnoj analizi i dizajnu" ili "objektnom modeliranju", gdje zapravo nije riječ o objektima, nego o onome što se u području baza podataka obično naziva entitet. Druga gruba greška (Date 2004, str. 870 je miješanje pokazivača (pointer i relacija. Pokazivači pokazuju na varijable, a ne na vrijednosti. Ali, ako relacijska varijabla R1 ima atribut čija je vrijednost pokazivač u relacijsku varijablu R2, tada ti pokazivači pokazuju na tuple varijablu, a pojam tuple varijable ne postoji u relacijskom modelu jer se relacijski model (slobodno rečeno bavi relacijama (relacijskim vrijednostima koje su skupovi tuple vrijednosti, koji su pak skupovi skalarnih vrijednosti. Date pretpostavlja da druga gruba greška dolazi od toga što objektni sustavi i objektni jezici uključuju pokazivače kao neku formu objektnog ID-a, pa se onda ideja o miješanju pokazivača i relacija javila iz želje da relacijski sustavi budu što više "object-like". 5. ORACLE TIPOVI PODATAKA Oracle baza 11g (i prethodne verzije podržava prije svega sistemski definirane ili ugrađene (built-in tipove podataka (Oracle ih naziva native, koji mogu biti skalarni ("jednostavni" ili neskalarni. Slijedi kratak popis nekih sistemski definiranih skalarnih tipova podataka. Znakovni tipovi podataka su (između ostalih CHAR za fiksan broj znakova (maksimum je 2000, VARCHAR2 za varijabilan broj znakova (maksimum je 4000, CLOB (Character Large OBject zapravo, nije riječ o objektu za veliki broj znakova (4 GB i više. Najvažniji numerički tip podataka je NUMERIC. Najvažniji datumski, a istovremeno i vremenski tip podataka je DATE, koji služi za pamćenje podataka o stoljeću, godini, mjesecu, danu, satu, minuti i sekundi. Ne postoji tip podataka BOOLEAN (odnosno, postoji u PLSQLu, ali ne i u SQL-u, kojega Date (2005, str. 165 smatra fundamentalnim tipom podataka. Od neskalarnih sistemski definiranih tipova podataka vjerojatno je najzanimljiviji XMLTYPE (uveden je u bazi 9i, koji služi za pohranu XML dokumenata i manipulaciju njima pomoću brojnih ugrađenih metoda (operatora. Iako je riječ o sistemskom tipu podataka, on se koristi na sličan način kao korisnički definirani (user-defined tipovi podataka. Osim iz SQL-a, XMLTYPE može se koristiti i iz PLSQL-a i Jave: programske varijable, parametri procedure, povratne vrijednosti funkcije i sl. - mogu biti tipa XMLTYPE. Oracle je 1997. godine objavio 8.0 verziju baze i nazvao ju objektno-relacijskom. U skladu s tim nadopunjeni su i SQL i Oracle specifični programski jezik PLSQL. U bazu 8.0 uvedeni su novi tipovi podataka poznati kao kolekcije (collection; termin se često koristi neprecizno, jer se ponekad misli na tip, a ponekad na objekt tog tipa, kao i objektni tip (object type za koji možemo reći da je ekvivalent OOPL klasi (napomena: vjerojatno bi pravilnije bilo reći tip objekta, ali zbog lakšeg razumijevanja kod upotrebe tog izraza u rečenicama, koristit ćemo izraz objektni tip želimo dati naglasak na pojam tip, a ne na pojam objekt. Kolekcije se u Oracle literaturi obično navode zajedno sa objektnim tipom, tj. kolekcije se smatraju objektno-relacijskim mogućnostima (značajkama. Zanimljivo je da su u bazi 8.0 te objektno-relacijske mogućnosti činile opciju koja se posebno prodavala, ali već u bazi 8i Oracle ih je ugradio u standardne (bez posebne doplate mogućnosti Oracle baze. Oracle SQL poznaje dva tipa-kolekcije: tip-ugniježđena tablica (nested table type; uobičajeni ne-oracle pojam je MULTISET, a mi ćemo ga nazivati tablični tip i tip-niz (VARRAY type. VARRAY je skraćenica za variable-sized array, ali se definirani broj elemenata može naknadno mijenjati tek od baze 10g. Jezik PLSQL poznaje još jednu vrstu kolekcije asocijativne nizove (associative array, koji imaju porijeklo još iz baze Oracle 7, kada su se zvali PLSQL tablice. Primjer definiranja tabličnog tipa: CREATE TYPE list_of_names AS TABLE OF VARCHAR2(100 Primjer definiranja tipa-niza sa 10 elemenata, te povećanja broja elemenata (od baze 10g na 20: CREATE TYPE array_of_names AS VARRAY(10 OF VARCHAR2(100 ALTER TYPE array_of_names MODIFY LIMIT 20 CASCADE 8
Nažalost, pojedinačnim elementima VARRAY tipa ne može se pristupiti kroz SQL, već samo kroz PLSQL. Zapravo, jedno (naše rješenje postoji, ali je poprilično složeno tekst "Updating the Individual Elements of a Varray" na adresi www.revealnet.compipelinesplsqltips04.htm#january. Objektni tip pojavio se u bazi 8.0, ali u bazi 8i Oracle je stavio naglasak na ugrađivanje JVM (Java Virtual Machine u bazu - otuda potječe ono "i" (kao Internet u nazivu 8i. Zanimljivo je pročitati (Feuerstein 2005, str. 982 da se u vrijeme pojave baze 8i smatralo da se programski jezik PLSQL neće nadograđivati sa novim objektnim mogućnostima. Međutim, objektni tip je u bazi 9i (i u SQL-u i u PLSQL-u dobio neke važne objektne mogućnosti kao što su nasljeđivanje, nadjačavanje metoda, polimorfizam. U bazi 10g uvedene su operacije za usporedbu tabličnih tipova i operacije za manipulaciju nad njima (MULTISET operacije, npr. MULTISET UNION, MULTISET INTERSECT i sl.. SQL i PLSQL objektni tip se (barem za sada može definirati samo kao objekt baze (u određenoj shemi. Objektni tip ima dva dijela - specifikaciju i tijelo. U specifikaciji se deklariraju atributi i metode (funkcije i procedure, a u tijelu se metode (deklarirane u specifikaciji u potpunosti definiraju. Metode mogu biti statične (STATIC tj. metode koje se ne primjenjuju na određeni objekt, već na cijelu klasu, te MEMBER metode. U sljedećem primjeru prikazan je objektni tip (samo njegova specifikacija koji ima dva atributa i tri (MEMBER metode, od kojih je jedna metoda konstruktor (mora se zvati isto kao objektni tip: CREATE OR REPLACE TYPE osoba AS OBJECT ( ime VARCHAR2 (20, tezina_u_kg NUMBER, CONSTRUCTOR FUNCTION osoba ( p_ime VARCHAR2, p_tezina_u_kg NUMBER RETURN SELF AS RESULT, MEMBER PROCEDURE prikazi_podatke, MEMBER FUNCTION tezina_u_funtama RETURN NUMBER NOT FINAL Budući da prethodni objektni tip nije finalan (označen je sa NOT FINAL, možemo napraviti podklasu i nadjačati bilo koju njenu MEMBER metodu (Oracle STATIC metode ne mogu se nadjačati, već sakriti, jer je default kod metoda NOT FINAL. Npr. u nastavku radimo podklasu prethodne klase i u njoj nadjačavamo metodu PRIKAZI_PODATKE, te uvodimo novu metodu JEDI_MALO_I_DOBRO, koja se dalje ne može nadjačati, jer je označena sa FINAL (a podklasa je označena sa NOT FINAL, kako bi se mogle raditi i njene podklase: CREATE OR REPLACE TYPE gurman UNDER osoba ( omiljena_hrana VARCHAR2(20, CONSTRUCTOR FUNCTION gurman ( p_ime VARCHAR2, p_tezina_u_kg NUMBER, p_omiljena_hrana VARCHAR2 RETURN SELF AS RESULT, OVERRIDING MEMBER PROCEDURE prikazi_podatke, FINAL MEMBER PROCEDURE jedi_malo_i_dobro NOT FINAL Oracle objektni tipovi mogu se koristiti za kreiranje perzistentnih objekata (kroz SQL i za kreiranje tranzijentnih objekata (kroz PLSQL. Nažalost, za sada Oracle PLSQL ne podržava reference (ili pokazivače na tranzijentne objekte (to bi vjerojatno uvelo dodatnu komplikaciju dizajnerima PLSQL-a potrebu za automatskim sakupljanjem smeća, jer ne želimo da programer mora sam, kao u jeziku C++, voditi brigu o brisanju nepotrebnih objekata. Kao primjer rada sa tranzijentnim objektima može se pogledati naš tekst "The Template Design Pattern in PLSQL" na web adresi www.revealnet.compipelinesplsqltips06.htm#october. 9
Jedan drugi naš tekst pokazuje pak moguće greške kod istovremene upotrebe nadjačavanja i preopterećenja metoda - "Dynamic Method Dispatch and Method Overloading in a Subtype" na web adresi www.quest-pipelines.comnewsletter-v40503_c.htm. Za razliku od referenci na tranzijentne objekte, koje (za sada ne podržava, Oracle podržava reference na perzistentne objekte, i to ne samo unutar PLSQL jezika, već i unutar samog SQL-a. To znači da jedna relacija može imati reference na retke druge relacije to je ono što Date smatra (drugom grubom greškom. Referentni tip (REF na neki drugi tip ne definira se u bazi direktno (pomoću CREATE TYPE naredbe, već u okviru neke druge definicije, npr. kao u sljedećem primjeru (REF dept_type: CREATE TYPE emp_type AS OBJECT ( empno NUMBER, ename VARCHAR2(20, deptno REF dept_type U bazi 9i Oracle je uveo i specijalne tipove podataka ANYDATA, ANYDATASET i ANYTYPE. ANYDATA je samoopisujući tip (self-describing i podržava refleksivnost (kroz odgovarajući API. ANYDATA tip omogućava da stupci (tablice tog tipa ili (PLSQL varijable tog tipa sadrže podatak bilo kojeg sistemski ili korisnički definiranog tipa. ANYDATASET tip je sličan, ali omogućava pohranu skupa podataka (a ne jednog podatka bilo kojeg tipa. ANYTYPE je tip podataka koji sadrži opis drugog (bilo kojeg tipa, bez obzira da li je taj drugi tip podataka perzistentan tip (definiran kroz SQL, ili je čak tranzijentan tip, tj. tip podataka koji se generira dinamički za vrijeme izvršavanja (PLSQL programa. ANYDATA tipovi omogućavaju veliku fleksibilnost u programiranju, ali su zbog svoje fleksibilnosti i teški za razumijevanje, pa su programi koji ih koriste teško čitljivi i mogu biti pogrešno napisani, a greška se pokaže tek kod izvođenja. Ukoliko nam zaista ne treba refleksivno programiranje, bolje ih je ne koristiti. Jedan (naš primjer korištenja ANYDATA i ANYTYPE tipova podataka je "Inserting a 'Generic Record Type' Using ANYDATAANYTYPE Types" na web adresi www.revealnet.compipelinesplsqltips04.htm#march. 6. ORACLE OBJEKTNO-RELACIJSKE TABLICE Imenom objektne-relacijske tablice (object-relational tables možemo nazvati one tablice kod kojih je jedan ili više stupaca (ali ne redak kao cjelina temeljen na objektnom tipu ili tipu-kolekciji. Date smatra da su takve vrste tablica sasvim prihvatljive i da su to zapravo relacijske tablice. U sljedećem primjeru kreiramo tip ADRESA_T i koristimo ga za definiciju stupca ADRESA u objektno-relacijskoj tablici OSOBA: CREATE TYPE adresa_t AS OBJECT ( grad VARCHAR2(20, ulica VARCHAR2(30 CREATE TABLE osoba ( ime VARCHAR2(40 PRIMARY KEY, adresa adresa_t Kada iz Oracle alata SQL+ pogledamo pomoću naredbe DESCRIBE opis tablice OSOBA, vidjet ćemo da ona ima dva stupca: Name Type ------ ------------ IME VARCHAR2(40 ADRESA ADRESA_T 10
Međutim, tablica OSOBA zapravo ima 4 stupca: skalarni stupac IME, dva stupca koja predstavljaju komponente stupca-objekta ADRESA (njihova imena počinju sa SYS, te poseban stupac (dužine 1 byte, koji se zove kao stupac-objekt (u ovom slučaju ADRESA - njega Oracle koristi za interne potrebe, kao oznaku tipa: SELECT segcol#, name, segcollength, type# FROM sys.col$ WHERE obj# = (SELECT object_id FROM user_objects WHERE object_name = 'OSOBA' ORDER BY segcol#; SEGCOL# NAME SEGCOLLENGTH TYPE# ---------- ------------------------------ ------------ ---------- 1 IME 40 1 2 ADRESA 1 121 3 SYS_NC00003$ 20 1 4 SYS_NC00004$ 30 1 Unos i izmjena redaka nad tablicom OSOBA prikazani su u nastavku. Primijetimo da se kod unosa vrijednosti neskalarnog stupca ADRESA mora pozvati (default konstruktor ADRESA_T, a kod izmjene komponente neskalarnog tipa mora se koristiti alias tablice, dok se kod izmjene kompletnog skalarnog stupca opet koristi konstruktor (a alias tablice nije nužan: INSERT INTO osoba VALUES ( 'Ana', adresa_t ('G1', 'U1' ; UPDATE osoba o SET o.adresa.ulica = 'U2' WHERE ime = 'Ana'; UPDATE osoba SET adresa = adresa_t ('G2', 'U3' WHERE ime = 'Ana'; Slijede dvije varijante SELECT naredbe nad tablicom OSOBA prva selektira neskalarni stupac kao cjelinu, a druga selektira komponente skalarnog stupca (u drugom slučaju je nužan alias tablice: SELECT ime, adresa FROM osoba; IME ADRESA(GRAD, ULICA ---- ----------------------- Ana ADRESA_T('G2', 'U3' SELECT ime, o.adresa.grad, o.adresa.ulica FROM osoba o; IME ADRESA.GRAD ADRESA.ULICA ---- ----------- ------------ Ana G2 U3 Izbrišimo sada tablicu i tip, da nam ne smetaju u nastavku: DROP TABLE osoba; DROP TYPE adresa_t; 11
Prikažimo sada kako izgleda nasljeđivanje tipova podataka, nadjačavanje metoda i polimorfizam kod objektno-relacijskih tablica. Prvo ćemo kreirati nadtip ADRESA_T: CREATE TYPE adresa_t AS OBJECT ( grad VARCHAR2(20, ulica VARCHAR2(30, MEMBER FUNCTION adresa_f RETURN VARCHAR2 NOT FINAL -- OBAVEZNO CREATE TYPE BODY adresa_t AS MEMBER FUNCTION adresa_f RETURN VARCHAR2 IS BEGIN RETURN 'Generalna adresa:' grad ' ' ulica; END; END; Kreirajmo sada tablicu OSOBA i unesimo jedan redak: CREATE TABLE osoba ( ime VARCHAR2(40 PRIMARY KEY, adresa adresa_t ; INSERT INTO osoba VALUES ( 'Ana', adresa_t ('G1', 'U1' ; Kreirajmo sada podtipove KUCNA_ADRESA_T i POSL_ADRESA_T, u kojima ćemo dodati atribute i nadjačati metodu (funkciju ADRESA_F: CREATE TYPE kucna_adresa_t UNDER adresa_t ( dodatak1 VARCHAR2(11, OVERRIDING MEMBER FUNCTION adresa_f RETURN VARCHAR2 ; CREATE TYPE BODY kucna_adresa_t AS OVERRIDING MEMBER FUNCTION adresa_f RETURN VARCHAR2 IS BEGIN RETURN 'Kućna adresa:' grad ' ' ulica ' ' dodatak1; END; END; CREATE TYPE posl_adresa_t UNDER adresa_t ( dodatak1 VARCHAR2(12, dodatak2 VARCHAR2(13, dodatak3 VARCHAR2(14, OVERRIDING MEMBER FUNCTION adresa_f RETURN VARCHAR2 ; CREATE TYPE BODY posl_adresa_t AS OVERRIDING MEMBER FUNCTION adresa_f RETURN VARCHAR2 IS BEGIN RETURN 'Poslovna adresa:' grad ' ' ulica ' ' dodatak1 ' ' dodatak2 ' ' dodatak3; END; END; 12
Sada možemo unijeti retke sa konstruktorima podtipova KUCNA_ADRESA_T, POSL_ADRESA_T, jer se tablica OSOBA automatski proširila sa 4 dodatna stupca (1 + 3: SELECT segcol#, name, segcollength, type# FROM sys.col$ WHERE obj# = (SELECT object_id FROM user_objects WHERE object_name = 'OSOBA' ORDER BY segcol#; SEGCOL# NAME SEGCOLLENGTH TYPE# ---------- ------------------------------ ------------ ---------- 1 IME 40 1 2 ADRESA 256 121 3 SYS_NC00003$ 16 23 4 SYS_NC00004$ 20 1 5 SYS_NC00005$ 30 1 6 SYS_NC00006$ 11 1 7 SYS_NC00007$ 12 1 8 SYS_NC00008$ 13 1 9 SYS_NC00009$ 14 1 INSERT INTO osoba VALUES ( 'Pero', kucna_adresa_t ('G2', 'U2', 'D1' ; INSERT INTO osoba VALUES ( 'Mira', posl_adresa_t ('G3', 'U3', 'D1', 'D2', 'D3' ; Sada možemo propustiti dvije varijante SELECT naredbe u prvoj se navode imena stupaca, a u drugoj se navodi ime stupca i ime metode (funkcije. Vidimo da u drugom SELECT-u moramo koristiti alias tablice i zagrade iza imena metode, iako (u ovom slučaju metoda nema parametara: SELECT ime, adresa FROM osoba; IME ADRESA(GRAD, ULICA ---- -------------------------- Ana ADRESA_T('G1', 'U1' Pero KUCNA_ADRESA_T('G2', 'U2', 'D1' Mira POSL_ADRESA_T('G3', 'U3', 'D1', 'D2', 'D3' -- obavezne zagrade iza imena metode (PLSQL ima uniformni pristup, SQL ne SELECT ime, o.adresa.adresa_f( FROM osoba o; IME O.ADRESA.ADRESA_F( ---- --------------------- Ana Generalna adresa:g1 U1 Pero Kućna adresa:g2 U2 D1 Mira Poslovna adresa:g3 U3 D1 D2 D3 13
Dalje - selekcija na retke kojima je adresa određenog tipa -- samo tip kucna_adresa_t ili njegovi podtipovi (sada ih nema SELECT ime, adresa FROM osoba WHERE adresa IS OF (kucna_adresa_t; -- samo tip adresa_t ili njegovi podtipovi (sada su to svi SELECT ime, adresa FROM osoba WHERE adresa IS OF (adresa_t; -- samo tip adresa_t, bez podtipova SELECT ime, adresa FROM osoba WHERE adresa IS OF (ONLY adresa_t; Kako prikazati samo određene atribute objektnog stupca (one koji odgovaraju određenim atributima iz nadtipa adresa ili iz njegovih podtipova? Atribute koji odgovaraju atributima iz nadtipa adresa možemo lako prikazati: SELECT ime, o.adresa.grad FROM osoba o; IME ADRESA.GRAD ---------------------------------------- -------------------- Ana G1 Pero G2 Mira G3 Ali, ne možemo (direktno prikazati atribute koji odgovaraju atributima podtipa: SELECT ime, o.adresa.dodatak1 FROM osoba o; ERROR at line 1: ORA-00904: "O"."ADRESA"."DODATAK1": invalid identifier Istina, moguće je navesti sistemsko ime stupca: SELECT ime, SYS_NC00009$ FROM osoba; No, "čišće" je koristiti TREAT ("object_column" AS "subtype": SELECT ime, TREAT (adresa AS posl_adresa_t.dodatak1 FROM osoba; IME TREAT(ADRESA ---------------------------------------- ------------ Ana Pero Mira D1 Ili, prikažimo samo osobe koje imaju poslovnu adresu: SELECT ime, TREAT (adresa AS posl_adresa_t.dodatak1 FROM osoba WHERE adresa IS OF (posl_adresa_t; IME TREAT(ADRESA ---------------------------------------- ------------ Mira D1 14
Kako raditi UPDATE objektnog stupca cijelog ili pojedinih atributa? Kako smo i prije vidjeli, lako je ažurirati cijeli stupac: UPDATE osoba SET adresa = adresa_t ('G2', 'U3' WHERE ime = 'Ana'; Možemo ažurirati i atribute objektnog stupca koji odgovaraju atributima iz nadtipa adresa: UPDATE osoba o SET o.adresa.grad = 'G3' WHERE ime = 'Ana'; Ali, ne možemo (direktno ažurirati atribute koji odgovaraju atributima podtipa (npr. podtipa posl_adresa_t. Napomenimo da u sljedećoj naredbi razlog greške nije taj što 'Ana' ima generalnu adresu (tipa adresa_t koja nema stupac dodatak1 isto bi bilo sa 'Pero' i 'Mira', iako njihove adrese (tipa kucna_adresa_t i posl_adresa_t imaju taj stupac: UPDATE osoba o SET o.adresa.dodatak1 = 'D2' WHERE ime = 'Ana'; SET o.adresa.dodatak1 = 'D2' * ERROR at line 2: ORA-00904: "O"."ADRESA"."DODATAK1": invalid identifier Istina, mogli bismo koristiti sistemska imena stupaca dodatak1 (napomena - imamo ih dva, kao kod SELECT, ali to nije "čisto". No, za razliku od SELECT, kod UPDATE ne pomaže TREAT: UPDATE osoba o SET TREAT (adresa AS posl_adresa_t.dodatak1 = 'D2' WHERE ime = 'Ana'; SET TREAT (adresa AS posl_adresa_t.dodatak1 = 'D2' * ERROR at line 2: ORA-00927: missing equal sign Ali, ovo radi - UPDATE inline wiew: UPDATE (SELECT TREAT (adresa AS posl_adresa_t.dodatak1 dod1 FROM osoba WHERE ime = 'Ana' SET dod1 = 'D2'; ili UPDATE (SELECT ime, TREAT (adresa AS posl_adresa_t.dodatak1 dod1 FROM osoba SET dod1 = 'D2' WHERE ime = 'Ana'; Nažalost, moramo primijetiti da smo u ovom konkretnom slučaju dobili nekonzistentnost, iako u UPDATE nismo koristili sistemsko ime stupca (što nije "čisto". Naime, 'Ana' sada ima napunjen stupac dodatak1, iako je njena adresa i dalje ostala tipa adresa_t, a adresa_t nema taj stupac. 15
Kako napraviti INDEX ili CONSTRAINT nad atributima objektnog stupca? Ne mora se koristiti "sistemsko ime" (u sljedećoj točki vidjet ćemo da ponekad moramo, npr. kod FK i objektnih tablica, u nekim slučajevima, može i ovako: CREATE INDEX dodatak3_i ON osoba (TREAT (adresa AS posl_adresa_t.dodatak3; Izbrišimo opet tablice i tipove, da nam ne smetaju u nastavku (to ćemo raditi i poslije: DROP TABLE osoba; DROP TYPE posl_adresa_t; DROP TYPE kucna_adresa_t; DROP TYPE adresa_t; Pogledajmo sada kako bi izgledala tablica u kojoj je stupac TELEFONI deklariran kao NIZ_TELEFONA_T (niz ima pet elemenata. Elementi niza u ovom slučaju su skalarne vrijednosti, ali mogu biti i neskalarne. Primijetimo da kod INSERT naredbe nije nužno navesti sve elemente niza (navedena su samo dva telefona: CREATE TYPE niz_telefona_t AS VARRAY (5 OF VARCHAR2(20 CREATE TABLE osoba ( ime VARCHAR2(40 PRIMARY KEY, telefoni niz_telefona_t INSERT INTO osoba VALUES ( 'Mira', niz_telefona_t ('12345', '54321' ; DROP TABLE osoba; DROP TYPE niz_telefona_t; Kako smo već naveli u 5.poglavlju, pojedinačnim elementima VARRAY tipa ne može se pristupiti kroz SQL (osim na vrlo složen način, već samo kroz PLSQL. Zato u Oracle bazi nije preporučljivo koristiti VARRAY tip za stupce tablice. Na kraju, pogledajmo kako objektno-relacijska tablica OSOBA može imati stupac čija je vrijednost neki skup redaka telefona. Za takav slučaj uobičajeno bi se reklo da tablica OSOBA nije u 1.normalnoj formi, ali (kako smo vidjeli u 2.poglavlju Date naglašava da ta tablica jeste u 1.normalnoj formi ali je njen atribut TELEFONI tzv. RVA (relational-valued attribute. Oracle to zove ugniježđena tablica (nested table: CREATE TYPE telefon_t AS OBJECT ( vrsta VARCHAR(10, broj VARCHAR2(20 CREATE TYPE tablica_telefona_t AS TABLE OF telefon_t CREATE TABLE osoba ( ime VARCHAR2(40 PRIMARY KEY, telefoni tablica_telefona_t NESTED TABLE telefoni STORE AS telefoni_tab 16
Vidimo da se u stvarnosti stupac TELEFONI realizira kao odvojena tablica TELEFONI_TAB. Interno, tablice-roditelj OSOBA i tablica-dijete TELEFONI_TAB imaju dodatne stupce koji služe za njihovo povezivanje. No, kako kaže Date, nije važna interna realizacija, već vanjski pogled (korisnika, uključujući i programera. Evo kako bi izgledao INSERT nad tablicom OSOBA: INSERT INTO osoba VALUES ( 'Ana', tablica_telefona_t ( telefon_t ('kućni', '123', telefon_t ('posl.', '456', telefon_t ('mobil', '789' ; UPDATE možemo raditi na dva načina. Prvi način, mijenjanje vrijednosti cijelog RVA stupca TELEFONI, je jednostavniji: UPDATE osoba SET telefoni = tablica_telefona_t ( telefon_t ('posl.', '000', telefon_t ('mobil', '111' WHERE ime = 'Ana'; U drugom načinu mijenjamo samo neke retke ugniježđene tablice (nula, jedan ili više, ali uvijek retke-djecu koji pripadaju odabranom (samo jednom retku-roditelju, inače Oracle javlja grešku (u nastavku mijenjamo samo telefone koji pripadaju osobi Ana; konkretno mijenjamo samo jedan telefon. U ovom načinu moramo koristiti operator TABLE, kojim pretvaramo odabrani skup redaka ugniježđene tablice u virtualnu tablicu: UPDATE TABLE (SELECT telefoni FROM osoba WHERE ime = 'Ana' SET broj = '111' WHERE vrsta = 'kućni'; DROP TABLE osoba; DROP TYPE tablica_telefona_t; DROP TYPE telefon_t; Tablice sa RVA stupcima najčešće nisu dobar dizajnerski izbor, jer sa njima model podataka sliči na nekadašnje hijerarhijske baze podataka, u kojima se tablici-djetetu moglo pristupati samo preko tablice-roditelja, a rijetko u stvarnosti imamo tablice kojima ne želimo pristupati i direktno. Kako smo već rekli u 2.poglavlju, i Date (2005, str. 143 drži da RVA atributi najčešće nisu dobar dizajnerski izbor, iako su u relacijskom modelu dozvoljeni. Inače, poznati Oracle ekspert (i Oracle zaposlenik Tom Kyte kaže (2005, str. 417 da on uopće ne upotrebljava objektno-relacijske ili objektne tablice, već koristi objektne mogućnosti unutar jezika PLSQL i koristi objektne poglede (object views napravljene nad relacijskim tablicama. 17