Adatbázis rendszerek Gyakorlati jegyzet
Készítette:
Selling István 2012
Adatbázis rendszerek
Tartalomjegyzék 1. Első gyakorlat
3
2. Második gyakorlat
5
3. Harmadik gyakorlat
9
4. Negyedik gyakorlat
10
5. Ötödik gyakorlat
11
6. Hatodik gyakorlat
13
7. Hetedik gyakorlat
14
8. Nyolcadik gyakorlat
16
9. Kilencedik gyakorlat
18
10.Tizedik gyakorlat
20
11.Tizenegyedik gyakorlat
21
2. oldal
Adatbázis rendszerek
1.
Első gyakorlat
1.1.
Feladat kitűzés
Hozzunk létre egy három táblából álló adatbázist a következő módon: • Diák tábla: – Neptun kód: A Diák tábla elsődleges kulcsa, 6 karakterből áll. – Név: A Diák neve, 25 karakterből állhat. • Tárgy tábla: – Tkód: A Tárgy tábla elsődleges kulcsa, 10 karakterből álló tárgykód. – Név: A tárgy neve, 25 karakterből állhat. – Leírás: A tárgy leírása, 70 karakterből állhat. • Oktató tábla: – Okód: Az Oktató tábla elsődleges kulcsa, 6 karakterből áll. – Név: Az oktató neve, 25 karakterből állhat. – Szoba: Az oktató szobája, 7 karakterből állhat. • Az Oktató és Tárgy tábla között egy a többhöz kapcsolat áll fenn. • A Tárgy és Diák tábla között több a többhöz kapcsolat áll fenn. Ennek a kapcsolatnak a Jegy az attribútuma.
1.2.
A feladat ER modellje
1.3.
Bejelentkezés az SQL szerverre
Az isqlplus szerver a következő címen érhető el: 193.6.5.72:5560/isqlplus Első bejelentkezéskor mind a felhasználónév, mind a jelszó a neptunkód. Ezt a következő paranccsal lehet módosítani:
3. oldal
Adatbázis rendszerek
ALTER USER felhasznalo_nev IDENTIFIED BY uj_jelszo;
1.4.
A feladat megoldása
Create TABLE Diak (Neptunkod Varchar(6) Primary Key, Nev Varchar(25)); Create TABLE Oktato (Okod Varchar(6) Primary Key, Nev Varchar(25), Szoba Create TABLE Targy (Tkod Varchar(10) Primary Key, Nev Varchar(25), Leiras Create TABLE Jegyek (Jegy Number(1), Tkod Varchar(10) REFERENCES Targy(Tkod), Neptunkod Varchar(6) REFERENCES Diak(Neptunkod));
4. oldal
Adatbázis rendszerek
2.
Második gyakorlat
2.1.
LDAP konfigurációs fájl példa
ucdata-path ./ucdata include ./schema/core.schema include ./schema/cosine.schema include ./schema/nis.schema include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/dyngroup.schema pidfile ./run/slapd.pid argsfile ./run/slapd.args # Enable TLS if port is defined for ldaps TLSVerifyClient never TLSCipherSuite HIGH:MEDIUM:-SSLv2 TLSCertificateFile ./secure/certs/server.pem TLSCertificateKeyFile ./secure/certs/server.pem TLSCACertificateFile ./secure/certs/server.pem # bdb database definitions database bdb suffix "dc=maxcrc,dc=com" rootdn "cn=Manager,dc=maxcrc,dc=com" # Cleartext passwords, especially for the rootdn, should # be avoid. See slappasswd(8) and slapd.conf(5) for details. # Use of strong authentication encouraged. rootpw SSHABw0oPbVXljDFQQ5Dqx/143XE2wH8bzw+
2.2.
A példa elemzése
A konfigurációs fájl legelején találhatóak az include utasítások. Ezek segítségével sémákat tölthetünk be. Sémák megadásánál választhatunk az előredefiniált között, vagy írhatunk sajátot is. Ha saját magunk írunk ilyen szerkezetet, akkor azt LDIF formátumbanl kell megadnunk. Miután megírtuk, a szerver konfigurációs fájljába illesztjük, az include listába, majd pedig a változtatás érvénybe lépéséhez leállítjuk, és újra elindítjuk a szervert. A konfigurációs fájl vége lehet még számunkra érdekes. A database mögött megadjuk, hogy a háttérben milyen adatbázistípus van, mivel az LDAP (Lightweight Directory Access Protocol) nem tárol adatokat, így egy adatbázist kell megadnunk, melyben majd az adatok tárolásra kerülnek. A suffix mögött megtalálhatjuk, hogy mi az a DN (Distinguished Name) előtag, amely minden hivatkozás elé körül. A root dn mögött megadjuk a rendszergazda nevét, ami egy bejegyzést jelent a fában, és a végén a rootpw segítségével megadjuk a rendszergazda jelszavát. Ha vannak jogosultsági parancsok, akkor ezek ezután találhatóak meg.
2.3.
Jogosultsági parancs, példa
Legyen a hierarchiánkban egy elem a következő azonosítóval: dn= a=1, b=2. Adjunk ezen elem részfájának minden felhasználójának módosítási, és írási jogot! ACCESS TO dn.subtree="a=1,b=2" BY users write
5. oldal
Adatbázis rendszerek
2.4.
JXplorer
Ebben a fejezetben tekintsük meg a JXplorer programot, ami egy olyan LDAP böngésző, amiben van lehetőségünk az adatok módosítására is.
Ahhoz, hogy bejelentkezzünk, kattintsunk a File menüre, majd azon belül a Connect lehetőségre.
Ezen a bejelentkező felületen lehetőségünk van megadni a Host címét, ahova csatlakozunk, BaseDN értéket, és a biztonság szintjét. A Host legyen a 193.6.5.72, és a 389es porton kapcsolódjunk hozzá.Biztonsági szintnél válasszuk ki a User+Password lehetőséget. Ezután adjuk meg a CN értéket, és a jelszót. cn=Kecso_D, ou=halllgatok_2012, o=db_msc, dc=com Az ehhez tartozó jelszó megegyezik a CN értékkel, azaz ebben az esetben Kecso_D.
6. oldal
Adatbázis rendszerek
Sikeres bejelentkezés esetén láthatjuk az LDAP hierarchiát a bal oldalon. A fent található Quick Search funkcióval lehetőségünk van lekérdezésekre, attribútum=érték alakkal. Ha az adatokat módosítani akarjuk, akkor erre a jobboldali felületen van lehetőségünk. Kattintsunk a Table Editor fülre, és láthatjuk táblázatban az adatokat, és egyszerűen írjuk át. Ezután kattintsunk alul a Submit gombra, és megtörténik az adatok változtatása.
Új elem felvitelére is van lehetőségünk. Kattintsunk a fában a megfelelő szülő elemre a jobb egérgombbal, és használjuk a New opciót. A képen is látható módon meg kell adnunk a szülő elem DN-jét, és a RelativeDN-t, ami a DN első tagja. Ezután ki kell jelölnünk, hogy az új elem melyik osztálysémákra illeszkedjen, legalább 1 osztályba tartoznia kell. Ezután, ha van kötelező attribútum, akkor annak az értéket meg kell adni. Új elem felvitelére lehetőségünk van LDIF fájl segítségével is.
7. oldal
Adatbázis rendszerek
2.5.
Tervezési feladat
Vegyünk egy iskolát, és készítsünk rendszert az osztályok névsorához! Adjuk meg az LDIF fájlt! dn: o=iskola objectclass: organisation dn: ou=2012, o=iskola objectclass: organisation unit ou=2012 dn: ou=A, ou=2012, o=iskola objectclass: organisation unit ou=A cn=Pál, ou=A, ou=2012, o=iskola objectclas: common name cn=Pál Mindegyik szinten meg kell adni a következőket az adott entry: • DN értékét, • osztálytípusát, • és RelativeDN értékét.
8. oldal
Adatbázis rendszerek
3.
Harmadik gyakorlat
3.1.
Kitűzött feladat
Valósítsuk meg a következő ER modell megfelelőjét LDAP környezetben! Az ER modell kulcsainak feleljenek meg a RelativeDN értékek!
3.2. A • • • •
3.3.
Hierarchikus modellre átalakítás kitűzött feladatot a következő hierarchia alapján képzelhetjük el: Legfelső szinten áll a saját bejegyzésünk, ennek a részfája lesz az összes többi. Alatta az ország áll, ez lesz a részfa gyökere. Harmadik szinten a kiadók állnak. Legalsó szinten pedig a könyvek találhatóak.
Megoldási menet
Jelentkezzünk be a JXplorer segítségével az LDAP rendszerbe! Bejelentkezés után kattinsunk a saját cn értékű bejegyzésre jobb egérgombbal, és használjuk a new funkciót. Adjuk meg az RDN értékét, válasszunk ki a listából egy olyan osztályt, amire illeszkedik a megvalósítandó egyed, adjunk értéket a szükséges attribútumoknak, illetve az opcionálisok közül azoknak, amelyek megfelelnek a céljainknak, ezután kattintsunk a Submit gombra. Egy lehetséges objektumosztály felépítés: • Az országnak adjunk country típusú osztályt. • A kiadó legyen organisation típusú. • A könyv pedig legyen organisation unit típusú.
9. oldal
Adatbázis rendszerek
4.
Negyedik gyakorlat
4.1.
Kitűzött feladat
Adott egy relációs tábla, amelynek az egyik eleme XML típusú. Feladatok: • Hozzuk létre a táblát! • Vigyünk fel 4 rekordot! • Készítünk direkt lekérdezési listát! • Az üzenetek kódját, és címét listázzuk ki, mind xPath, mind xQuery segítségével! • Az olvasatlan üzenetek típusát írjuk át olvasottá!
4.2.
A feladat modellje
4.3.
A feladatok megoldásai
Először hozzuk létre a táblát! Create TABLE Uzenetek (Kod int Primary Key, Datum Varchar(15), Uzenetek XMLTYPE); Ezután töltsük fel négy rekorddal! INSERT INTO Uzenetek VALUES (1,’2012’,XMLTYPE (’
Atorzs1U’)); INSERT INTO Uzenetek VALUES (2,’2011’,XMLTYPE (’
Btorzs2U’)); INSERT INTO Uzenetek VALUES (3,’2002’,XMLTYPE (’
Ctorzs3R’)); INSERT INTO Uzenetek VALUES (4,’2001’,XMLTYPE (’
Dtorzs4U’)); Valósítsuk meg a direkt lekérdezést! Select Extract(uzenet,’/level’) From Uzenetek; Listázzuk ki a kód+cím párosokat, először xPath segítségével! Select kod,Extract(uzenet,’//level/cim/text()’) From Uzenetek; Ezután xQuery segítségével valósítsuk meg ugyanezt! Select kod, XMLQuery( ’for $v in //level return $v/cim/text()’ PASSING BY VALUE uzenet RETURNING CONTENT) FROM Uzenetek; Írjuk át az olvasatlan levelek típusát (U) olvasottra (R)! UPDATE Uzenetek SET uzenet=UpdateXml( uzenet,’//level/tipus’,XMLTYPE( ’
R’)) WHERE ExtractValue(uzenet,’//level/tipus’)=’U’;
10. oldal
Adatbázis rendszerek
5.
Ötödik gyakorlat
5.1.
SQLJ távoli elérés
SQLJ távoli eléréshez szükségünk van a kapcsolódási paraméterekre, és a tűzfal megfelelő beállítására. A kapcsolódási paraméterek megadását egy példán keresztül mutatjuk be. jdbc:oracle:thin:@193.6.5.72:1521:orcl jdbc:oracle:thin: A kapcsolati drivert azonosítja, azaz JDBC segítségével kötődünk az adatbázisunkhoz. 193.6.5.72:1521: IP cím, vagy domain name formában azonosítjuk a távoli erőforrást, amihez kapcsolódni akarunk. orcl: Adatbázis SID (System ID). Ennek segítségével azonosíthatjuk be a szolgáltatást. Az Oracle hálózati komponensét (SQLNET ) használva a tnsnames.ora konfigurációs fájlban találhatjuk meg a lehetőségeket, amikből választhatunk. Ez kliens oldalon leírt, lokális összerendelése a logikai szervernévnek, és a fizikai paramétereknek.
5.2.
Első feladat
Írassuk ki SQLJ segítségével a felhasználó nevünket! public class Sqlj1 { public Sqlj1() { super(); } public static void main(String[] args) { Sqlj1 sqlj1 = new Sqlj1(); String username; System.out.println("Hello"); try { Oracle.connect("jdbc:oracle:thin:@193.6.5.72:1521:orcl","kovacs","CCC"); #sql {SELECT user INTO :username FROM dual }; System.out.println(username); } catch(SQLException e){ System.err.println(e.getMessage()); }; } }
5.3.
Második feladat
Készítsünk egy olyan metódust, mely megvalósítja egy táblába egy rekord felvitelét! A rekord mezőinek értékét a metódus a paraméterein keresztül kapja meg! public static int seged(int current_tkod, String current_tnev, int current_megyseg) { try{ #sql{INSERT INTO Termek(tkod,tnev,megyseg) VALUES (:current_tkod,:current_tnev,:current_megyseg)}; #sql{COMMIT}; } catch(SQLException e){ System.err.println(e.getMessage()); }; return 1; }
11. oldal
Adatbázis rendszerek
Ezen metódus meghívása a következőképpen történik: Sqlj1.seged(1,"auto",3);
5.4.
Harmadik feladat
Valósítsuk meg a nevek lekérdezését kurzor segítségével! Első lépésként hozzunk létre egy iterátor változót, az osztálydefiníció előtt! #sql iterator m1 (String tnev); Ezután hozzunk létre egy metódust az osztályban, ami megvalósítja a kurzort! public static void kurzoros() { try{ m1 it1=null; #sql it1 = {select tnev from termek order by tnev}; System.out.println("Elkezdve"); while(it1.next()){ System.out.println(it1.tnev()); } it1.close(); } catch (SQLException e){ System.err.println(e.getMessage()); }; } Ezután hívjuk meg a metódust! Sqlj1.kurzoros();
12. oldal
Adatbázis rendszerek
6.
Hatodik gyakorlat
Hozzunk létre egy UDT típust isqlplus szerveren keresztül! Hozzunk létre egy táblát, aminek egyik mezője ez az UDT típus, és töltsük fel két elemmel! Hajtsunk végre egy általános lekérdezést, és egyet az UDT típusú mező értéke alapján! CREATE TYPE diaktip AS OBJECT (Nev CHAR(20), Kor NUMBER(3)); CREATE TABLE munka (Kod NUMBER(3), Felelos diaktip); INSERT INTO munka VALUES(1,diaktip(’Laci’,23)); INSERT INTO munka VALUES(2,diaktip(’Feri’,24)); Ebben a parancsban látható diaktip(. . . ) szerkezet a létrehozott UDT típusunk konstruktora. SELECT * FROM munka; SELECT * FROM munka m where m.felelos.kor>23; Az m ebben az esetben egy iterátornak felel meg, amin keresztül érhetjük el az adott rekord mezőinek értékét. Először hivatkozunk az UDT típusú mező nevére, majd . operátor segítségével hivatkozunk annak elemére.
13. oldal
Adatbázis rendszerek
7.
Hetedik gyakorlat
7.1.
Adatbázis
Legyen az adatbázisunkban két tábla: • Dolgozók tábla: – Kód, elsődleges kulcs – Név – Fizetés – Üzem, idegen kulcs • Üzemek tábla: – Kód, elsődleges kulcs – Név
7.2.
Első feladat
Hozzunk létre PL/SQL nyelven egy tárolt eljárást, ami egy üzem rekordot visz fel az adatbázisunkba! Az értékeket bemenő paramétereken keresztül kapja meg! CREATE OR REPLACE PROCEDURE uj_uzem (current_kod int, current_nev char) IS Begin INSERT INTO uzemek(kod, nev) VALUES (current_kod, current_nev); End; A metódus hívása a következőképpen történik: EXECUTE uj_uzem(kod, nev);
7.3.
Második feladat
Hozzunk létre egy olyan tárolt eljárást, ami egy üzem rekordot visz fel az adatbázisunkba úgy, hogy csak az üem nevét kapja meg paraméterként, az üzem kódját a következő szabad értéknek tekinti! CREATE OR REPLACE PROCEDURE uj_uzem2(current_nev char) IS uj_ertek uzemek.kod%type; Begin Select max(kod) INTO uj_ertek FROM uzemek; Insert into uzemek(kod,nev) Values(uj_ertek+1,current_nev); End; Fontos megjegyezni, hogy ez az eljárás nem fog működni üres tábla esetén, mivel a Select utasítás nem ad vissza értéket.
7.4.
Második feladat javítása
Javítsuk ki a második feladatot úgy, hogy üres tábla esetén is működjön! Első megoldás: Hozzunk létre kivételt aszerint, hogy a Select parancs talált-e adatot! CREATE OR REPLACE PROCEDURE uj_uzem2_jav1(current_nev char) IS uj_ertek uzemek.kod%type; Begin Begin Select kod into uj_ertek from (select kod from uzemek order by kod desc) where rownum=1; Exception WHEN NO_DATA_FOUND THEN uj_ertek:=0; End; Insert into uzemek(kod,nev) Values(uj_ertek+1,current_nev); End; 14. oldal
Adatbázis rendszerek
Második megoldás: Hozzunk létre kivételt az alapján, hogy sikerült-e az Insert parancsnak rekordot felvinnie a táblába! CREATE OR REPLACE PROCEDURE uj_uzem2_jav2(current_nev char) IS uj_ertek uzemek.kod%type; Begin Begin Select max(kod) INTO uj_ertek FROM uzemek; Insert into uzemek(kod,nev) Values(uj_ertek+1,current_nev); Exception WHEN OTHERS THEN INSERT into uzemek(kod,nev) values(00,current_nev); End; End;
15. oldal
Adatbázis rendszerek
8.
Nyolcadik gyakorlat Adott a következő EER modell:
Valósítsuk meg ezt a modellt objektumrelációs adatbázis modellen keresztül, objektumtáblákat használva!
8.1.
Személy létrehozása
A Személyek tábla létrehozásához először el kell készítenünk egy lakcím típust. CREATE TYPE lakcim_t AS OBJECT (varos VARCHAR2(20), utca VARCHAR2(20)); Hozzuk létre a személy típust! A személy típusnak legyen egy életkort megadó függvénye! CREATE TYPE szemely_t AS OBJECT (nev VARCHAR2(20), lakcim LAKCIM_T, szul_ev NUMBER(4), MEMBER FUNCTION get_kor RETURN NUMBER) NOT FINAL; Hozzunk létre a függvény törzsét! CREATE OR REPLACE TYPE BODY szemely_t IS MEMBER FUNCTION get_kor RETURN NUMBER AS szk NUMBER(4); BEGIN SELECT TO_NUMBER(TO_CHAR(SYSDATE,’YYYY’)) - SELF.szul_ev INTO szk FROM DUAL; RETURN szk; END; END; Hozzuk létre a személyobjektumokból álló Személyek táblát! CREATE Table Szemelyek OF szemely_t; Töltsük fel ezt a táblát néhány személlyel! INSERT INTO szemelyek VALUES( szemely_t( ’sz1’,lakcim_t(’Eger’,’Ut 12’),1975)); INSERT INTO szemelyek VALUES( szemely_t( ’sz2’,lakcim_t(’Miskolc’,’Ut 13’),1985)); INSERT INTO szemelyek VALUES( szemely_t( ’sz3’,lakcim_t(’Eger’,’Ut 14’),1992)); 16. oldal
Adatbázis rendszerek
Kérdezzük le a személyek nevét, és életkorát! Select d.nev, d.get_kor() FROM szemelyek d; Kérdezzük le, hogy hányan laknak Egerben! Select count(*) FROM szemelyek d WHERE d.lakcim.varos=’Eger’;
17. oldal
Adatbázis rendszerek
9.
Kilencedik gyakorlat
Oldjuk meg LINQPad program segítségével a következő feladatokat! Használjuk a LINQPad C# statements beállítását!
9.1.
Parancsmód
Első feladat: Adjunk meg egy tömböt, és hajtsunk végre rendezett kiírást! string[] names = {"vas","ember","kabala"}; var q = from n in names orderby n select n; q.Dump(); Második feladat: Adjunk meg emberekből és hozzájuk tartozó kódokból áló rekordokat, és listázzuk ki név szerinti csökkenő sorrendben! var emberek = new [] { new{kod=1,nev="feri"}, new{kod=3,nev="antal"}, new{kod=4,nev="anna"}}; var q = from n in emberek orderby n.nev descending select new{nev=n.nev,kod=n.kod}; Harmadik feladat: Adottak emberek (kód, név, fizetés, beosztás). Listázzuk ki a 30 egységnél többet keresők neveit! var emberek = new [] { new{kod=1,nev="feri",fizetes=30,beosztas="fonok"}, new{kod=3,nev="antal",fizetes=29, beosztas="szerelo"}, new{kod=4,nev="anna", fizetes=31, beosztas="nagyfonoK"}}; var q = from n in emberek where n.fizetes>=30 orderby n.nev descending select n.nev; Negyedik feladat: Adjuk meg az emberek nevét, és azt, hogy hol található az üzemük! var emberek = new [] { new{kod=1,nev="feri",fizetes=30,beosztas="fonok", uzem=1}, new{kod=3,nev="antal",fizetes=29, beosztas="szerelo", uzem=2}, new{kod=4,nev="anna", fizetes=31, beosztas="nagyfonok", uzem=3}}; var uzemek = new[] new{kod=1, new{kod=2, new{kod=3,
{ varos="Eger"}, varos="Miskolc"}, varos="Budapest"}};
var q = from n in emberek join u in uzemek on n.uzem equals u.kod select new{nev=n.nev,varos=u.varos}; Ötödik feladat: Adjuk meg valamelyik beosztas átlagfizetését! Az átlagszámítás metódusként valósítható meg, amit egy objektumkollekcióhoz kell kötni.
18. oldal
Adatbázis rendszerek
var emberek = new [] { new{kod=1,nev="feri",fizetes=30,beosztas="fonok", uzem=1}, new{kod=3,nev="antal",fizetes=29, beosztas="kisfonok", uzem=2}, new{kod=4,nev="anna", fizetes=36, beosztas="fonok", uzem=3}}; var uzemek = new[] new{kod=1, new{kod=2, new{kod=3,
{ varos="Eger"}, varos="Miskolc"}, varos="Budapest"}};
var q = from n in emberek where n.beosztas=="fonok" group n.fizetes by 1 into g select g.Average();
9.2.
Lambda kalkulus
Első feladat: Adjuk meg az emberek neveit csökkenő sorrendben! var q = emberek.OrderBy(x => x.nev).Reverse().Select(x => x.nev); Második feladat: Számoljuk meg, hány főnök beosztású ember van! var q = emberek.Where(x => x.beosztas=="fonok").Count(); Harmadik feladat: Adjuk meg a főnök beosztású emberek átlagfizetését! var q = emberek.Where(x => x.beosztas=="fonok").Average(x => x.fizetes); Negyedik feladat: Adjuk meg az emberek nevét, és az üzemük városát! var q = emberek.Join(uzemek, x=>x.uzem, y => y.kod, (x,y) => new{x.nev,y.varos}); Ötödik feladat: Adjuk meg, hogy hányan dolgoznak az egyes városokban! var q = emberek.Join(uzemek, x=>x.uzem, y => y.kod, (x,y) => new{x.nev,y.varos}).GroupBy(x =>x.varos).Select(x => new{kulcs=x.Key, szam=x.Count()}); Hatodik feladat: Adjuk meg a második legtöbbet kereső ember nevét! var q = emberek.OrderBy(x=> x.fizetes).Reverse().Select(x => x.nev).ElementAt(1); Hetedik feladat: Adjuk meg az átlagnál többet keresők neveit! var q = emberek.Where(x=>x.fizetes>(emberek.Average(y=>y.fizetes))).Select(x=>x.nev);
19. oldal
Adatbázis rendszerek
10.
Tizedik gyakorlat
Datalog DLV rendszerben oldjuk meg a következő problémákat! A rendszer elérhető http://users.iit.uni-miskolc.hu/ kovacs/ Futtatás: dlv.exe parancssorból. Első feladat: Ha süt a Nap, akkor meleg az idő! sut_a_nap. meleg_van :- sut_a_nap. hideg_van :- not sut_a_nap. Második feladat: Adott három ember, és hozzájuk tartozó predikátum: idősebb. Valósítsuk meg a tranzitivitást! Futtatáskor be kell kapcsolni a -brave kapcsolót, hogy következtessen. idosebb(antal,feri). idosebb(feri,tomi). idosebb(X,Z) :- idosebb(X,Y), idosebb(Y,Z). idosebb(feri,X)? Harmadik feladat: Készítsünk egy családfát, és írjuk meg, hogy ki kinek a rokona, illetve ki kinek az unokája! szulo(anya,gyerek). szulo(apa,gyerek). szulo(apa,gyerek2). szulo(anya,gyerek2). szulo(nagyapa1,apa). szulo(nagyapa2,anya). szulo(nagymama1,anya). szulo(nagymama2,apa). unoka(X,Z) :- szulo(X,Y), szulo(Y,Z). rokona(X,Z) :- unoka(X,Z). rokona(X,Z) :- unoka(Z,X). rokona(X,Z) :- szulo(X,Z). rokona(X,Z) :- szulo(Z,X). rokona(X,Z) :- szulo(Y,X),szulo(Y,Z). Negyedik feladat: Páros számok meghatározására írjunk predikátumot! Fontos, hogy korlátozni kell futáskor, hogy mit jelent az egész tartomány, be kell állítani a maxint értékét. Ezt a -N=100 kapcsoló beállításával tudjuk 100ra beállítani. pszam(2). pszam(Y) :- Y=X+2, pszam(X). Ötödik feladat: Írjunkl predikátumot a Fibonacci számok meghatározására! fszam(1,1). fszam(2,1). fszam(X,Y) :- fszam(X1,Y1), fszam(X2,Y2), Y=Y1+Y2, X1=X-1, X2=X-2, X=X1+1, X1=X2+1. Ötödik feladat: Prímszámot meghatározó predikátum írása! osztoja(Y,X) :- \#mod(X,Y,0), Y>0, \#int(X), \#int(Y). nemprimszam(X) :- Y<X, Y>1, osztoja(Y,X), \#int(X), \#int(Y). primszam(X) :- not nemprimszam(X), X>1, \#int(X). primszam(X)? Hatodik feladat: Tanulmányozzuk a következő három színkérdést megoldó programot! http://www.dlvsystem.com/dlvsystem/index.php/3col Hetedik feladat: Tanulmányozzuk a következő programot! http://users.iit.uni-miskolc.hu/ kovacs/p1.txt
20. oldal
Adatbázis rendszerek
11. 11.1.
Tizenegyedik gyakorlat Protégé
Hozzunk létre egy mintaontológiát a következő módon! Legyenek ételek, azon belül levesek és főételek, illetve legyenek italok, azon belül alkoholos és alkoholmentes italok! Indítsuk el a Protégé ontológia-szerkesztő programot! Kattintsunk a Classes menüpontra, és hozzuk létre a mintát! Kattintsunk a Thing nevű osztályra, majd az Add subclass gombra! Így hozhatunk létre alosztályokat.
Lehetőségünk van az eddig létrehozott ontológiánkat megtekinteni XML -es alakban is. Ehhez kattintsunk a Window menüpontra, azon belüle Views, Ontology Views, és OWL/XML rendering. Az osztályhierarchia mellett találhatóak az osztályok leírásai. Állítsuk be itt, hogy az Ételek, és Italok egymással diszjunktak legyenek! Ehhez kattintsunk az Ételre, és a Disjoint With melletti plusz jelre kattintva állítsuk be az Ital osztályt, és ismételjük ezt meg a másik irányból! Állítsunk be tulajdonságokat a meglévő osztályainkhoz! Kattintsunk a Data Properties menüpontra, és hozzunk létre pár tulajdonságot a topDataProperty altulajdonságaiként! Ezekhez a tulajdonságokhoz állíthatunk értelmezési tartományt (Domains (intersection)), és értékkészletet (Ranges).
Hozzunk létre példányokat a meglévő osztályhoz! Kattintsunk az Individuals menüpontra! Itt láthatjuk az osztályhierarchiánkat, mellette a példányok listáját, amellett pedig azok tulajdonságait. Hozzunk létre egy példányt a Főételekhez! Ehhez kattintsunk a Főétel osztályra, majd a példányok listájánál az Add individual gombra!
21. oldal
Adatbázis rendszerek
11.2.
SPARQL
A SPARQL egy ontológia lekérdező nyelv, RDF alapokkal rendelkezik, az OWL ezt vette át. Kattintsunk a SPARQL Query menüpontra! Valósítsunk meg pár mintalekérdezést! Kérdezzük le a teljes adatbázis tartalmát! Select ?x ?y ?z Where {?x ?y ?z} Ez a lekérdezés minden állításhármast lekérdez. A ? után írt kifejezések változókat jelentenek. Az y a kapcsolat típusát jelöli, az x és z pedig az objektumot és szubjektumot. Írassuk ki az italokat! Ehhez létre kell hozni egy saját névteret, jelölje ezt sajat alias. Select ?x Where {?x rdfs:subClassOf sajat:Ital} Order By ?x Kérdezzük le a rantott_szelet nevű példányok árait! Select ?x Where { ?q a sajat:rantott_szelet. ?q sajat:ar ?x.}
22. oldal