web view1.1.paplašinājuma izstrāde ms visual studio vidē5. ... valodu prolog, funkcionālo...

49
Rīgas Tehniskā universitāte DATORZINĀTNES UN INFORMĀCIJAS TEHNOLOĢIJAS FAKULTĀTE Lielu datu bāzu administrēšana 3. darbs – Deduktīvās datu bāzes Izstrādāja: Dmitrijs Vecgailis I kurss 3. grupa St. apl. nr: 061RDB156 Pārbaudīja: asoc. prof. Jānis Eiduks

Upload: duonglien

Post on 10-Feb-2018

231 views

Category:

Documents


9 download

TRANSCRIPT

Rīgas Tehniskā universitāte

DATORZINĀTNES UN INFORMĀCIJAS TEHNOLOĢIJAS FAKULTĀTE

Lielu datu bāzu administrēšana

3. darbs – Deduktīvās datu bāzes

Izstrādāja: Dmitrijs Vecgailis

I kurss 3. grupa

St. apl. nr: 061RDB156

Pārbaudīja: asoc. prof. Jānis Eiduks

Rīga – 2010

SATURS

UZDEVUMA NOSTADNE....................................................................................................3

1. DEDUKTĪVĀS DATU BĀZES PROJEKTĒŠANA UN IMPLEMENTĒŠANA.....4

1.1. PAPLAŠINĀJUMA IZSTRĀDE MS VISUAL STUDIO VIDĒ...............................................51.2. TABULU RULES UN FACTS IZVEIDOŠANA.................................................................111.3. FAKTU TABULU VEIDOŠANA.....................................................................................12

2. TABULU AIZPILDĪŠANA..........................................................................................17

2.1. TABULU DATI............................................................................................................172.2. DATU IEVADE AR RĪKU BCP......................................................................................182.3. FAKTU IZGŪŠANA.....................................................................................................20

3. KONCEPTUĀLIE VAICĀJUMI................................................................................24

4. LIKUMU DEFINĒŠANA.............................................................................................25

4.1. CEĻU MEKLĒŠANA STARP DIVĀM PILSĒTĀM.............................................................254.2. ĪSĀKĀ MEKLĒŠANA STARP DIVĀM PILSĒTĀM............................................................254.3. BRAUKŠANAS LAIKA IZSKAITĻOŠANA......................................................................264.4. RULES TABULAS AIZPILDĪŠANA AR LIKUMIEM.........................................................27

5. DEDUKTĪVIE VAICĀJUMI......................................................................................28

SECINĀJUMI.......................................................................................................................35

PIELIKUMS..........................................................................................................................37

2

UZDEVUMA NOSTADNE

Praktiskā darba ietvaros ir jāizstrādā deduktīvā datu bāze, kas ļauj izpildīt sarežģītus

vaicājumus izmantojot kādas deklaratīvās programmēšanas valodas elementus (piemēram,

predikātu loģiku – valodu Prolog, funkcionālo valodu – LISP, datu bāzes paplašinājumu –

DATALOG utt.).

Deduktīvajā datu bāzē jānodrošina iespējas:

izpildīt rekursīvus vaicājumus;

papildināt zināšanu bāzi ar jauniem faktiem;

papildināt zināšanu bāzi ar jauniem izveduma likumiem;

uzglābāt faktu un likumus kā datu bāzes objektus.

3

DLL bibliotēka (paplašinājums) ar CS-PROLOGu un tabulāru funkciju SQLPROLOG

tabula Facts

tabula Rules

faktu tabula 1 faktu tabula 2 faktu tabula n…

MS SQL Server 2008datu bāze

1. DEDUKTĪVĀS DATU BĀZES PROJEKTĒŠANA UN IMPLEMENTĒŠANA

Deduktīvās datu bāzes projektēšanai tika izmantoti šādi līdzekļi:

DBVS Microsoft SQL Server 2008;

IDE Microsoft Visual Studio 2008;

brīvi pieejams (GPL licence) interpretators CS-Prolog1.

Izstrādātas deduktīvās datu bāzes arhitektūra ir parādīta . attēlā.

1. attēls. Izstrādātas deduktīvās datu bāzes arhitektūra

. attēlā ir redzams, ka sistēma sastāv no šādiem objektiem:

tabula Facts – tabulā ir ierakstītas tabulu nosaukumi, kuros glabājas fakti;

tabula Rules – tabulā atrodas lietotāja definēti izveduma likumi

formātā kolona1:-kolona2.;

faktu tabulas – relāciju tabulas, kuru ieraksti tiek uzskatīti par faktiem

formātā tabulas_nosaukums(kolona1, kolona2, kolona3, …, kolona3);

1 Interpretatora pirmkods pieejams pēc adreses http://sourceforge.net/projects/cs-prolog/

4

DLL bibliotēka ar izveduma mehānismu – bibliotēkā ir iekapsulēts

interpretators CS-Polog, kurš adaptēts (papildināts ar vienu klasi un tabulāru

funkciju) darbam ar datu bāzi.

Pirms izstrādāt deduktīvo datu bāzi ir jāveic šādi pasākumi:

