Języki i środowiska programowania systemów rozproszonych

20
Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 1 2011 Języki i środowiska programowania systemów rozproszonych Wykładowca: Tomasz Kowalski Wykłady przygotowane na podstawie materiałów prof. Kazimierza Subiety Wykład 8 Operator sortowania order by Operator group by – czy potrzebny?

description

Języki i środowiska programowania systemów rozproszonych. Wykład 8 Operator sortowania order by Operator group by – czy potrzebny?. Wykładowca : Tomasz Kowalski Wykłady przygotowane na podstawie materiałów prof. Kazimierza Subiety. Sortowanie w językach zapytań. - PowerPoint PPT Presentation

Transcript of Języki i środowiska programowania systemów rozproszonych

Page 1: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 1 2011

Języki i środowiska programowania systemów rozproszonych

Wykładowca: Tomasz Kowalski

Wykłady przygotowane na podstawie materiałówprof. Kazimierza Subiety

Wykład 8Operator sortowania order byOperator group by – czy potrzebny?

Page 2: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 2 2011

Sortowanie w językach zapytań

Operator sortowania order by występuje w SQL i jest proponowany w innych językach takich jak ODMG OQL.

Operator ten umożliwia posortowanie wyniku według wybranego klucza.

Sortowanie jest bardzo ważną operacją w językach zapytań z następujących powodów:• Wyprowadzanie wyników wyszukiwania: wynik powinien być

posortowany dla zwiększenia jego czytelności i umożliwienia podjęcia szybkiej decyzji. Np. kierownikowi działu może zależeć na posortowaniu wyniku wyszukiwania według malejących zarobków lub według rosnącego wieku.

• Sortowanie zwiększa moc języka zapytań. Niektóre zapytania nie mogą być zadane bez sortowania, np. zapytanie „podaj 50-ciu najlepiej zarabiających pracowników”. Zapytania takie są zwane „zakresowymi” (range queries).

Page 3: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 3 2011

Definicja operatora order by w SBQL (1)

Operator order by został zaimplementowany w SBQL systemu ODRA. • Niżej objaśnimy (nieco uogólnioną) ideę tego operatora.

• Operator ten będzie należał do kategorii nie-algebraicznych.

• Przyjmijmy następującą składnię (rozszerzającą podane wcześniej reguły składniowe SBQL):

Semantyka zapytania q1 orderby q2

• Przedmiotem sortowania jest bag lub sekwencja zwrócona przez q1.

• q2 wyznacza klucz sortowania.

• Wynikiem jest sekwencja elementów zwróconych przez q1, uporządkowana zgodnie z kluczem q2. Zapytanie q2 wyznacza strukturę (ogólnie: bag struktur) struct{v1, v2, ..., vk}, gdzie vi Di, zaś Di V.

• Zbiory Di są dziedzinami, w których istnieje naturalny porządek liniowy, np. zbiór liczb całkowitych, zbiór stringów, zbiór dat, itd.

zapytanie ::= zapytanie zapytanie ::= zapytanie orderbyorderby zapytanie zapytanie

Page 4: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 4 2011

Definicja operatora order by w SBQL (2)

Przetwarzanie zapytania q1 orderby q2 odbywa się w sposób następujący:

• Oblicza się zależne złączenie q1 join q2 . Jeżeli zapytanie q1 zwróci bag{ r1, r2, ... }, to w wyniku całego zapytania otrzymujemy bag o budowie

• Analogicznie jeżeli q1 zwróci sekwencję.

• Jeżeli któreś z vij jest referencją, to wykonuje się automatycznie dereferencję.

• Jeżeli wartość vij nie należy do dziedziny Di V, w której obowiązuje naturalny porządek liniowy, wówczas sytuacja ta jest uważana za błędną.

• Dokonuje się sortowania powstałego bagu, które zamienia go na sekwencję. Sortowanie następuje według pierwszego klucza, w ramach identycznych wartości pierwszego klucza – według drugiego klucza, itd.

• Po sortowaniu otrzymamy sekwencję:

