Obiektowe języki zapytań 1..5

Download Report

Transcript Obiektowe języki zapytań 1..5

Obiektowe języki zapytań
Wykładowca: Kazimierz Subieta
Polsko-Japońska Wyższa Szkoła
Technik Komputerowych, Warszawa
[email protected]
Instytut Podstaw Informatyki PAN,
Warszawa
[email protected]
© K.Subieta. Obiektowe języki zapytań 09, Folia 1
Wykład 09:
Język SBQL (Stack-Based
Query Language) (2)
Operatory niealgebraiczne,
przykłady zapytań w SBQL
maj 2004
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.
© K.Subieta. Obiektowe języki zapytań 09, Folia 2
maj 2004
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.
© K.Subieta. Obiektowe języki zapytań 09, Folia 3
maj 2004
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).
© K.Subieta. Obiektowe języki zapytań 09, Folia 4
maj 2004
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.
© K.Subieta. Obiektowe języki zapytań 09, Folia 5
maj 2004
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.
© K.Subieta. Obiektowe języki zapytań 09, Folia 6
maj 2004
Formalny zapis procedury eval dla oper. niealgebr.
procedure eval( q : zapytanie )
begin
......
case q jest rozpoznane jako q1  q2 : (* q1 , q2 są zapytaniami,  jest operatorem niealgebraicznym *)
begin
wyniki_pośr: bag of Rezultat;
(* 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 q1 na czubku stosu QRES *)
for each e in 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;
© K.Subieta. Obiektowe języki zapytań 09, Folia 7
maj 2004
Poglądowy obraz małej bazy danych
i1
Prac
i2 Nazwisko ”Nowak”
i3 Zar 2500
i4 PracujeW
i5
Prac
i9
i6 Nazwisko ”Kowalski”
Prac
i10 Nazwisko ”Barski”
i7 Zar 2000
i11 Zar 900
i12 Adres
i8 PracujeW
i13 Miasto ”Radom”
i14 Ulica ”Wolska”
i15 NrDomu 12
i16 PracujeW
i17
Dział
i22
Dział
i18 Nazwa ”Produkcja”
i23 Nazwa ”Sprzedaż”
i19 Lokacja ”Kielce”
i24 Lokacja ”Radom”
i20 Lokacja ”Kraków”
i25 Zatrudnia
i21 Zatrudnia
i26 Zatrudnia
© K.Subieta. Obiektowe języki zapytań 09, Folia 8
maj 2004
Operator where (selekcja)
 Składnia: q1 where q2
• 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 q1 zwraca
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: Prac where ( Zar > 1000 )
© K.Subieta. Obiektowe języki zapytań 09, Folia 9
maj 2004
Operator where - ilustracja działania
Rezultat
zwracany przez
zapytanie Prac
(wiązanie Prac)
Iteracja po
elementach e
poprzedniego
rezultatu: na ENVS
wkłada się nested(e)
i1
i5
Stan stosu ENVS
przed ewaluacją
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
i9
Prac
© K.Subieta. Obiektowe języki zapytań 09, Folia 10
Rezultat
zwracany
przez
zapytanie Zar
(wiązanie Zar)
Nazwisko(i2) Zar(i3)
PracujeW(i4)
Rezultat Końcowy
zwracany rezultat
przez
zapytania
zapytanie
Zar>1000
Rezultat
dereferencji
wymuszanej
przez
operator >
Rezultat
zwracany
przez
zapytanie
1000
i3
2500
1000
prawda
i1
i7
2000
1000
prawda
i5
i11
900
1000
fałsz
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
Nazwisko(i6) Zar(i7)
PracujeW(i8)
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
Nazwisko(i10) Zar(i11)
Adres(i12) PracujeW(i16)
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
where
(
Zar
> 1000 )
maj 2004
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.
© K.Subieta. Obiektowe języki zapytań 09, Folia 11
maj 2004
Operator kropki - ilustracja działania
Rezultat
zwracany przez
zapytanie Prac
(wiązanie Prac)
i1
Iteracja po
elementach e
poprzedniego
rezultatu: na ENVS
wkłada się nested(e)
Nazwisko(i2) Zar(i3)
PracujeW(i4)
Rezultat
zwracany
przez
zapytanie Zar
(wiązanie Zar)
Końcowy
rezultat
zapytania
i3
i3
i7
i7
i11
i11
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
i5
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
Stan stosu ENVS
przed ewaluacją
i9
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
Nazwisko(i10) Zar(i11)
Adres(i12) PracujeW(i16)
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
Prac
© K.Subieta. Obiektowe języki zapytań 09, Folia 12
Nazwisko(i6) Zar(i7)
PracujeW(i8)
.
Zar
maj 2004
Operator zależnego złączenia
 Składnia: q1 join q2
 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 join Zar