Jāizveido lietotājs ar tiesībām papildināt datu bāzi ar CLR (Common

Language Runtime) struktūrām (t.i. procedūrām, funkcijām, trigeriem utt.,

kas ir veidoti C# vai kādā citā .NET valodā). Ir iespējams izmantot

administratora kontu;

Ir jānomaina savietojamības režīms, tā lai vērtība būtu 100 (t.i. būs aktivizētas

visas 2008 versijas iespējas, bet nebūs pilnas savietojamības ar iepriekšējām

versijām).

2. attēls. Savietojamības labošanas komanda (rīks SQLCMD)

1.1. Paplašinājuma izstrāde MS Visual Studio vidē

Sākumā tika izveidots jauns SQL Server tipa projekts (sk. . attēlu) ar nosaukumu

SQLProlog.

3. Jauna SQL Server projekta veidošana

5

Projektā bija jānorāda arī datu bāze, kurā tiks izmantotas izstrādājamās komponentes

(sk. . attēlu)

4. attēls. Savienojama izvēles vai veidošanas logs

Tika izmantots jauns pieslēgums iepriekšizveidotai (pagaidām tukšai) datu bāzei

SQLPROLOG (sk. . attēlu).

Autorizācijai tika izmantots administratora konts SA (administrators ir arī datu bāzes

īpašnieks), jo šī tipa lietotājam ir visas nepieciešamas tiesības papildināt datu bāzi ar CLR

tipa objektiem.

5. attēls. Savienojuma veidošanas logs

6

Tad projektā tika importētas visas CS-Prologa pirmkoda klases (sk. . attēlu). Šīs

klases izpildīs visas darbības Prolog vaicājumu apstrādei.

6. attēls. Projektā importētas CS-Prolog klases

Importētas klases nodrošina iespēju strādāt ar CS-Prologu interaktīvajā (konsoles)

režīmā, kad lietotājs ievada faktus un likumus no tastatūras vai ielāde no faila. Skaidrs, ka

deduktīvajā datu bāze faktus un likumus ir “jāņem” no tabulām un nav jānodrošina dialogs

ar lietotāju. Šo iemeslu dēļ, projekts tika papildināts vēl ar vienu klasi SQLProlog.cs

(sk. . attēlu), kurā tika aprakstītas visas metodes, kas ļauj strādāt gan ar datu bāzi, gan ar

Prologu (sk. . attēlu). Pilnais klases pirmkods ir pieejams pielikumā.

Klasē tika izveidotas šādas metodes:

ExecuteQuery(string query) – metode, kas apstrādā Prolog vaicājumu query

un atgriež rezultātu kā sarakstu;

AssertData – metode, kas ielāde faktus no tabulām;

LoadRules – metode, kas ielāde likumus no tabulas.

Metodes AssertData un LoadRules nav speciāli jāizsauc, tās nostrādā metodes

ExecuteQuery laikā.

7

7. attēls. Klases SQLProlog pievienošana

…namespace Prolog{ class SQLProlog { // engine - CS-Prologa interperatora eksemplars private static PrologEngine engine = new PrologEngine(); // Si funkcija atgriez sarakstu ar atbildem uz uzdoto vaicajumu public ArrayList ExecuteQuery(string query) {

… return list; } // Si funkcija pievieno faktus no datu bazes public void AssertData() { … } // Si funkcija pievieno likumus no datu bazes public void LoadRules() { … }}

8. attēls. Klases SQLProlg karkass

Projekts tika papildināts ar speciālo klasi, kas realizē datu bāzes funkciju, kura

atgriež tabulu (sk. . attēlu).

8

9. attēls. Lietotāja tabulārās funkcijas pievienošana

Klases ķermenis tika papildināts ar metodēm, kā paradīts . attēlā. Metode Prolog

(string query) kā argumentu saņem Prolog vaicājumu, bet kā rezultātu atgriež tabulu ar

piecām kolonām (TableDefinicion). Pati metode ir statiskā, un tabulas veidošanai netieši

izmanto papildus statisko metodi FillRow (šo metodi izsauc DBVS MS SQL Server

funkcijas Prolog izsaukšanas laikā).

Redzams, ka metode Prolog atgriež sarakstu, savukārt, metode FillRow apstrādā

atgriezta saraksta elementus un atgriež apstrādes rezultātus caur izejas argumentiem

(column_1, column_2, … , column_5), kuru definējums un secība sakrīt ar tabulas

definējumu.

9

Ņemot vērā to, ka dažiem vaicājumiem pieci elementi (piecas kolonas) izejas tabulā

dažreiz nemaz nav vajadzīgi, metodes sākumā nevajadzīgas kolonas tiek aizpildītas ar

tukšām vērtībām.

using System;using System.Collections;using System.Data;using System.Data.SqlClient;using System.Data.SqlTypes;using Microsoft.SqlServer.Server;using System.Diagnostics;namespace Prolog{ public partial class UDF //StoredProcedures { [SqlFunction(FillRowMethodName = "FillRow", TableDefinition = "column_1 nvarchar(4000), column_2 nvarchar(4000),column_3 nvarchar(4000), column_4 nvarchar(4000), column_5 nvarchar(4000)", DataAccess=DataAccessKind.Read)] public static IEnumerable Prolog(string query) { SQLProlog prolog = new SQLProlog(); ArrayList saraksts; prolog.AssertData(); prolog.LoadRules(); query = query.Replace('"', '\''); saraksts= prolog.ExecuteQuery(query); return saraksts; } private static void FillRow(Object obj, out string column_1, out string column_2, out string column_3, out string column_4, out string col-umn_5) { string[] row = (string[])obj; for (int i = 0; i < row.Length; i++) { row[i] = row[i].Replace("'", ""); } column_1 = ""; column_2 = ""; column_3 = ""; column_4 = ""; column_5 = ""; int j = row.Length; if (j-->0) column_1 = row[0]; if (j-->0) column_2 = row[1]; if (j-->0) column_3 = row[2]; if (j-->0) column_4 = row[3]; if (j-->0) column_5 = row[4];

} }};

10. attēls. Tabulārās funkcijas Prolog un papildus funkcijas FillRow pirmkodi

Izstrādāta funkcija atgriež tabulu ar neinicializēto mainīgo vērtībām. Tā, piemēram,