powstałą z poprzedniego bagu poprzez jego posortowanie;

• Końcowy rezultat uzyskujemy po rzutowaniu powstałej sekwencji na rezultaty q1. Ostateczny rezultat: sequence{ s1, s2, ...}.

bag{struct{ r1, v11, v21, ..., vk1 }, struct{ r2, v12, v22, ..., vk2 }, ...}

sequence{ struct{ s1, vs11, vs21, ..., vsk1 }, struct{ s2, vs12, vs22, ..., vsk2 }, ...}

Page 5: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 5 2011

Przykłady (schemat bazy danych)

Osoba[0..*]NazwiskoRokUrWiek()

Prac[0..*]NrPStan[1..*]Zar[0..1]ZmieńZar(nowyZar)ZarNetto( )

Dział [0..*]NrDNazwaLokacja[1..*]BudżetRoczny()

Kieruje[0..1] Szef

PracujeW Zatrudnia[1..*]

Page 6: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 6 2011

Przykłady zapytań

Podaj referencje do obiektów wszystkich pracowników posortowane według ich nazwisk:

Prac orderby Nazwisko • Wynikiem będzie sequence{iPrac1, iPrac2, iPrac3...} identyfikatorów obiektów

Prac, posortowanych według nazwisk.

• Zwrócimy uwagę, że wykorzystaliśmy dziedziczenie.

Podaj identyfikatory wszystkich pracowników posortowane według ich wieku, zaś w ramach tego samego wieku – według nazwisk:

Prac orderby (Wiek(), Nazwisko) Podaj działy posortowane według liczby pracowników w działach oraz

według nazwisk ich szefów; zwróć nazwę działu oraz jego lokacje posortowane alfabetycznie.

(Dział orderby (count(Zatrudnia), (Szef.Prac.Nazwisko))) .

(Nazwa, (((Lokacja as x) orderby x).x) group as lokacje)

Page 7: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 7 2011

Puste i wielowartościowe klucze

Przedstawiona semantyka operatora orderby posiada kilka niuansów. Pierwszy z nich dotyczy sytuacji, kiedy w zapytaniu q1 orderby q2 podzapytanie q2 zwraca pusty wynik.

• Np. w obiektach Prac podobiekt Zar może nie wystąpić.

• Wówczas zgodnie z przedstawiona semantyką opartą na zależnym złączeniu zapytanie:

Prac orderby Zar

pominie tych pracowników, dla których Zar nie występuje.

Aby uwzględnić tych pracowników w dostarczonym wyniku, wówczas należy ustalić dla nich klucz sortowania, np. przyjmując, że dla pracowników nie posiadających informacji o zarobku klucz wynosi zero. • Odpowiednie zapytanie (jedno z wielu) może mieć postać:

Prac orderby max( bag(0, Zar) )

• Funkcja max zwróci 0 dla pracowników nie posiadających zarobku i aktualny zarobek dla pozostałych.

Page 8: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 8 2011

Klucze wielowartościowe

Podobna sytuacja następuje wtedy, gdy w zapytaniu q1 orderby q2 podzapytanie q2 zwraca wiele wartości.

• Np. zapytanie:

Prac orderby Stan

• Zgodnie z przedstawioną semantyką opartą na zależnym złączeniu, identyfikatory pracowników posiadających więcej niż jedno stanowisko będą w wyniku powielone tyle razy, ile dany pracownik ma stanowisk.

• Następnie te identyfikatory zostaną posortowane według poszczególnych stanowisk.

• Taka interpretacja jest logiczna i konsekwentna.

• Oczywiście, może on użyć innych środków aby, dla uniknięcia powtórzeń, ustalić takie q2, które zwróci dla pracownika dokładnie jedno stanowisko, np.:

Prac orderby ((((Stan as z) orderby z).z) [1])

• W tym przypadku programista uporządkował stanowiska pracownika alfabetycznie i wybrał pierwsze stanowisko jako klucz sortowania.

Page 9: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 9 2011

Sortowanie w kolejności rosnącej i malejącej