• Zależne złączenie jest zdefiniowane w ODMG OQL (klauzula from) w znacznie
ograniczonej postaci w stosunku do powyższej definicji.
© K.Subieta. Obiektowe języki zapytań 09, Folia 13
maj 2004
Operator zależnego złączenia - ilustracja działania
Rezultat
zwracany przez
zapytanie Prac
(wiązanie Prac)
i1
Iteracja po
elementach e
poprzedniego
rezultatu: na ENVS
wkłada się nested(e)
Nazwisko(i2) Zar(i3)
PracujeW(i4)
Rezultat
zwracany
przez
zapytanie Zar
(wiązanie Zar)
Końcowy
rezultat
zapytania
i3
struct(i1, i3)
i7
struct(i5, i7)
i11
struct(i9, i11 )
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
i5
Nazwisko(i6) Zar(i7)
PracujeW(i8)
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
Stan stosu ENVS
przed ewaluacją
i9
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
Nazwisko(i10) Zar(i11)
Adres(i12) PracujeW(i16)
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
Prac
© K.Subieta. Obiektowe języki zapytań 09, Folia 14
join
Zar
maj 2004
Operator sortowania
 Składnia: q1 order by q2
 Semantyka
• Wykonywane jest zapytanie: q1 join dereferencja( 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. Prac order by Nazwisko
Prac order 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. Prac order 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,.. ).
© K.Subieta. Obiektowe języki zapytań 09, Folia 15
maj 2004
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 )
© K.Subieta. Obiektowe języki zapytań 09, Folia 16
maj 2004
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 q1 zwró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 )
© K.Subieta. Obiektowe języki zapytań 09, Folia 17
maj 2004
Kwantyfikator uniwersalny - ilustracja działania
Rezultat
zwracany przez
zapytanie Prac
(wiązanie Prac)
Iteracja po
elementach e
poprzedniego
rezultatu: na ENVS
wkłada się nested(e)
i1
i5
Stan stosu ENVS
przed ewaluacją
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
i9
Prac
© K.Subieta. Obiektowe języki zapytań 09, Folia 18
Rezultat
zwracany
przez
zapytanie Zar
(wiązanie Zar)
Nazwisko(i2) Zar(i3)
PracujeW(i4)
Rezultat
dereferencji
wymuszanej
przez
operator >
Rezultat
zwracany
przez
zapytanie
1000
Rezultat
zwracany
przez
zapytanie
Zar>1000
i3
2500
1000
prawda
i7
2000
1000
prawda
i11
900
1000
fałsz
Końcowy
rezultat
zapytania
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
Nazwisko(i6) Zar(i7)
PracujeW(i8)
fałsz
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
Nazwisko(i10) Zar(i11)
Adres(i12) PracujeW(i16)
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)