izsauc funkcija ar šādu vecaki (“Koks”, X), funkcija atgriezis vienu kolonu ar ierakstiem par

Koka vecākiem. Savukārt, ja funkciju izsaukt ar parametru vecaki (X,Y), funkcija atgriezis

10

divas kolonas – viena par kādu cilvēku, otra – par cilvēka vecākiem (patiesībā, funkcija

vienmēr atgriež piecas kolonas, bet informāciju satur tikai pirmās N kolonas, kur N -

neinicializēto mainīgo skaits predikātā (-os)).

Pēc aprakstīto darbību izpildes, projekta uzstādījumu logā tika norādīts (sk. . attēlu),

ka izstrādāto komponenti ir jālieto neaizsargāta režīmā (Unsafe). Tas izskaidrojams ar to, ka

PS-Prolog savā realizācijā satur “nedrošas” konstrukcijas (piemēram, destruktorus).

11. attēls. Projekta uzstādījumu mainīšana

Pēc aprakstīto darbību izpildes, projekts tika nokompilēts un datu bāzei automātiski

pievienojas jauna CLR tabulārā funkcija Prolog (query). Šī funkcija nav darbspējīga, kamēr

datu bāzē nav tabulu Rules un Fatcs.

1.2. Tabulu Rules un Facts izveidošana

Tabulu Rules un Facts izveidošanai tika izmantoti atbilstoši CREATE vaicājumi.

Tabulā Rules tika izveidota ar diviem laukiem:

Predicate – predikāta definējums (piemēram, max(X,Y,Z)).

Body – predikāta ķermenis ar realizāciju (piemēram, X>Y,Z is X,!;Z is Y);

Tādējādi, likums sastāv no divām daļām. Apvienojot divas daļās rodas Prolog

likums: max(X,Y,Z):-X>Y, Z is X,!; Z is Y).

Tabulā Facts sastāv no viena lauka – FactName – tabulas nosaukums, kurā glabājas

fakti.

Vaicājumi, kas veido šādas tabulas ir parādīti . un . attēlos.

11

12. attēls. Tabulas Rules veidošanas vaicājums

13. attēls. Tabulas Facts veidošanas vaicājums

Lai atvieglotu darbu, tika izveidota arī viena glabājamā procedūra, kuru izmanto

klase SQLProlog (sk. pielikumu), ar nosaukumu GetTable. Procedūra atgriež tabulu, kuras

nosaukums ir nodots kā parametrs. Lai realizētu šo procedūru, tika izmantota dinamiskā

konstrukcija EXEC (šī funkcija ir līdzīga Oracle funkcija EXECUTE IMMEDIATE).

Procedūras veidošanas vaicājums ir parādīts . attēlā.

14. attēls. Procedūras GetTable veidošanas vaicājums

1.3. Faktu tabulu veidošana

Lai nodrošinātu iespēju deduktīvai datu bāzei strādāt ar faktiem, tika izveidotas

vairākas tabulas, kurās glabāsies fakti.

Tabulai Pilsetas ir divi lauki – Pilsetas_ID un Pilseta. Pirmais (Pilsetas_ID) – ir

pilsētas unikālais numurs, otrais (Pilseta) – ir pilsētas nosaukums. Tādējādi, tabulā glābās

fakti par pilsētām. Tabulas veidošanas vaicājums ir parādīts . attēlā.

15 attēls. Tabulas Pilsetas veidošanas vaicājums

12

Tabulā Apskates_objekti ir apkopota informācija par apskates objektiem, ko var

redzēt noteiktajā pilsētā. Tabula sastāv no diviem laukiem: viens – Pilsetas_ID – pilsētas

numurs, otrs – Objekts – objekta nosaukums, kas atrodas attiecīgajā pilsēta. Vaicājums, kas

izveido tabulu ir parādīts . attēlā. Redzams, ka tabula ir saistīta ar tabulu Pilsētas.

16 attēls. Tabulas Apskates_objekti veidošanas vaicājums

Tabula Attalumi ir domāta, lai uzglabātu informāciju par attālumiem starp pilsētām, kuras pa tiešo ir saistītas ar ceļu. Tabulā ir trīs lauki. Pirmais un otrais (Pilseta_ID1 un Pilseta_ID2) norāda pilsētas, starp kuram ir ceļš, trešais lauks (Attalums) norāda attālumu starp pilsētām (pie tām, abas pilsētas ir saistītas ar ceļu). Vaicājums, kas izveido šo tabulu ir parādīts . attēlā.

17. attēls. Tabulas Attalumi veidošanas vaicājums

13

Tabula Celi satur informāciju par vidējo pārvietošanas ātrumu uz ceļiem. Ceļš tabulā

tiek uzdots kā trīs elementu kombinācija – ceļa sākumpunkts (lauks Pilseta_ID1), ceļa beigu

punkts (lauks Pilseta_ID2) un vidējais ātrums ar kuru var pārvietoties pa ceļu (lauks

Atrums). Uzdotais vidējais braukšanas ātrums attiecas uz visiem posmiem, kas atrodas starp

sākumu un beigām (piemēram, ja vidējais ātrums uz ceļa no pilsētas A līdz pilsētai C ir 80

km/st, un pilsēta A ir saistīta ar pilsētu B, bet pilsēta B ar pilsētu C (dati no tabulas

Attalumi), tad vidējais pārvietošanas ātrums starp pilsētām A un B (vai/un B un C) arī būs

80 km/st). Jāņem vērā, ka ceļš vienmēr ir mazākais attālums starp divām (gadījumos, ja ir

iespējami vairāki varianti). Vaicājums, kas izveido šo tabulu ir parādīts . attēlā.

Iegūtā datu bāzes tabulu struktūra ir parādīta . attēlā.

18.attēls. Tabulas Celi veidošanas vaicājums