W SQL i OQL do tego celu służą specjalne słowa kluczowe ASC (ascending) i DESC (descending) umieszczone za danym kluczem sortowania (pierwsze z nich jest domyślne). • Obydwie opcje oznaczają funkcje działające na kluczach sortowania.

• ASC jest funkcją identyczności (zwraca swój argument).

• DESC jest funkcją zwracającą element będący dopełnieniem swojego argumentu zgodnym z określonym porządkiem liniowym.

• Przykładowo, dla liczby całkowitej X dopełnieniem jest –X, lub 1000000000 – X, gdzie jest 1000000000 jest (przykładowym) maksymalnym kluczem.

• Podobnie, dopełnieniem stringu może być string, w którym każdy znak w ASCII o kodzie k zostaje zastąpiony przez znak o kodzie 256 - k.

• Przykład: podaj identyfikatory wszystkich pracowników posortowane malejąco według wieku i rosnąco według ich nazwisk:

Prac orderby (DESC(Wiek), ASC(Nazwisko))

Page 10: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 10 2011

Zapytania zakresowe

Powinna istnieć możliwość wyboru i-tego elementu sekwencji, ostatniego elementu sekwencji, itd. W najprostszym przypadku można zastosować następującą składnię:

zapytanie ::= zapytanie [liczba naturalna]

zapytanie ::= zapytanie [liczba naturalna .. liczba naturalna] Podaj 50-ciu najmniej zarabiających pracowników:

(Prac orderby Zar)[1..50] • W powyższym zapytaniu pierwszy element otrzymuje numer 1.

• Język C i jego pochodne (C++, Java), CORBA, OQL, itd. wprowadzają numerację, w której pierwszy element oznacza się numerem 0. W C/C++ było to umotywowane, ale uzasadnienie dla tego atawizmu znikło.

• Bardziej ogólna forma:

zapytanie ::= zapytanie [zapytanie]

zapytanie ::= zapytanie [zapytanie .. zapytanie]

(Prac orderby Zar)[x..y]

Page 11: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 11 2011

Operator group by - czy potrzebny?

Operator group by występuje w SQL i jest proponowany w innych językach takich jak ODMG OQL. W językach relacyjnych okazał się on użyteczny do formułowania niektórych zapytań, szczególnie takich, które wymagały użycia funkcji agregowanych; np.• Mamy tabele Prac( NrP, Nazwisko, Stan, Zar, PracujeW)

Dział(NrD, Nazwa, Lokacja, Szef )

• Dla każdego działu podaj jego numer, liczbę pracowników oraz średnią zarobków:

SQL: select PracujeW, count(*), avg(Zar) from Prac group by PracujeW

• Semantyka tej konstrukcji jest prosta: tabelę pracowników dzieli się na grupy w których atrybut PracujeW przyjmuje tę samą wartość; następnie dla każdej takiej grupy oblicza się wyrażenie znajdujące się w klauzuli select.

Page 12: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 12 2011

Konsekwencje wprowadzenia operatora group by

Wraz z pojawieniem się operatora group by pojawiła się konieczność wprowadzenia możliwości selekcji niektórych grup wyodrębnionych przez ten operator.

Do tego celu służy specjalna klauzula having, która zawiera predykat operujący na grupach; tylko grupy, dla który ten predykat zwróci true, są uwzględniane przy obliczaniu klauzuli select. Np.:• Dla każdego działu zatrudniającego więcej niż 50 pracowników podaj jego

numer oraz średnią zarobków:

SQL: select PracujeW, avg(Zar) from Prac

group by PracujeW having count(*) > 50

Page 13: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 13 2011

Dalsze konsekwencje

Operator grupowania nie jest już tak oczywisty w przypadku złączeń, gdy w klauzuli from znajduje się więcej niż jedna nazwa tabeli. • Dorzucając do powyższego zapytania wymaganie, aby zwróciło ono także

nazwę działu, otrzymamy bardziej rozbudowaną formę:

• Dla każdego działu zatrudniającego więcej niż 50 pracowników podaj jego numer, nazwę oraz średnią zarobków:

