1 / 35

Obiektowe języki zapytań

Obiektowe języki zapytań. Wykładowca : Kazimierz Subieta Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa subieta@pjwstk.edu.pl Instytut Podstaw Informatyki PAN, Warszawa subieta@ipipan.waw.pl. Wykład 09: Język SBQL (Stack-Based Query Language) (2)

channer
Download Presentation

Obiektowe języki zapytań

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Obiektowe języki zapytań Wykładowca: Kazimierz Subieta Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa subieta@pjwstk.edu.pl Instytut Podstaw Informatyki PAN, Warszawa subieta@ipipan.waw.pl Wykład 09: Język SBQL (Stack-Based Query Language) (2) Operatory niealgebraiczne, przykłady zapytań w SBQL

  2. Dlaczego "niealgebraiczne"? (1) • Do nich należą operator where, operator kropki, kwantyfikatory, zależne złączenie join, sortowanie (order by), i inne. Wszystkie są binarne. • Mimo podobieństwa do operatorów algebraicznych, semantyka operatorów niealgebraicznych nie da się prosto sprowadzić do algebry. • To zdanie może wydawać się niejasne. W modelu relacyjnym operatory selekcji (operator where), projekcji (operator kropki) oraz złączenia są przecież traktowane jako operatory algebraiczne algebry relacji. • Tu właśnie jest nieporozumienie. Takie traktowanie jest możliwe wyłącznie przy ograniczonej funkcjonalności, oraz po przyjęciu triku formalnego. • Trik polega na tym, że część semantyki jest przenoszona na poziom metajęzykowy. Operatory te są dodatkowo kwalifikowane wyrażeniem metajęzykowym. Np. w wyrażeniu algebry relacyjnej: Zar>1000( Prac ) operator selekcji  jest kwalifikowany wyrażeniem metajęzykowym Zar >1000. Operator selekcji nie jest pojedynczym operatorem, lecz nieskończoną rodziną zawierającą tyle operatorów, ile jest warunków selekcji.

  3. Dlaczego "niealgebraiczne"? (2) • Powyższy trik można uważać za uzasadniony w przypadku, gdy wyrażenie metajęzykowe parametryzujące operator jest proste, a jego semantyka jest oczywista. Nie zawsze to jest prawda. Operator selekcji może mieć bardziej złożony warunek selekcji, np. ZarobekNetto( Zar + 100 )>1000( Prac ) • Warunek selekcji zawiera operator + oraz wywołuje pewną funkcję ZarobekNetto. Wyrażenie metajęzykowe posiada nietrywialną wewnętrzną semantykę, która jest nieformalna. Jest to po prostu nieformalny komentarz. • Jeżeli jakikolwiek składnik języka nie ma formalnej semantyki, to cały język również nie ma formalnej semantyki. • Mimo podobieństwa wizualnego, w powyższych wyrażeniach nazwy Prac oraz Zar są ulokowane w dwóch różnych światach. • Pierwsza nazwa należy do języka algebry relacji, jest „pierwszej kategorii”, podlega formalnemu traktowaniu. • Natomiast druga nazwa należy do metajęzyka algebry relacji, jest „drugiej kategorii”, nie podlega formalnemu traktowaniu.

  4. Dlaczego "niealgebraiczne"? (3) • W ten sposób złamana została zasada relatywizmu, zgodnie z którą nazwy nie mogą posiadać fundamentalnie różnej semantyki w zależności od tego, jakiego rodzaju dane oznaczają. • Ta zasada staje się szczególnie istotna dla języków obiektowych, gdyż obiekty mogą mieć strukturę hierarchiczną, zaś nazwy mogą oznaczać dane na dowolnym poziomie hierarchii obiektów. • Podobny problem dotyczy operatorów. Operator selekcji  jest elementem języka tej algebry, należy do „pierwszej kategorii”, podczas gdy operator < występuje w metajęzyku, jest „drugiej kategorii”. • Powyższa językowo-meta-językowa schizofrenia podważa poprawność definicji semantyki. • Podane argumenty są wystarczające aby twierdzić, że tzw.algebry obiektowe są pseudo-matematyczną bzdurą (włączając algebry dla XML).

  5. Dlaczego "niealgebraiczne"? (4) • W podejściu stosowym dowolne operatory nie są indeksowane wyrażeniami meta-językowymi. • Nie występuje więc semantyczna schizofrenia nazw dzieląca je na „językowe” i „meta-językowe”. • Nie ma podziału na nazwy „pierwszej kategorii” i „drugiej kategorii”. Każda nazwa ma dokładnie taką samą semantykę i podlega dokładnie tym samym regułom wiązania i zakresu • Podobnie z operatorami: nie występuje semantyczne zróżnicowanie operatorów: operator < występuje na tym samym poziomie semantycznym jak operator selekcji where. • Koncepcja operatorów niealgebraicznych jest bardzo prosta oraz ma dobrze ugruntowane korzenie w semantyce języków programowania. • Definicja operatorów niealgebraicznych będzie się nieco różniła w zależności od tego, który modelu składu (M0 - M3) będzie rozpatrywany. Wszystkie te definicje będą bazowały na podanej niżej podstawowej definicji dla modelu M0.

  6. Opis procedury eval dla operatora nie-algebr.  • Aby dokonać ewaluacji zapytania q1 q2 wykonaj następujące czynności: • Dokonaj ewaluacji zapytania q1. Zapytanie to zwraca wielozbiór elementów. • Dla każdego elementu e należącego do wyniku q1 wykonaj następujące czynności: • Oblicz wartość funkcji nested( e ). Wynik jest zbiorem binderów. • Włóż obliczony zbiór binderów jako nową sekcje na wierzchołek stosu ENVS. • Dokonaj ewaluacji zapytania q2 w tym nowym środowisku. • Oblicz wynik cząstkowy dla danego elementu e poprzez połączenie e z wynikiem zwróconym przez q2. Funkcja łącząca zależy od operatora . • Usuń nowo wstawioną górną sekcję ze stosu ENVS. • Zsumuj wszystkie wyniki cząstkowe w wynik końcowy. Sposób sumowania sumuj ( U ) zależy od rodzaju operatora . • Stan stosu środowisk ENVS po zakończeniu ewaluacji jest taki sam, jak przez rozpoczęciem ewaluacji.

  7. Formalny zapis procedury eval dla oper. niealgebr. procedureeval( q : zapytanie ) begin ...... caseq jest rozpoznane jako q1 q2 : (* q1 , q2 są zapytaniami,  jest operatorem niealgebraicznym *) begin wyniki_pośr: bag ofRezultat; (* lokalna kolekcja wyników pośrednich *) wynik_pośredni: Rezultat; (* lokalna zmienna na wynik pośredni *) wynik_końcowy: Rezultat; (* lokalna zmienna na wynik końcowy *) e: Rezultat; (* lokalna zmienna na element kolekcji zwracanej przez q1 *) wyniki_pośr := ; (* zerowanie kolekcji wyników pośrednich *) eval( q1); (*q1 zwraca kolekcję elementów; wynik q1na czubku stosu QRES *) for eachein top( QRES ) do (* iteracja po wszystkich elementach wyniku q1 *) begin push( ENVS, nested( e ) ); (* nowa sekcja na stosie środowisk *) eval( q2 ); (* wynik q2 na czubku stosu QRES *) wynik_pośredni := połącz( e, top( QRES ) ); (* połączenie e z wynikiem q2; zależne od  *) wyniki_pośr := wyniki_pośr U { wynik_pośredni }; (* akumulacja wyniku pośredniego *) pop( QRES ); (* usuniecie z QRES wyniku q2 *) pop( ENVS ); (* usuniecie z ENVS nowej sekcji *) end; wynik_końcowy := sumuj( wyniki_pośr ); (* zsumowanie wyników pośrednich; zależne od  *) pop( QRES ); (* usuniecie z QRES wyniku q1 *) push( QRES, wynik_końcowy ); (* włożenie na QRES końcowego wyniku *) end; ....... end;

  8. Poglądowy obraz małej bazy danych i1Prac i5Prac i9Prac i2 Nazwisko ”Nowak” i6 Nazwisko ”Kowalski” i10 Nazwisko ”Barski” i3 Zar 2500 i7 Zar 2000 i11 Zar 900 i4 PracujeW i12 Adres i8 PracujeW i13 Miasto ”Radom” i14 Ulica ”Wolska” i15 NrDomu 12 i16 PracujeW i17Dział i22Dział i18 Nazwa ”Produkcja” i23 Nazwa ”Sprzedaż” i19 Lokacja ”Kielce” i24 Lokacja ”Radom” i25 Zatrudnia i20 Lokacja ”Kraków” i26 Zatrudnia i21 Zatrudnia

  9. Operatorwhere (selekcja) • Składnia: q1whereq2 • Ograniczenie: podzapytanie q2 zwraca wartość prawda lub fałsz. • Semantyka • Dla każdego elementu e zwróconego przez q1, ENVS jest podwyższany o nested(e) • Następnie ewaluowane jest q2 • Po ewaluacji q2 stos ENVS wraca do poprzedniego stanu • e należy do ostatecznego wyniku wyłącznie wtedy, gdy q2 zwróciło prawda. • Objaśnienie funkcji eval • Funkcja połącz: dla danego e należącego do wyniku q1zwraca jednoelementowy wielozbiór { e } w przypadku, gdy dla tego e podzapytanie q2 zwróciło prawda, lub pusty wielozbiór { }, jeżeli podzapytanie q2 zwróciło fałsz. • Funkcja sumuj: sumuje (mnogościowo) wszystkie wyniki pośrednie. • Przykład: Pracwhere ( Zar > 1000 )

  10. Operatorwhere - ilustracja działania 1000 prawda i3 2500 prawda i7 2000 1000 i11 900 1000 fałsz Nazwisko(i6) Zar(i7) PracujeW(i8) Nazwisko(i10) Zar(i11) Adres(i12) PracujeW(i16) Nazwisko(i2) Zar(i3) PracujeW(i4) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Rezultat zwracany przez zapytanie Prac (wiązanie Prac) Iteracja po elementach e poprzedniego rezultatu: na ENVS wkłada się nested(e) Rezultat zwracany przez zapytanie Zar (wiązanie Zar) Rezultat dereferencji wymuszanej przez operator > Rezultat zwracany przez zapytanie 1000 Rezultat zwracany przez zapytanie Zar>1000 Końcowy rezultat zapytania i1 i5 i9 i1 i5 Stan stosu ENVS przed ewaluacją Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac where ( Zar > 1000 )

  11. Operator kropki (projekcja, nawigacja) • Składnia: q1. q2 • Semantyka • Dla każdego elementu e zwróconego przez q1, ENVS jest podwyższany o nested(e) • Następnie ewaluowane jest q2 • Po ewaluacji q2 stos ENVS wraca do poprzedniego stanu • Ostateczny wynik jest sumą mnogościową wyników q2 • Objaśnienie funkcji eval • Funkcja połącz: ignoruje e; zwraca wynik podzapytania q2. • Funkcja sumuj: sumuje (mnogościowo) wszystkie wyniki pośrednie. • Przykład: Prac .Zar • Operator kropki przykrywa tzw. wyrażenia ścieżkowe (path expressions) w najbardziej uniwersalnej postaci, pozwalając je jednocześnie dowolnie kombinować z innymi operatorami.

  12. Operator kropki - ilustracja działania i3 i7 i11 Nazwisko(i6) Zar(i7) PracujeW(i8) Nazwisko(i2) Zar(i3) PracujeW(i4) Nazwisko(i10) Zar(i11) Adres(i12) PracujeW(i16) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Rezultat zwracany przez zapytanie Prac (wiązanie Prac) Iteracja po elementach e poprzedniego rezultatu: na ENVS wkłada się nested(e) Rezultat zwracany przez zapytanie Zar (wiązanie Zar) Końcowy rezultat zapytania i1 i5 i9 i3 i7 i11 Stan stosu ENVS przed ewaluacją Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac . Zar

  13. Operator zależnego złączenia • Składnia: q1joinq2 • Semantyka • Dla każdego e zwróconego przez q1, ENVS jest podwyższany o nested(e) • Następnie ewaluowane jest q2 • Po ewaluacji q2 stos ENVS wraca do poprzedniego stanu • Ostateczny wynik jest sumą mnogościową wszystkich struktur, w których na początku jest e, zaś dalej jest element wyniku q2 zwrócony dla tego e. • Objaśnienie funkcji eval • Funkcja połącz: zarówno e jak i każdy element e2 zwracany przez q2 traktuje jako struktury (jednoelementowe lub wieloelementowe). Dla każdego e2 zwracanego przez q2 tworzy strukturę poprzez połączenie e oraz e2. Wynikiem pośrednim jest kolekcja wszystkich takich struktur. • Funkcja sumuj: sumuje (mnogościowo) wszystkie wyniki pośrednie. • Przykład: Prac joinZar • Zależne złączenie jest zdefiniowane w ODMG OQL (klauzula from) w znacznie ograniczonej postaci w stosunku do powyższej definicji.

  14. Operator zależnego złączenia - ilustracja działania i3 i7 i11 Nazwisko(i6) Zar(i7) PracujeW(i8) Nazwisko(i2) Zar(i3) PracujeW(i4) Nazwisko(i10) Zar(i11) Adres(i12) PracujeW(i16) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Rezultat zwracany przez zapytanie Prac (wiązanie Prac) Iteracja po elementach e poprzedniego rezultatu: na ENVS wkłada się nested(e) Rezultat zwracany przez zapytanie Zar (wiązanie Zar) Końcowy rezultat zapytania i1 i5 i9 struct(i1, i3) struct(i5, i7) struct(i9, i11 ) Stan stosu ENVS przed ewaluacją Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac join Zar

  15. Operator sortowania • Składnia: q1order by q2 • Semantyka • Wykonywane jest zapytanie: q1joindereferencja( q2 ) • Wynik (bag) jest sortowany według części struktur zwróconej przez q2 . Po posortowaniu wynik jest sekwencją. • Końcowy wynik uzyskuje się poprzez projekcję tej sekwencji (bez zmiany kolejności elementów na części struktur zwrócone przez q1 . • Np. Pracorder byNazwisko Pracorder by ((PracujeW.Dział.Nazwa), Zarobek) • Operator ten można dodatkowo wyposażyć w kwalifikatory asc (wzrastająco) i desc (malejąco) przy każdej składowej q2. • Np. Pracorder by ((PracujeW.Dział.Nazwa) asc, Zarobek desc) • Operator asc jest komentarzem, operator desc jest odwrotnością wartości: np. 5 desc oznacza -5, "abceg" desc oznacza "zyxvt", itd. • Operator ten należy parametryzować (najlepiej konfiguracyjnie) funkcją porównania elementów (zależną od języka: angielski, polski, niemiecki,.. ).

  16. Kwantyfikator egzystencjalny • Składnia: q1(q2 ) lub q1q2 • Ograniczenie: podzapytanie q2 zwraca wartość prawda lub fałsz. • Semantyka • Dla każdego e zwróconego przez q1, ENVS jest podwyższany o nested(e) • Następnie ewaluowane jest q2 • Po ewaluacji q2 stos ENVS wraca do poprzedniego stanu • Ostateczny wynik jest prawda wtedy i tylko wtedy, jeżeli dla co najmniej jednego e podzapytanie q2 zwróciło prawda. • Objaśnienie funkcji eval • Funkcja połącz: ignoruje e; zwraca wynik podzapytania q2. • Funkcja sumuj: Zwraca prawda jeżeli co najmniej jeden wynik pośredni zwrócony przez q2 jest prawda; w przeciwnym wypadku zwraca fałsz. • Przykład: Prac ( Zar > 1000 )

  17. Kwantyfikator uniwersalny • Składnia: q1(q2 ) lub q1q2 • Ograniczenie: podzapytanie q2 zwraca wartość prawda lub fałsz. • Semantyka • Dla każdego e zwróconego przez q1, ENVS jest podwyższany o nested(e) • Następnie ewaluowane jest q2 • Po ewaluacji q2 stos ENVS wraca do poprzedniego stanu • Ostateczny wynik jest prawda wtedy i tylko wtedy, jeżeli dla wszystkich e podzapytanie q2 zwróciło prawda. Jeżeli q1zwróciło pusty wielozbiór, to wynik także jest prawda. • Objaśnienie funkcji eval • Funkcja połącz: ignoruje e; zwraca wynik podzapytania q2. • Funkcja sumuj: Zwraca fałsz jeżeli co najmniej jeden wynik pośredni zwrócony przez q2 jest fałsz ; w przeciwnym wypadku zwraca prawda. • Przykład: Prac ( Zar > 1000 )

  18. Kwantyfikator uniwersalny - ilustracja działania 1000 i3 2500 i7 2000 1000 i11 900 1000 Nazwisko(i6) Zar(i7) PracujeW(i8) Nazwisko(i2) Zar(i3) PracujeW(i4) Nazwisko(i10) Zar(i11) Adres(i12) PracujeW(i16) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Rezultat zwracany przez zapytanie Prac (wiązanie Prac) Iteracja po elementach e poprzedniego rezultatu: na ENVS wkłada się nested(e) Rezultat zwracany przez zapytanie Zar (wiązanie Zar) Rezultat dereferencji wymuszanej przez operator > Rezultat zwracany przez zapytanie 1000 Rezultat zwracany przez zapytanie Zar>1000 Końcowy rezultat zapytania i1 i5 i9 prawda fałsz prawda Stan stosu ENVS przed ewaluacją fałsz Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac ( Zar > 1000 )

  19. Kroki ewaluacji zapytania z pomocniczą nazwą 1000 prawda i3 i1 2500 x(i1) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Nazwisko(i2) Zar(i3) PracujeW(i4) x(i1) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) prawda i7 i5 2000 1000 x(i5 ) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Nazwisko(i6) Zar(i7) PracujeW(i8) x(i5 ) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) i11 i9 900 1000 fałsz Nazwisko(i10) Zar(i11) Adres(i12) PracujeW(i16) x(i9) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) x(i9) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Rezultat zwracany przez zapytanie Prac Rezultat zwracany przez zapytanie Prac as x Iteracja po elementach e poprzedniego rezultatu: na ENVS wkłada się nested(e) Rezultat zwracany przez zapytanie x (wiązanie x) Iteracja po elementach e poprzedniego rezultatu: na ENVS wkłada się nested(e) Rezultat zwracany przez zapytanie Zar Rezultat dereferencji wymuszanej przez operator > Rezultat zwracany przez zapytanie 1000 Rezultat zwracany przez zapytanie Zar>1000 Końcowy rezultat zapytania i1 i5 i9 x(i1) x(i5 ) x(i9) x(i1) x(i5 ) (Prac as x) where ( ( x . Zar ) > 1000 )

  20. Zamiana "zmiennej" na etykietę struktury • Dla zapytania (Pracasx) where (( x.Zar ) > 1000 ) końcowy wynik jest różny od wyniku zapytania PracwhereZar > 1000 , mianowicie, elementy wyniku są opatrzone nazwą x. • Elementy takie można uważać za proste struktury (w sensie języków C/C++), których jedynym polem jest pole o nazwie x. • W standardzie ODMG są "tajemnicze" miejsca, w których zmienna dziedzinowa zmienia się w etykietę struktury. Standard tego nie wyjaśnia. • Dopiero na gruncie SBA widać jasno, dlaczego tak się dzieje. Wymagało to jednak bardzo istotnych założeń odnośnie semantyki. Standard ODMG jest semantycznie nieprecyzyjny, więc nie jest w stanie tego wyjaśnić. • Tego efektu nie można także wyjaśnić na gruncie „algebry obiektowej”, „dziedzinowego rachunku obiektowego”, lub innego tradycyjnego formalizmu. • Można pokazać, że zapytanie PracwhereZar > 1000 jest równoważne zapytaniu ((Pracasx) where (( x.Zar ) > 1000 )) .x

  21. SBQL - schematy BD dla przykładów zapytań Adres NrP Miasto Ulica NrDomu Prac NrP Nazwisko Stan Zar PracujeW Dział NrD Nazwa Szef Lokacje NrD Lokacja Adres [0..1] Miasto Ulica NrDomu Schemat relacyjny Strzałki modelują asocjacje; prowadzą od klucza obcego do głównego Schemat obiektowy (diagram klas) Prac[0..*] NrP Nazwisko Stan Zar Zatrudnia[1..*] PracujeW Dział [0..*] NrD Nazwa Lokacja[1..*] Kieruje[0..1] Szef Asocjacje są zrealizowane jako (bliźniacze) obiekty pointerowe

  22. SBQL - przykłady zapytań (1) Podaj pełną informację o pracownikach: Prac Jest to odpowiednik zapytania SQL: select * fromPrac. Wbrew popularnym opiniom, lukier select ... from ... będziemy uważać za szkodliwy. Różnice semantyczne: zapytanie SQL zwraca tabelęPrac, podczas gdy Prac zwraca referencje do obiektów Prac. Zapytania SBQL nigdy nie zwracają obiektów. Podaj nazwiska wszystkich pracowników: Prac .Nazwisko Zapytanie jest odpowiednikiem zapytania SQL: selectNazwisko fromPrac. Zapytanie SQL zwraca jedno-kolumnową tablicę stringów będących nazwiskami, natomiast zapytanie SBQL zwraca tablicę referencji do pod-obiektów Nazwisko w obiektach Prac. Do tej tablicy można oczywiście zastosować operator dereferencji, który referencje na stringi, ale automatyczna dereferencja prowadzi do straty informacji. Referencje są bardziej uniwersalne niż stringi, gdyż. np. mogą być użyte po lewej stronie operacji podstawienia.

  23. SBQL - przykłady zapytań (2) Podaj pełną informację o Kowalskim: Pracwhere (Nazwisko = ”Kowalski”) SQL: select * fromPrac where Nazwisko = ‘Kowalski’. W odróżnieniu od SQL, zapytanie w SBQL zwróci referencję do obiektu Kowalskiego. Referencję tę można następnie „skonsumować” zdaniem imperatywnym; np. można usunąć obiekt Kowalskiego zdaniem delete Pracwhere (Nazwisko = ”Kowalski”); W dalszych przykładach będziemy często rezygnować z nawiasów. Podaj zarobek Kowalskiego: (Pracwhere Nazwisko = ”Kowalski”) . Zar SQL: selectZar fromPracwhereNazwisko = ‘Kowalski’. W odróżnieniu od SQL, zapytanie w SBQL zwróci referencję do zarobku Kowalskiego. Referencję tę można następnie „skonsumować” zdaniem imperatywnym; np. można zmienić zarobek Kowalskiego zdaniem: ((Pracwhere Nazwisko = ”Kowalski”) . Zar) := 5000; Odpowiada to zdaniu aktualizacyjnemu SQL: updatePracsetZar = 5000 where Nazwisko = ‘Kowalski’;

  24. SBQL - przykłady zapytań (3) Podaj numery i nazwiska pracowników zarabiających więcej niż 1000. (Pracwhere Zar > 1000) . (NrP, Nazwisko) Wynikiem zapytania jest wielozbiór struktur struct{iNrP, iNazwisko}, gdzie w każdej strukturze pierwsza referencja dotyczy atrybutu NrP, zaś druga - atrybutu Nazwisko. Przecinek oznacza operator algebraiczny konstruktora struktury. Zwróć referencję do danej pointerowej PracujeW dla pracownika Kowalskiego: (Pracwhere Nazwisko = ”Kowalski”) . PracujeW Zapytanie nie ma odpowiednika w SQL i OQL. Zapytanie takie ma jednak sens, gdyż może być podzapytaniem szerszego zapytania. Ma również sens z powodu operacji aktualizacyjnych. Przykładowo, jeżeli chcielibyśmy przenieść Kowalskiego do działu Sprzedaż, wówczas takie zdanie może mieć postać: (Pracwhere Nazwisko=”Kowalski”).PracujeW := &(DziałwhereNazwa=”Sprzedaż”) Z lewej strony podstawienia obliczana jest l-wartość (l-value), czyli referencja do danej pointerowej PracujeW w obiekcie Kowalskiego. Z prawej strony podstawienia mamy r-wartość (r-value), która jest referencją do działu Sprzedaż.

  25. SBQL - przykłady zapytań (4) Podaj pełne dane o dziale, w którym pracuje Kowalski: ((Pracwhere Nazwisko = ”Kowalski”) . PracujeW ) . Dział Zapytanie to zwraca referencję do obiektu działu, w którym pracuje Kowalski. OQL: selectdfromPracasp, p.PracujeWasdwherep.Nazwisko = ”Kowalski” OQL unika nazwy Dział. Jest to niewłaściwe z dwóch powodów. (1) Jak pokazuje poprzedni przykład, istnieje potrzeba rozróżnienia pomiędzy referencją do pointera prowadzącego do obiektu, a referencją do samego obiektu. (2) Zapytanie w SBQL jest bardziej czytelne, gdyż explicite używa nazwy Dział, oznaczającej końcowy efekt ewaluacji. Podaj nazwę działu, w którym pracuje Kowalski: (Pracwhere Nazwisko = ”Kowalski”) . PracujeW . Dział . Nazwa Zapytanie to zwraca referencję do nazwy działu, w którym pracuje Kowalski. OQL: selectp.PracujeW.NazwafromPracaspwherep.Nazwisko = ”Kowalski” Przykład ilustruje tzw. wyrażenia ścieżkowe (path expressions), czyli nawigację wzdłuż ścieżki wyznaczonej powiązaniami pointerowymi lub w dół hierarchii obiektów. W SBQL takie wyrażenia są efektem definicji kropki - wyrażenie czytamy jako (((Pracwhere Nazwisko = ”Kowalski”) . PracujeW) . Dział) . Nazwa

  26. SBQL - przykłady zapytań (5) Wyrażenia ścieżkowe mogą być dowolnie długie. Np. nazwisko szefa Kowalskiego: (Pracwhere Nazwisko = ”Kowalski”) . PracujeW . Dział. Szef . Prac . Nazwisko Nie definiujemy specjalnych wyrażeń ścieżkowych, lecz wykorzystujemy operator kropki. Uzyskujemy przez to możliwość dowolnego kombinowania wyrażeń ścieżkowych z innymi operatorami. Przykładowo, poniższe wyrażenie SBQL (Pracwhere ”budynek D”  (PracujeW.Dział.Lokacja)).(Nazwisko, (Adres.Miasto)) specyfikuje nazwisko i miasto pracownika pracującego w budynku D. ODMG OQL ogranicza możliwość używania wygodnych wyrażeń ścieżkowych poprzez niezbyt mądry w tym kontekście lukier select...from...where... oraz poprzez przyjęcie (również niezbyt mądrego) założenia, że operator kropki może się pojawić tylko wtedy, jeżeli wyrażenie przed kropką zwraca dokładnie jedną wartość. Obydwa te założenia są odrzucone przy definiowaniu operatorów niealgebraicznych.

  27. SBQL - przykłady zapytań (6) Podaj wszystkie informacje o pracownikach zarabiających więcej od Kowalskiego: Pracwhere Zar > ((Pracwhere Nazwisko = ”Kowalski”).Zar) SQL: select * fromPracwhereZar > selectZarfromPracwhereNazwisko = ”Kowalski” W zapytaniu tym występuje dwa razy nazwa Zar, ale dzięki stosowej semantyce każde z tych wystąpień jest inaczej wiązane: pierwsze Zar jest wiązane na stosie posiadającym 2 sekcje, drugie Zar na stosie posiadającym 3 sekcje. Dla każdego pracownika zwróć pełną informację o pracowniku i jego dziale. Pracjoin (PracujeW.Dział) Skorzystaliśmy z operatora zależnego złączenia. Wynikiem jest wielozbiór struktur struct{ iPrac, iDział }, gdzie pierwszy składnik każdej struktury jest referencją do obiektu pracownika, zaś drugi jest referencją do obiektu jego działu. Zapytanie to ma odpowiednik w OQL: selectstruct(pr: p, dz: d) fromPracasp, p.PracujeW as d Nie jest to dokładny odpowiednik, ponieważ w OQL struktury muszą mieć etykiety (tutaj pr i dz), a ponadto OQL nie wprowadza referencji.

  28. SBQL - przykłady zapytań (7) Dla każdego pracownika zwróć pełną informację o pracowniku i jego dziale. Analogiczne zapytanie odnoszące się do struktury relacyjnej ma postać: Pracjoin (DziałwherePracujeW = NrD) lub (z użyciem produktu kartezjańskiego) (PracDział ) wherePracujeW = NrD To ostatnie zapytanie ma odpowiednik w SQL: select * fromPrac, DziałwherePracujeW = NrD Nie jest to dokładny odpowiednik, ponieważ wynikiem nie jest wielozbiór z parami referencji (jak w przypadku SBQL), lecz zbiorcza tabela zawierająca zarówno atrybuty tabeli Prac jak i tabeli Dział.

  29. SBQL - przykłady zapytań (8) Podaj informację o działach i średnich zarobkach pracowników w działach: Działjoinavg(Zatrudnia.Prac.Zar) Wynikiem zapytania jest wielozbiór struktur struct{ iDział, średni_zar }, gdzie pierwszy składnik każdej struktury jest referencją do obiektu Dział, zaś drugi jest liczbą będącą średnią zarobków w tym dziale. Następny slajd przedstawia stany stosu środowisk przy wiązaniu poszczególnych nazw występujących w tym zapytaniu. W OQL zapytanie to wymaga użycia opcji group by, która została wyspecyfikowana nieprecyzyjnie, toteż nie ma pewności jak jej użyć. Podobne zapytanie można sformułować przy pomocy następującego zdania SQL: selectd.*, avg(p.Zar) fromDziałd, Pracpwhered.NrD = p.PracujeW group byd.NrD Wadą jest konieczność użycia operatora group by, który jest nieortogonalny, prowadzi do nowego jakościowo warunku (having), ma rafy semantyczne, oraz sprawia trudności z optymalizacją zapytań. W SBQL unikamy tego wątpliwego operatora, również dla struktur relacyjnych: Działjoinavg((PracwherePracujeW = NrD ).Zar)

  30. SBQL - przykłady zapytań (9) NrP (..) Nazwisko(..) Stan(..) Zar(..) Adres(..) PracujeW(..) Kieruje(..) Nrd(..), Nazwa(..) Lokacja(..) Lokacja(..) ... Zatrudnia(..) Zatrudnia(..) ... Szef(..) Prac(..) Prac(..), ... Dział(..) Dział(..) ... Nrd(..), Nazwa(..) Lokacja(..) Lokacja(..) ... Zatrudnia(..) Zatrudnia(..) ... Szef(..) Prac(..) Prac(..), ... Dział(..) Dział(..) ... Prac(..) Prac(..), ... Dział(..) Dział(..) ... Prac(..) Prac(..), ... Dział(..) Dział(..) ... Stany stosu środowisk przy wiązaniu nazw występujących w zapytaniu Działjoinavg(Zatrudnia.Prac.Zar) ( Dział join avg(( Zatrudnia . Prac ) . Zar ) ) Prac(..) Nrd(..), Nazwa(..) Lokacja(..) Lokacja(..) ... Zatrudnia(..) Zatrudnia(..) ... Szef(..) Prac(..) Prac(..), ... Dział(..) Dział(..) ... Nrd(..), Nazwa(..) Lokacja(..) Lokacja(..) ... Zatrudnia(..) Zatrudnia(..) ... Szef(..) Prac(..) Prac(..), ... Dział(..) Dział(..) ... Nrd(..), Nazwa(..) Lokacja(..) Lokacja(..) ... Zatrudnia(..) Zatrudnia(..) ... Szef(..) Prac(..) Prac(..), ... Dział(..) Dział(..) ...

  31. SBQL - przykłady zapytań (10) Podaj średnią liczbę pracowników w działach. Dla schematu obiektowego: avg( Dział . count(Zatrudnia)) Dla schematu relacyjnego: avg( Dział . count(PracwhereNrD = PracujeW)) Analogiczne zdanie w standardzie SQL-89 nie istnieje; zapytanie można wyrazić z pomocą dodatkowej perspektywy. W standardzie SQL-92 zdanie to można sformułować przy pomocy opcji group by. Opcja ta prowadzi do znanej rafy semantycznej, polegającej na tym, że jeżeli pewien dział nie będzie miał ani jednego pracownika, wówczas nie zostanie uwzględniony przy obliczaniu średniej. W SBQL ta rafa nie występuje.

  32. SBQL - przykłady zapytań (11) Dla pracowników zarabiających więcej niż 2000 i pracujących w budynku A podaj nazwisko, stanowisko, nazwę działu i nazwisko szefa działu. ((Prac where Zar > 2000) join (PracujeW. (Dział where "budynek A"  Lokacja ))) . (Nazwisko, Stan, Nazwa, (Szef.Prac.Nazwisko)) Wynikiem będzie kolekcja struktur struct{iNazwisko1, iStan, iNazwa, iNazwisko2 }, gdzie każda struktura zawiera cztery referencje. Czy w każdym dziale jest pracownik zarabiający więcej od swojego szefa? Dział ( Zatrudnia.Prac ( Zar > Szef.Prac.Zar)) Wynikiem zapytania jest wartość boolowska prawda lub fałsz. Kwantyfikatory są operatorami niealgebraicznymi, wobec czego (jak w całym SBQL), użycie nazw pomocniczych (czyli „zmiennych związanych kwantyfikatorami”) nie jest konieczne. Jeżeli zachodziłaby potrzeba, wówczas takie „zmienne” można byłoby powołać w postaci pomocniczych nazw: Działasx ( x.Zatrudnia.Pracasy ( y.Zar > x.Szef.Prac.Zar)) Zmuszanie użytkowników do obowiązku stosowania pomocniczych nazw, jak w OQL, jest konsekwencją pseudo-matematycznych koncepcji semantyki.

  33. SBQL - przykłady zapytań (12) Podaj pracowników którzy na pewno mieszkają w Olsztynie. Zgodnie ze schematem, adres pracownika jest daną opcyjną i złożoną. W terminologii modelu relacyjnego, brak adresu dla pracownika oznacza, ze w tym miejscu jest zapisana wartość zerowa (null). Wartości te wymagają w SQL specjalnych opcji, które są niespójne oraz komplikują semantykę i pragmatykę języka. W naszym podejściu będziemy ich unikać. Zamiast operacji na wartościach zerowych można zastosować kwantyfikatory. PracwhereAdres (Miasto = ”Olsztyn”) Podaj pracowników którzy albo na pewno mieszkają w Olsztynie albo być może mieszkają w Olsztynie, ponieważ ich adres jest nieznany: PracwhereAdres (Miasto = ”Olsztyn”) Pamiętać: kwantyfikator  działający na pustym zbiorze zwraca true.

  34. SBQL - przykłady zapytań (13) Podaj nazwiska i zarobki projektantów zarabiających więcej od swoich szefów: Zilustrujemy kilka stylów tworzenia zapytań, które są konsekwencją przyjętych przez nas definicji: Styl SQL (schemat relacyjny): (((Pracasx)  (Działasy)  (Pracasz)) wherex.Stan = ”projektant” andx.PracujeW = y.NrDandy.Szef = z.NrPandx.Zar > z.Zar) . (x.Nazwisko, x.Zar) Styl OQL (schemat obiektowy): ((Pracasx) join (x.PracujeW.Działasy) joined with (y.Szef.Pracasz) wherex.Stan = ”projektant” andx.Zar > z.Zar) . (x.Nazwisko, x.Zar) Wariant minimalny SBQL (schemat obiektowy ): (PracwhereStan = ”projektant” andZar > (PracujeW.Dział.Szef.Prac.Zar)) . (Nazwisko,Zar) Styl „rachunku dziedzinowego” zapisanego w SBQL (schemat relacyjny): (((Prac.(Nazwisko as np, Zar as zp, Stanas sp, PracujeW as dp))  (Dział.( Nrdasnd, Szefassd))  (Prac.(Zaraszs, NrP as ns))) wheresp = ”projektant” anddp = nd andsd = nsandzp > zs) . (np, zp)

  35. SBQL - podsumowanie przykładów • Poprzez przykłady, szczególnie z poprzedniego slajdu, pokazujemy, że debaty o „wyższości formalizmu A nad formalizmem B” oraz obecne spory o języki zapytań można pogodzić na gruncie podejścia stosowego. • Istotne jest, jakie struktury danych dopuszczamy w systemie zarządzania bazą danych. Z chwilą precyzyjnej definicji tych struktur dla dowolnych z nich można zbudować język zapytań na gruncie podejścia stosowego. • Teza M.Stonebrakera o tym, że dla modeli obiektowych nie można zbudować języka zapytań, jest nonsensem; próbą zbudowania fałszywego stereotypu. Struktury relacyjne nie mają w tym względzie jakiejkolwiek przewagi nad strukturami obiektowymi, i odwrotnie. • Gorąca debata ideologów świata komercyjnego odnośnie tego, który paradygmat struktur danych i języków zapytań jest lepszy, na gruncie SBA staje się jałową demagogiczną retoryką, pustosłowiem pozbawionym merytorycznych argumentów. Szczególnie wtedy, gdy powołuje się na „mocne podstawy matematyczne".

More Related