14

19. attēls. Datu bāzes tabulu struktūra

. attēlā ir parādīta deduktīvas datu bāzes SQLProlog paplašinājuma darbības shēma.

Redzams, ka pēc funkcijas Prolog izsaukšanas notiek faktu un likumu ielāde atmiņā. Tad

notiek sākotnēja vaicājuma izpilde. Vaicājuma izpildes rezultāts tiek transformēts tabulā un

atgriezts kā funkcijas vērtība.

15

PROLOG (‘Vaicājums Prologā’)

klases SQLProlog eksemplāra veidošana

Metožu LoadRules un LoadFacts izsaukšana (faktu ielādē atmiņā)

Vaicājuma izpilde CS-Prologā

Rezultāts:X = Vērtība1,Y = Vērtība2;X = Vērtība3,Y = Vērtība4;true.

column_1 column_2 column_3 column_4 column_5

Vērtība1 Vērtība_2

Vērtība3 Vērtība4

Tabulas atgriešana

Rezultātu transformēšana tabulā

tabula Rules tabula Facts

tabulas ar faktiem

20. attēls. Deduktīvās datu bāzes SQLProlog paplašinājuma darbības shēma

16

Rīga

Sigulda

Salaspils

Jēkabpils

Jūrmala

Liepāja

Kuldīga

Ventspils

215 km91 km

58 km

166 km

119 km51 km

19 km

124 km

23km

Jelgava

47 km

137 km

Cēsis

39 km

2. TABULU AIZPILDĪŠANA

2.1. Tabulu dati

Tabulas tika aizpildītas ar datiem, kas satur informāciju par pilsētām, attālumiem

starp pilsētām, vidējo braukšanas ātrumu konkrētajā ceļā un informāciju par apskates

objektiem, kas atrodas noteiktajā pilsētā.

. attēlā ir parādīts ceļu tīkls (ar attālumiem starp pilsētām), kas tika izmantots tabulas

Attalumi aizpildīšanai.

21. attēls. Pilsētas, attālumi un ceļi.

. attēlā ir uzskaitīti ceļi starp pilsētām ar vidējo pārvietošanas ātrumu.

Pilsēta Pilsēta Ātrums (km/st)Rīga Cēsis 90Rīga Jēkabpils 85Rīga Jelgava 100

RīgaVentspils 95

Rīga Liepāja 85

LiepājaVentspils 75

Liepāja Jūrmala 85

KuldīgaVentspils 85

22. attēls. Informācija par vidējo ātrumu uz ceļiem

. attēlā ir uzskaitītas visas pilsētas un pilsētās esošās apskates objekti.

17

Pilsēta Apskates objekti objekti

Rīga Brīvdabas muzejsRīga Botāniskais dārzsRīga ZoodārzsRīga VecpilsētaRīga Dabas muzejsRīga PilsRīga PludmaleJēkabpils PilsJēkabpils Strausu fermaJēkabpils Brīvdabas muzejsCēsis PilsCēsis VējdzirnavaCēsis AlaCēsis Dabas parks

Salaspils Botāniskais dārzsSalaspils VecpilsētaSalaspils Doles salaJelgava PilsJelgava Mīlestības alejaJelgava VecpilsētaJelgava Dabas parksJūrmala PludmaleJūrmala AkvaparksJūrmala Bērnu parksLiepāja CietumsLiepāja PludmaleLiepāja KarostaLiepāja Izgriežamais tiltsKuldīga ŪdenskritumsKuldīga Vecpilsēta

Kuldīga Vecais tiltsKuldīga ŪdensdzirnavasKuldīga PilsVentspils Bērnu parksVentspils AkvaparksVentspils PludmaleVentspils GovsVentspils MazbānītisSigulda AlaSigulda PludmaleSigulda PilsSigulda PilsdrupasSigulda Dabas parksSigulda ŪdenskritumsSigulda Vagoniņš

23. attēls. Apskates objekti

2.2. Datu ievade ar rīku bcp

Rīks bcp ļauj ievadīt datus no teksta failiem (līdzīgs Oracle rīkam SQL*Loader).

Tabulas Pilsetas aizpildīšanai tika izmantots fails Pilsetas.txt (sk. . attēlu) un bcp

komanda, kas parādīta . attēlā.

1 Rīga2 Jēkabpils3 Cēsis4 Salaspils5 Jelgava6 Jūrmala7 Liepāja8 Kuldīga9 Ventspils10 Sigulda

24. attēls. Faila Pilsetas.txt saturs

25. attēls. Tabulas Pilsetas aizpildīšanas komanda

18

Tabulas Apskates_objekti aizpildīšanai tika izmantots fails Objekti.txt (sk. . attēlu)

un bcp komanda, kas parādīta . attēlā.

1 Brīvdabas muzejs1 Botāniskais dārzs1 Zoodārzs1 Vecpilsēta1 Dabas muzejs1 Pils1 Pludmale2 Pils2 Strausu ferma2 Brīvdabas muzejs3 Pils3 Vējdzirnavas3 Ala3 Dabas parks4 Botāniskais dārzs

4 Vecpilsēta4 Doles sala5 Pils5 Mīlestības aleja5 Vecpilsēta5 Dabas parks6 Pludmale6 Akvaparks6 Bērnu parks7 Cietums7 Pludmale7 Karosta7 Izgriežamais tilts8 Ūdenskritums8 Vecpilsēta

8 Vecais tilts8 Ūdensdzirnavas8 Pils9 Bērnu parks9 Akvaparks9 Pludmale9 Govs9 Mazbānītis10 Ala10 Pludmale10 Pils10 Pilsdrupas10 Dabas parks10 Ūdenskritums10 Vagoniņš

26. attēls. Faila Objekti.txt saturs