SQL: select PracujeW, Nazwa, avg(Zar) from Prac, Dział

where PracujeW = NrD

group by PracujeW, Nazwa having count(*) > 50

SQL wymaga, aby dowolny atrybut występujący w klauzuli select i nie objęty funkcją agregowaną był wymieniony w klauzuli group by.

Istnieją dalsze niuanse syntaktyczne i semantyczne klauzuli group by oraz klauzul select i having, które są z nią związane.

Wbrew pozornej oczywistości, operator ten okazał się z pragmatycznego punktu widzenia dość trudny dla użytkowników i błędogenny.

Page 14: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 14 2011

Semantyczne rafy opcji group by

Wada koncepcyjna: jeżeli pewna grupa ma zero elementów, wówczas nie uczestniczy w przetwarzaniu, co prowadzi do błędnych wyników. • Przykładowo, programista chcący policzyć średnią liczbę pracowników w

działach użyje zdania:SQL: select PracujeW, count(*) from Prac group by PracujeW następnie przetworzy wynikową tabelę celem obliczenia średniej.

• Niestety, ta tabela nie zawiera informacji o działach z zerową liczbą pracowników, w związku z czym wynik będzie błędny; co więcej błąd ten pojawi się bez ostrzeżenia.

Inna wada: Opcja ta grupuje wartości NULL w ramach jednej grupy, co jest sprzeczne z założeniem twórców SQL, że wartości NULL oznaczają wartości nieznane (zatem być może różne) lub nierelewantne. • Np. jeżeli informacja PracujeW przyjęłaby wartość NULL dla niektórych

pracowników, to skutek powyższego zdania SQL byłby taki, jakby wszyscy oni pracowali w jednym dziale, zaś liczba grup byłaby o jeden większa od liczby działów.

• Średnia liczba pracowników byłaby oczywiście wyliczona błędnie.

Page 15: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 15 2011

Wyżej podane zapytania w SBQL

Dział . (NrD, count(Zatrudnia), avg(Zatrudnia.Prac.Zar))

(Dział where count(Zatrudnia) > 50). (NrD, avg(Zatrudnia.Prac.Zar))

(Dział where count(Zatrudnia) > 50).

(NrD, Nazwa, avg(Zatrudnia.Prac.Zar)) • Podane zapytania wyglądają naturalnie, zaś zasada koncepcyjnej kontynuacji

jest w pełni zachowana (porównaj dwa ostatnie zapytania).

• Nie występuje też wspomniana rafa semantyczna dotycząca pustych grup: jeżeli któryś dział nie będzie miał pracowników, to count(Zatrudnia) zwróci dla niego 0, co jest zgodne z oczekiwaniem programisty.

• Druga rafa semantyczna związana z wartościami zerowymi nie może wystąpić, ponieważ modele składu i SBQL w ogóle nie wprowadzają wartości zerowych.

• Ponieważ nie ma opcji group by, niepotrzebne są też dedykowane dla tej opcji metody optymalizacyjne.

• Niepotrzebne są też oczywiście specjalne warunki, które w opcji group by znajdują się w klauzuli having.

Page 16: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 16 2011

Recepta na zapytanie w SBQL, które w SQL wymagałoby group by

Ustalamy dyskryminator grup, tj. takie podzapytanie, którego wynik będzie podstawą podziału pewnych zasobów danych na grupy.

Nazywamy dyskryminator pewną nazwą d poprzez operator as. Dyskryminator wraz z nazwą d obejmujemy nawiasami i po operatorze

kropki formułujemy drugie podzapytanie, które dla danej wartości d ustala odpowiadającą jej grupę. Krok ten można pominąć.

Stosujemy dowolne operatory działających na d lub wyodrębnionych w poprzednim kroku grupach celem uzyskania ostatecznego wyniku.

Przykład: Dla każdego działu zatrudniającego programistów podaj jego numer, nazwę i średnią zarobków:

(((Dział where „programista” (Zatrudnia.Prac.Stan)) as d) .

(d.NrD, d.Nazwa, avg(d.Zatrudnia.Prac.Zar))

Page 17: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 17 2011

Przykłady wykorzystujące podaną receptę (1)

Dla każdego stanowiska podaj liczbę pracowników, którzy je posiadają oraz liczbę działów, w których ci pracownicy są zatrudnieni (atrybut Stan jest wielowartościowy):

(unique(Prac.Stan) as z) . (z, count(Prac where z Stan),

count(Dział where z (Zatrudnia.Prac.Stan))

• Pierwsza linia ustala wszystkie stanowiska, usuwa duplikaty i ten dyskryminator nazywa z. Druga i trzecia linia zawiera przetwarzanie tego z.

Recepta ta jest również dobra dla systemów relacyjnych. Np. zdanie

SQL: select PracujeW, avg(Zar) from Prac group by PracujeW having count(*) > 50

można zapisać jako:

SBQL: ((unique(Prac.PracujeW) as p) join ((Prac where PracujeW = p) group as g)

where count(g) > 50). (p, avg(g.Zar))

Page 18: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 18 2011

Przykłady wykorzystujące podaną receptę (2)

Dla grup wiekowych pracowników .., 15-19, 20-24, 25-29, .... podaj średni zarobek oraz różnicę pomiędzy maksymalnym i minimalnym zarobkiem; pomiń grupy wiekowe, w których nie ma żadnego pracownika:(unique(Prac.integerOf(Wiek/5)) as w) .((((5*w) as wiekDol, (5*w + 4) as wiekGor) join(Prac where Wiek wiekDol and Wiek wiekGor) group as g).(wiekDol, wiekGor, avg(g.Zar), max(g.Zar) – min(g.Zar))) • Pierwsza linia dzieli wiek pracowników przez 5, bierze od tego część

całkowitą, usuwa duplikaty i ten dyskryminator nazywa w (nie uwzględnia grup wiekowych, w których nie ma żadnego pracownika).

• Druga linia ustala dolny i górny wiek dla każdej grupy. • Trzecia linia ustala grupy referencji do obiektów pracowników znajdujących

się w tym przedziale wiekowym i każdą taką grupę nazywa g. • Złączenie czyni nazwy wiekDol, wiekGor oraz g widocznymi dla dalszej

części zapytania. Ostatnia linia dokonuje obliczeń wyniku.• Sformułowanie tego zapytania w SQL okazało się niezłą łamigłówką.

Page 19: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 19 2011

Związek pomiędzy group by i group as

Poprzedni przykład pokazuje użycie omówionego wcześniej operatora group as.

Pojawił się on jako skutek drobiazgowej analizy semantyki i pragmatyki przykładów na grupowanie.

Okazało się jednak, że w większości tego rodzaju przykładów:• nie jest on niezbędny,

• jest on niezbędny w innych kontekstach, np. wtedy, gdy chcemy wynik zapytania zbudować w postaci hierarchii nazwanych, zagnieżdżonych pod-wyników.

Z tego powodu operatory group as oraz group by nie mają ze sobą istotnego związku, mimo pewnych zależności genealogicznych.

Page 20: Języki i środowiska programowania systemów rozproszonych

Języki i środowiska programowania systemów rozproszonych, Wykład 08, Slajd 20 2011

Podsumowanie

Operator sortowania order by jest konieczny do wyprowadzania wyniku oraz do sformułowania niektórych zapytań, wobec czego powinien być zaimplementowany.• Jest to jedno z wymagań dla języków zapytań dla XML

Respektowanie porządku, w którym przetwarzane są kolekcje, zmniejsza potencjał dla optymalizacji zapytań.

Zatem sekwencje i operator porządkowania są z tego względu niekorzystne i powinno być stosowane tylko tam, gdzie jest niezbędne.

Operator group by w obiektowych językach zapytań jest tworem redundantnym.

Jeżeli przy tym przenosi wady z języka SQL, to powinien być również traktowany jako szkodliwy.

Implementacja tego operatora jest więc pozbawiona cienia sensu.