(
Zar
> 1000 )
maj 2004
Kroki ewaluacji zapytania z pomocniczą nazwą
Rezultat
zwracany
przez
zapytanie
Prac
i1
i5
i9
(Prac
Rezultat
zwracany
przez
zapytanie
Prac as x
x(i1)
x(i5 )
x(i9)
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
Końcowy
rezultat
zapytania
Rezultat
zwracany
przez
zapytanie
Zar>1000
Nazwisko(i2) Zar(i3)
PracujeW(i4)
x(i1)
i3
2500
1000
prawda
x(i1)
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
Prac(i1) Prac(i5) Prac(i9) Dział(i17)
Dział(i22)
x(i5 )
i5
Nazwisko(i6) Zar(i7)
PracujeW(i8)
x(i5 )
2000
1000
prawda
x(i5 )
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
Prac(i1) Prac(i5) Prac(i9) Dział(i17)
Dział(i22)
i7
x(i9)
i9
Nazwisko(i10) Zar(i11)
Adres(i12) PracujeW(i16)
x(i9)
i11
900
1000
fałsz
i1
x(i1)
Prac(i1) Prac(i5) Prac(i9)
Dział(i17) Dział(i22)
where
( ( x
© K.Subieta. Obiektowe języki zapytań 09, Folia 19
Prac(i1) Prac(i5) Prac(i9) Dział(i17)
Dział(i22)
.
Zar )
> 1000 )
maj 2004
Zamiana "zmiennej" na etykietę struktury
 Dla zapytania (Prac as x) where (( x . Zar ) > 1000 ) końcowy wynik
jest różny od wyniku zapytania Prac where Zar > 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 Prac where Zar > 1000 jest równoważne
zapytaniu ((Prac as x) where (( x . Zar ) > 1000 )) . x
© K.Subieta. Obiektowe języki zapytań 09, Folia 20
maj 2004
SBQL - schematy BD dla przykładów zapytań
Schemat relacyjny
Adres
NrP
Miasto
Ulica
NrDomu
Dział
NrD
Nazwa
Szef
Prac
NrP
Nazwisko
Stan
Zar
PracujeW
Lokacje
NrD
Lokacja
Strzałki modelują asocjacje;
prowadzą od klucza obcego
do głównego
Schemat obiektowy (diagram klas)
Prac[0..*]
NrP
Nazwisko
Stan
Zar
Adres [0..1]
Miasto
Ulica
NrDomu
© K.Subieta. Obiektowe języki zapytań 09, Folia 21
PracujeW
Kieruje[0..1]
Zatrudnia[1..*]
Szef
Dział [0..*]
NrD
Nazwa
Lokacja[1..*]
Asocjacje są zrealizowane jako
(bliźniacze) obiekty pointerowe
maj 2004
SBQL - przykłady zapytań (1)
Podaj pełną informację o pracownikach:
Prac
Jest to odpowiednik zapytania SQL: select * from Prac. 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: select Nazwisko from Prac.
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.
© K.Subieta. Obiektowe języki zapytań 09, Folia 22
maj 2004
SBQL - przykłady zapytań (2)
Podaj pełną informację o Kowalskim:
Prac where (Nazwisko = ”Kowalski”)
SQL: select * from Prac 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 Prac where (Nazwisko = ”Kowalski”);
W dalszych przykładach będziemy często rezygnować z nawiasów.
Podaj zarobek Kowalskiego:
(Prac where Nazwisko = ”Kowalski”) . Zar
SQL: select Zar from Prac where Nazwisko = ‘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: ((Prac where Nazwisko = ”Kowalski”) . Zar) := 5000;
Odpowiada to zdaniu aktualizacyjnemu SQL:
update Prac set Zar = 5000 where Nazwisko = ‘Kowalski’;
© K.Subieta. Obiektowe języki zapytań 09, Folia 23
maj 2004
SBQL - przykłady zapytań (3)
Podaj numery i nazwiska pracowników zarabiających więcej niż 1000.
(Prac where 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:
(Prac where 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ć:
(Prac where Nazwisko=”Kowalski”).PracujeW :=
&(Dział where Nazwa=”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ż.
© K.Subieta. Obiektowe języki zapytań 09, Folia 24
maj 2004
SBQL - przykłady zapytań (4)
Podaj pełne dane o dziale, w którym pracuje Kowalski:
((Prac where Nazwisko = ”Kowalski”) . PracujeW ) . Dział
Zapytanie to zwraca referencję do obiektu działu, w którym pracuje Kowalski.
OQL: select d from Prac as p, p.PracujeW as d where p.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:
(Prac where Nazwisko = ”Kowalski”) . PracujeW . Dział . Nazwa
Zapytanie to zwraca referencję do nazwy działu, w którym pracuje Kowalski.
OQL: select p.PracujeW.Nazwa from Prac as p where p.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 (((Prac where Nazwisko = ”Kowalski”) . PracujeW) . Dział) . Nazwa
© K.Subieta. Obiektowe języki zapytań 09, Folia 25
maj 2004
SBQL - przykłady zapytań (5)
Wyrażenia ścieżkowe mogą być dowolnie długie. Np. nazwisko szefa Kowalskiego:
(Prac where 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
(Prac where ”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.
© K.Subieta. Obiektowe języki zapytań 09, Folia 26
maj 2004
SBQL - przykłady zapytań (6)
Podaj wszystkie informacje o pracownikach zarabiających więcej od Kowalskiego:
Prac where Zar > ((Prac where Nazwisko = ”Kowalski”).Zar)
SQL: select * from Prac where Zar > select Zar from Prac where Nazwisko = ”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.
Prac join (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:
select struct(pr: p, dz: d) from Prac as p, 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.
© K.Subieta. Obiektowe języki zapytań 09, Folia 27
maj 2004
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ć:
Prac join (Dział where PracujeW = NrD)
lub (z użyciem produktu kartezjańskiego)
(Prac  Dział ) where PracujeW = NrD
To ostatnie zapytanie ma odpowiednik w SQL:
select * from Prac, Dział where PracujeW = 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ł.
© K.Subieta. Obiektowe języki zapytań 09, Folia 28
maj 2004
SBQL - przykłady zapytań (8)
Podaj informację o działach i średnich zarobkach pracowników w działach:
Dział join avg(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:
select d.*, avg(p.Zar) from Dział d, Prac p where d.NrD = p.PracujeW group by d.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ł join avg((Prac where PracujeW = NrD ). Zar)
© K.Subieta. Obiektowe języki zapytań 09, Folia 29
maj 2004
SBQL - przykłady zapytań (9)
Stany stosu środowisk przy wiązaniu nazw występujących w zapytaniu
Dział join avg(Zatrudnia.Prac.Zar)
( Dział join avg(( Zatrudnia . Prac
Prac(..)
Prac(..), ...
Dział(..)
Dział(..) ...
Nrd(..),
Nazwa(..)
Lokacja(..)
Lokacja(..) ...
Zatrudnia(..)
Zatrudnia(..) ...
Szef(..)
Prac(..)
Prac(..), ...
Dział(..)
Dział(..) ...
Prac(..)
Nrd(..),
Nazwa(..)
Lokacja(..)
Lokacja(..) ...
Zatrudnia(..)
Zatrudnia(..) ...
Szef(..)
Prac(..)
Prac(..), ...
Dział(..)
Dział(..) ...
© K.Subieta. Obiektowe języki zapytań 09, Folia 30
)
Nrd(..),
Nazwa(..)
Lokacja(..)
Lokacja(..) ...
Zatrudnia(..)
Zatrudnia(..) ...
Szef(..)
Prac(..)
Prac(..), ...
Dział(..)
Dział(..) ...
.
Zar
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ł(..) ...
maj 2004
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(Prac where NrD = 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.
© K.Subieta. Obiektowe języki zapytań 09, Folia 31
maj 2004
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ł as x (  x.Zatrudnia.Prac as y ( 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.
© K.Subieta. Obiektowe języki zapytań 09, Folia 32
maj 2004
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.
Prac where  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:
Prac where  Adres (Miasto = ”Olsztyn”)
Pamiętać: kwantyfikator  działający na pustym zbiorze zwraca true.
© K.Subieta. Obiektowe języki zapytań 09, Folia 33
maj 2004
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):
(((Prac as x)  (Dział as y)  (Prac as z)) where x.Stan = ”projektant” and
x.PracujeW = y.NrD and y.Szef = z.NrP and x.Zar > z.Zar) . (x.Nazwisko, x.Zar)
Styl OQL (schemat obiektowy):
((Prac as x) join (x.PracujeW.Dział as y) joined with (y.Szef.Prac as z) where x.Stan
= ”projektant” and x.Zar > z.Zar) . (x.Nazwisko, x.Zar)
Wariant minimalny SBQL (schemat obiektowy ):
(Prac where Stan = ”projektant” and Zar > (PracujeW.Dział.Szef.Prac.Zar)) . (Nazwisko,Zar)
Styl „rachunku dziedzinowego” zapisanego w SBQL (schemat relacyjny):
(((Prac.(Nazwisko as np, Zar as zp, Stan as sp, PracujeW as dp)) 
(Dział.( Nrd as nd, Szef as sd))  (Prac.(Zar as zs, NrP as ns)))
where
sp = ”projektant” and dp = nd and sd = ns and zp > zs) . (np, zp)
© K.Subieta. Obiektowe języki zapytań 09, Folia 34
maj 2004
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".
© K.Subieta. Obiektowe języki zapytań 09, Folia 35
maj 2004