27 attēls. Tabulas Apskates_objekti aizpildīšanas komanda

Tabulas Attalumi aizpildīšanai tika izmantots fails Attalumi.txt (sk. . attēlu) un bcp

komanda, kas parādīta . attēlā.

1 10 511 4 191 5 471 6 231 7 2157 9 1197 8 918 9 588 6 1376 9 16610 3 394 2 124

28. attēls. Faila Attalumi.txt saturs

19

29 attēls. Tabulas Attalumi aizpildīšanas komanda

Tabulas Celi aizpildīšanai tika izmantots fails Celi.txt (sk. . attēlu) un bcp komanda,

kas parādīta . attēlā.

1 3 901 2 851 5 1001 9 951 7 857 9 757 6 858 9 85

30 attēls. Faila Celi.txt saturs

31. attēls. Tabulas Celi aizpildīšanas komanda

Lai Prolog paplašinājums zinātu, kur atrodas fakti, ko jāizmanto izvedumos, tabula

Facts tika papildināta ar ierakstiem, kas norāda uz vajadzīgām tabulām (sk. . attēlu).

32. attēls. Tabulas Facts aizpildīšanas vaicājums

2.3. Faktu izgūšana

Lai pārliecinātos, ka visas tabulas bija aizpildītas pareizi, tika izmantoti vairāki

SELECT vaicājumi. Nodāļā ir apskatīti gan parastie SQL vaicājumi, gan deduktīvie

vaicājumi, kas griežas pie tabulām kā pie faktiem.

Reālajās situācijās, gadījumos, kad ir iespējams iegūt vienu un to pašu rezultātu

izmantojot gan “tīro” SQL, gan deduktīvo paplašinājumu, datu izgūšanai ir jāizmanto

parastais SQL, jo tas vaicājumus izpilda ātrāk.

Vaicājumi, kas izgūst datus par attālumiem starp pilsētām ir parādīti . ,. attēlos.

20

33. attēls. Informācija par attālumiem starp pilsētām (SQL vaicājums)

34. attēls. Informācija par attālumiem starp pilsētām (deduktīvais vaicājums)

Vaicājumi, kas izgūst datus par pilsētas apskates objektiem ir parādīti ., . attēlos (ir

parādīts tikai izgūto datu fragments, jo tabulā ir liels ierakstu skaits).

21

35. attēls. Informācija par pilsētas apskates objektiem (SQL vaicājums)

36. attēls. Informācija par pilsētas apskates objektiem (deduktīvais vaicājums)

22

Vaicājumi, kas izgūst datus par vidējo pārvietošanas ātrumu ir parādīti . ,. attēlos.

37. attēls. Informācija par vidējām ātrumiem uz ceļiem (SQL vaicājums)

38. attēls. Informācija par vidējām ātrumiem uz ceļiem (deduktīvais vaicājums)

23

3. KONCEPTUĀLIE VAICĀJUMI

1. Kā nokļūt no pilsētas A līdz pilsētai B?

Vaicājumam ir jāatgriež visi iespējamie varianti kā var nokļūt no pilsētas A līdz

pilsētai B. Tā, piemēram, no Rīgas līdz Jūrmalai var nokļūt pa šādiem maršrutiem:

Rīga,JūrmalaRīga,Liepāja,Kuldīga,JūrmalaRīga,Liepāja,Kuldīga,Ventspils,JūrmalaRīga,Liepāja,Ventspils,JūrmalaRīga,Liepāja,Ventspils,Kuldīga,Jūrmala

Papildus vaicājumi (izmantojot arī SQL konstrukcijas):

1.1. Cik daudz variantu, kā var nokļūt no pilsētas A uz B?

1.2. Kāds ir garākais maršruts no pilsētas A līdz B, tā, lai pilsētas neatkārtotos un

nebūtu ciklu?

1.3. Kādi ir maršruti, ja braucot no pilsētas A līdz pilsētai B ir jāapmeklē pilsēta C.

1.4. Kur un pa kādiem ceļiem var aizbraukt no pilsētas A?

2. Kāds ir īsākais ceļš starp pilsētām A un B?

Vaicājumam ir jāatgriež īsākais ceļš kā var nokļūt no vienas pilsētas līdz otai,

piemēram, īsākais ceļš no Rīgas līdz Ventspils būs šāds:

Rīga, Jūrmala, Ventspils – 189 km

3. Kādā pilsētā atrodas noteiktais apskates objekts? Piemēram, ja uzdots jautājums,

kur atrodas ala, atbilde būs šāda:

Sigulda, Cēsis

Papildus vaicājumi (izmantojot arī SQL konstrukcijas):

3.1. Kādi apskates objekti atrodas noteiktajā pilsēta?

3.2. Kurā pilsēta, kas atrodas vistuvāk pilsēta A, atrodas noteikts objekts?

4. Cik ilgi jābrauc no pilsētas A līdz pilsētai B? Piemēram, no Rīgas līdz Jūrmalai

atbilde būs šāda:

Rīga – Jūrmala 16 minūtes

Papildus vaicājumi (izmantojot arī SQL konstrukcijas):

4.1. Cik ilgi jābrauc līdz pilsētai, kurā atrodas noteikts apskates objekts?

24

4. LIKUMU DEFINĒŠANA

4.1. Ceļu meklēšana starp divām pilsētām

Izstrādātais algoritms ļauj atrast visus ceļus starp divām grafa virsotnēm (izslēdzot

ciklus). Algoritma pirmkods Prolog valodā ir parādīts . attēlā.

39. attēls. Pirmkods ceļu meklēšanai grafā

Programmas izsaukšanai ir jāizmanto predikāts path(A, B, Path, Length), kur A -

sākuma pilsēta, B – beigu pilsēta, Path – atrastie ceļi, Length – atrasta ceļa garums.

4.2. Īsākā meklēšana starp divām pilsētām

Īsākais ceļš starp divām pilsētām ir viens no ceļiem, kura garums ir mazākais.

Tādējādi, īsākā ceļa meklēšanai var izmantot iepriekšdefinēto predikātu path atlasot īsāko

ceļu. Pirmkods, kas atrod īsāko ceļu ir parādīts . attēlā.

25

40. attēls. Īsākā ceļa meklēšanas algoritms

4.3. Braukšanas laika izskaitļošana

. attēlā piedāvātais algoritms izskaitļo laiku, ko jāpavada ceļā braucot pilsētas A līdz

pilsētai B. Rezultātā tiek atgriezts stundu skaits.

41. attēls. Braukšanas laika izskaitļošanas algoritms

26

4.4. Rules tabulas aizpildīšana ar likumiem

. attēlā ir parādīts faila Rules saturs. Failā ir iekļauti dati par deduktīvajā datu bāzē

izmantotājiem likumiem. . attēlā ir parādīts tabulas Rules aizpildīšanas rezultāts.

42. attēls. Faila Rules.txt saturs

43. attēls. Tabulas Rules aizpildīšana

27

Rīga

Sigulda

Salaspils

Jēkabpils

Jūrmala

Liepāja

Kuldīga

Ventspils

4,5,63 5

2

1,6

3,4

1,2,3,4,5,6

1,2,3

Jelgava1,2,3,4,5,6

2,3 6

Cēsis

5. DEDUKTĪVIE VAICĀJUMI

1. Kā nokļūt no pilsētas “Jēkabpils” līdz pilsētai “Ventspils” ?

Vaicājuma izpildes ilustrācija ir parādīta . attēla, deduktīvais vaicājums ir parādīts .

attēlā.

44. attēls. Vaicājuma ilustrācija

45. attēls. Deduktīvais vaicājums

1.1. Cik daudz variantu, kā var nokļūt no pilsētas Rīgas uz Ventspili?

Vaicājuma izpildes ilustrācija ir parādīta . attēla, deduktīvais vaicājums ir parādīts .

attēlā.

28

Rīga

Sigulda

Salaspils

Jēkabpils

Jūrmala

Liepāja

Kuldīga

Ventspils

4,5,63 5

2

1,6

3,4

1,2,3

Jelgava

2,3 6

Cēsis

Rīga

Sigulda

Salaspils

Jēkabpils

Jūrmala

Liepāja

Kuldīga

Ventspils

215 km91 km

58 km

166 km

119 km 51 km

19 km

124 km

23km

Jelgava

47 km

137 km

Cēsis

39 km

46. attēls. Vaicājuma ilustrācija

47. attēls. Deduktīvais vaicājums

1.2. Kāds ir garākais maršruts no Cēsis līdz Jēkabpils, tā, lai pilsētas neatkārtotos un

nebūtu ciklu?

Vaicājuma izpildei tika izmantots predikāts path ,SELECT konstrukcija ORDER BY

lai sakārtotu ierakstus pēc attālumiem un konstrukcija TOP 1, lai izvadītu tikai pirmo

ierakstu. Vaicājuma izpildes ilustrācija ir parādīta . attēla, deduktīvais vaicājums ir parādīts .

attēlā.

48. attēls. Vaicājuma ilustrācija

29

Rīga

Sigulda

Salaspils

Jēkabpils

Jūrmala

Liepāja

Kuldīga

Ventspils

1,2

2 4

2,3

3,4 1,2,3,4

1,2,3,4

Jelgava

1,4

Cēsis

49. attēls. Deduktīvais vaicājums

1.3. Kādi ir maršruti, ja braucot no Liepājas līdz Siguldai ir jāapmeklē Jūrmala.

Vaicājuma izpildes ilustrācija ir parādīta . attēla, deduktīvais vaicājums ir parādīts .

attēlā. Deduktīvais vaicājums atrod visus ceļus no Liepājas līdz Siguldai ar predikātu path un

tad atlasa maršrutus, kuros ir pilsēta Jūrmala.

50. attēls. Vaicājuma ilustrācija

51. attēls. Deduktīvais vaicājums

30

1.4. Kur un pa kādiem ceļiem var aizbraukt no Rīgas?

Šajā vaicājumā atšķirībā no iepriekšējiem vaicājumiem, otrais predikāta arguments

tika izmantots nevis kā ieejas parametrs, bet kā izejas. Vaicājuma izpildes rezultāts ir

parādīts . attēlā.

52. attēls. Deduktīvais vaicājums

Nav parādīti visi varianti, jo pavisam ir 78 ieraksti.

2. Kāds ir īsākais ceļš starp pilsētām Cēsis un Ventspils ?

Vaicājuma izpildes ilustrācija ir parādīta . attēla, deduktīvais vaicājums ir parādīts .

attēlā.

31

Rīga

Sigulda

Salaspils

Jēkabpils

Jūrmala

Liepāja

Kuldīga

Ventspils

215 km91 km

58 km

166 km

119 km 51 km

19 km

124 km

23km

Jelgava

47 km

137 km

Cēsis

39 km

53. attēls. Vaicājuma ilustrācija

54. attēls. Deduktīvais vaicājums

3. Kādās pilsētās atrodas akvaparks?

Vaicājuma izpildes rezultāts ir parādīts . attēlā. Analoģisko rezultātu var iegūt

izmantojot “parasto” SQL (piemēram, SELECT P.Pilseta FROM Pilsetas P,

Apskates_objekti A WHERE P.Pilsetas_ID=A.Pilsetas_ID AND

A.Objekts='Akvaparks').

55. attēls. Deduktīvais vaicājums

3.1. Kādi apskates objekti atrodas Rīgā?

Vaicājuma izpildes rezultāts ir parādīts . attēlā. Analoģisko rezultātu var iegūt

izmantojot “parasto” SQL (piemēram, SELECT A.Objekts FROM Pilsetas P,

32

Apskates_objekti A WHERE P.Pilsetas_ID=A.Pilsetas_ID AND

P.Pilseta='Rīga').

56. attēls. Deduktīvais vaicājums

3.2. Kurā pilsēta, kas atrodas vistuvāk Rīgai, ir ūdenskritums?

Vaicājuma izpildes rezultāts ir parādīts . attēlā. Sākumā deduktīvajā daļā notiek īsākā

ceļa atrāšana līdz pilsētai, kur atrodas ūdenskritums, tad ar ORDER BY un TOP 1 no visiem

ierakstiem tiek atlasīts tikai viens ieraksts – tuvākā līdz Rīgai pilsēta, kur ir ūdenskritums.

57. attēls. Deduktīvais vaicājums

4. Cik ilgi jābrauc no pilsētas Jēkabpils līdz Cēsīm?

Vaicājuma izpildes rezultāts ir parādīts . attēlā. Vaicājumā pamatdaļā notiek lauka

column_2 transformēšana (pārveidošana) uz skaitli (jo visi tabulārās funkcijas tabulas lauki

ir teksta rindas – nvarchar) un reizināšana ar 60, lai iegūtu minūtes.

33

58. attēls. Deduktīvais vaicājums

Papildus vaicājumi (izmantojot arī SQL konstrukcijas):

4.1. Cik ilgi jābrauc no Liepājas līdz pilsētai, kurā atrodas botāniskais dārzs?

Vaicājuma izpildes rezultāts ir parādīts . attēlā.

59. attēls. Deduktīvais vaicājums

34

SECINĀJUMI

Laboratorijas darba gaitā tika izstrādāts speciālais paplašinājums priekš DBVS

Mircosoft SQL Server 2008. Paplašinājums ļauj lietotājam izpildīt deduktīvos vaicājumus

izmantojot faktus un likumus no tabulām.

Darbs sastāv no piecām nodaļām. Pirmajā nodaļā ir sniegti paskaidrojumi par

paplašinājuma izstrādi. Paplašinājuma izstrādei tika izmantoti brīvi pieejami Prolog

interpretatora CS-Prolog pirmkodi. Nodaļā ir aprakstīts lietotāja funkcijas definēšanas

process valodā C#. Nodaļā ir arī uzskaitītas visas tabulas, kas tika izmantotas paplašinājuma

darbības pārbaudei un uzrakstīti visi vaicājumi šo tabulu izveidošanai.

Otrajā nodaļā ir aprakstīta procedūra, kas tika izmantota tabulu aizpildīšanai ar rīku

BCP. Ir parādīti faili, kas tika izmantoti tabulu aizpildīšanai, un komandas tabulu

aizpildīšanai.

Trešajā nodaļā ir nodefinēti konceptuālie vaicājumu izpildei ar paplašinājuma

palīdzību.

Ceturtajā nodaļā ir parādīti visi pirmkodi valodā Prolog trešajā nodaļā definēto

vaicājumu izpildei. Ir sniegti paskaidrojumi par algoritmu darbības principiem, kā arī

parādīts, ka tika aizpildīta tabula Rules

Piektajā nodaļā ir parādīti deduktīvi vaicājumi un šo vaicājumu izpildes rezultāti.

Sava ķermenī vaicājumi satur gan ceturtajā nodaļā nodefinētu likumus, gan tos predikātus,

kas jau ir iebūvēti CS-Prologā (piemēram, member).

Izstrādātām paplašinājumam ir šādas priekšrocības:

nav redundantā informācija t.i. nav jāglabā tie fakti, ko var izvest (izsecināt)

no citiem faktiem. Piemēram, lai uzglabātu informāciju par visiem

iespējamiem maršrutiem no jebkuras pilsētas līdz jebkurai citai, ar darbā

piedāvātu ceļu karti, būtu jāveido tabula ar 924 ierakstiem (reālajās dzīvēs

situācijās šīs skaitlis būtu vairākas reizes lielāks);

viegli izmantot rekursiju un maksimālais rekursijas dziļums ir lielāks nekā

izmantojot MS SQL Server 2008 glabājamās procedūras, kur rekursijas

dziļums nevar būt lielāks par 32 līmeņiem;

tā iemesla dēļ, ka dati tiek atgriezt tabulārajā struktūrā, izgūto informāciju var

apstrādāt ar SQL konstrukcijām (WHERE, funkcijas un apakšvaicājumi) un

savienot ar datus citām tabulām;

likumu definēšanai jāizmanto Prolog sintakse, kas ievērojami atvieglo likumu

definēšanu.

35

Risinājumam piemīt arī vairāki trūkumi:

zemā ātrdarbība – vaicājumi lēni apstrādājas, jo CS-Prolog ir interpretators un

pirms vaicājuma izpildes notiek faktu un likumu ielādēšana atmiņā. Šī

iemesla dēļ, deduktīvo paplašinājumu ir jāizmanto tikai tad, kad līdzīgo

darbību nav iespējams izpildīt ar parasto SELECT vaicājumu;

atrieztajā tabulā kolonu skaits vienmēr ir pieci, kaut arī mēdz būt gadījumi,

kad ir nepieciešams atgriezt lielākais kolonu skaits (kolonu skaitu var mainīt

funkcijas definējumā, bet to nav iespējams mainīt dinamiski izpildes laikā);

Salīdzinājumā ar Oracle MS SQL Server 2008 ir daži trūkumi. Pirmkārt, funkciju,

procedūru, trigeru definēšanai ir vēlams izmantot ārējās bibliotēkas (t.i. rakstīt tās C# vai

VB.NET valodās), jo šādu funkciju ātrdarbība ir lielāka nekā līdzīgajai konstrukcijai T-SQL

valodā (izņemot gadījumos, kad ir jāveic tikai datu izgūšana), kā arī valoda T-SQL nav tik

elastīga (un nesatur tik pat daudz konstrukciju) kā Oracle PL/SQL. Otrkārt, dažas

konstrukcijās var izveidot izmantojot tikai CLR komponentes, tā, piemēram, agrēgējošo

funkciju un tipu definēšanai (darbā šādas konstrukcijas nav apskatītas) jāizmanto C# vai

VB.NET valoda. Kā arī, salīdzinājumā ar Oracle, MS SQL Server tipi nevar būt kolekcijas

vai masīvi – tie var būt tikai no pamattipiem veidotie saliktie tipi.

Deduktīvās datu bāzes ir ļoti jaudīgs mehānisms, kas ļauj izpildīt sarežģītus

vaicājumus situācijās, kad nav nepieciešamus faktus, tos var iegūt ar izvedumu. Diemžēl, par

mehānisma jaudu ir “jāmaksā” ar ātrdarbību, tāpēc, reālajās dzīves situācijās, datu bāzes

deduktīvo paplašinājumu ir lietderīgi veidot atsevišķajā lietojumserverā (var, piemēram,

izmantot serviss-orientēto arhitektūru), lai datu bāze nebūtu pārslogota ar sarežģītu operāciju

izpildi.

Darba gaitā izdevās nostiprināt lekcijās iegūtas zināšanas un arī iegūt jaunas

zināšanas lasot grāmatas un interneta avotus.

36

PIELIKUMSusing System;using System.Collections.Generic;using System.Collections;using System.Text;using System.Data.SqlClient;using System.Data;using System.Data.SqlTypes;

namespace Prolog{ class SQLProlog { private static PrologEngine engine = new PrologEngine(); // Si funkcija atgriez sarakstu ar atbildem uz uzdoto vaicajumu public ArrayList ExecuteQuery(string query) { StringBuilder queryBuilder = new StringBuilder(); ArrayList list = new ArrayList(); bool result = engine.ExecuteQuery(ref query); while (!engine.Halted) { { string[] row = new string[engine.Variables.Count]; int j = 0; foreach (DictionaryEntry de in engine.Variables) { row[j++] = de.Value.ToString(); } list.Add(row); // pievieno jauno atbildi sarakstam } if (engine.CanBacktrack(false)) { result = engine.More(); } else break; } return list; }

// Si funkcija pievieno faktus no datu bazes public void AssertData() { string connetionstring = "Data Source=WINDOWSXP;Initial Cata-log=SQLPROLOG;Persist Security Info=True;User ID=Dmitry;Password=123"; SqlConnection con = new SqlConnection (connetionstring); con.Open(); SqlConnection tableconnection = new SqlConnection(connetion-string); tableconnection.Open(); SqlCommand com = new SqlCommand("dbo.GetTable"); com.Connection = con; com.CommandType = CommandType.StoredProcedure; com.Parameters.Add(new SqlParameter("@Table", "Facts")); com.Parameters[0].Direction = ParameterDirection.Input; SqlDataReader reader = com.ExecuteReader(); SqlCommand tablecommand = new SqlCommand(); SqlDataReader tablereader; string assertcommand; string tablename; while (reader.Read())

37

{ tablename = reader.GetString(0); tablecommand.CommandType = CommandType.Text; tablecommand.CommandText = "SELECT * FROM "+tablename; tablecommand.Connection = tableconnection; tablereader = tablecommand.ExecuteReader(); string retractcomand = "retractall(" + tablename.ToLower() + "("; for (int i = 0; i < tablereader.FieldCount; i++) { if (i != 0) retractcomand += ","; retractcomand += "_";

} retractcomand += "))."; engine.ExecuteQuery(ref retractcomand); while (tablereader.Read()) { assertcommand = "assert(" + tablename.ToLower() + "("; for (int i = 0; i < tablereader.FieldCount; ++i) { if (i != 0) assertcommand += ","; if (tablereader.GetProviderSpecificFieldType(i).ToString() == "System.Da-ta.SqlTypes.SqlString") { assertcommand += "'" + tablereader.GetString(i) + "'"; } if (tablereader.GetProviderSpecificFieldType(i).ToString() == "System.Da-ta.SqlTypes.SqlInt64") { assertcommand += tablereader.GetInt64(i).ToString() ; } if (i == tablereader.FieldCount - 1) { assertcommand += "))."; engine.ExecuteQuery(ref assertcommand); } } } tablereader.Close(); } reader.Close(); } public void LoadRules() { SqlConnection con = new SqlConnection ("Data Source=WINDOWSXP;Initial Catalog=SQLPROLOG;Persist Security Info=True;User ID=Dmitry;Password=123"); con.Open(); SqlCommand com = new SqlCommand("SELECT * FROM RULES", con); SqlDataReader reader = com.ExecuteReader(); while (reader.Read()) { string pred = reader.GetString(0); string body = reader.GetString(1); string newpred = pred; string predretract = "retractall(" + newpred + ")."; engine.ExecuteQuery(ref predretract);

38

} reader.Close(); reader = com.ExecuteReader(); while (reader.Read()) { string pred = reader.GetString(0); string body = reader.GetString(1); string newpred = pred; if (body.Trim().Length == 0) newpred += ""; else { newpred += ":-" + body; } string assertpred = "assert(" + newpred + ")."; engine.ExecuteQuery(ref assertpred); } } }

}

39