Języki i Środowiska Programowania Baz Danych | |
|
Wstęp W poprzednim rozdziale ustaliśmy, że w naszym podejściu zapytania będą pełnić rolę wyrażeń znanych z języków programowania. Ponieważ jednocześnie przyjęliśmy zasadę ortogonalnej trwałości, która nie różnicuje sposobów dostępu do trwałych i nietrwałych danych, wobec tego nasze zapytania będą również stosowane do nietrwałych danych. Inaczej mówiąc, przyjęliśmy, że w naszym (jak dotąd hipotetycznym) języku programowania nie będzie innych wyrażeń niż zapytania. Zapytaniami będą więc także klasyczne wyrażenia, takie jak 2+2, sin(x), A[i+1] itd. To założenie jest pewną rewolucją w odniesieniu do języków zapytań. Tradycyjnie, np. w języku SQL zapytania (zagnieżdżone w język programowania) mogły odwoływać się do zmiennych języka programowania poprzez specjalną składnię. Z powodu różnej przestrzeni nazw, nazwy zmiennych były w zapytaniach SQL poprzedzane znakiem dwukropka i specyficznie wiązane, tak aby zatrzeć różnicę pomiędzy wczesnym wiązaniem zmiennych a późnym wiązaniem charakterystycznym dla języka SQL. Postępem w tym zakresie był system DBPL [Matt92, Schm94] bazujący na języku Modula-2. Przyjęto tam zasadę ortogonalnej trwałości, ale pozostawiono tradycyjne wyrażenia języka Modula-2 operujące na zmiennych nietrwałych. Zapytania natomiast mogły operować na trwałych i nietrwałych kolekcjach. Mogły też używać zmiennych nie będących kolekcjami, ale z ograniczeniami. Uzasadnione to było w ten sposób, że przetwarzanie zapytań nie może obejść się bez optymalizacji, zaś pełna moc obliczeniowa języka zapytań zredukuje możliwość zastosowania metod optymalizacyjnych. Konsekwencją tego był syntaktyczny i semantyczny podział na wyrażenia i zapytania w ramach jednego zintegrowanego języka programowania. Argument o konieczności zredukowania mocy języka ze względu na optymalizację jest powierzchowny i kontrowersyjny. Jeżeli nie dopuścimy pewnej funkcjonalności w języku zapytań, to programista będzie musiał ją zrealizować inaczej, prawdopodobnie również bez optymalizacji. Przypomina to sytuację, w której w nowoczesnej kuchence elektrycznej ograniczono temperaturę do 50 stopni, ponieważ ktoś mógłby się poparzyć. Ponieważ większość zastosowań kuchennych wymaga i tak temperatury co najmniej 100 stopni, zmusza to kucharza do rozpalania paleniska, gdzie oczywiście też może się poparzyć, ale już w inny, mniej nowoczesny sposób, za który nowoczesna maszynka nie odpowiada. Podobną filozofię przyjmują języki określane jako języki czwartej generacji (4GL), gdzie występują zarówno wyrażenia odnoszące się do nietrwałych, lokalnych danych, jak i zapytania w SQL odwołujące się do tabel zapamiętanych w bazie danych. Również PL/SQL systemu Oracle, pierwszy komercyjny język programowania w pełni zintegrowany z językiem SQL wprowadza podział na wyrażenia i zapytania. Wydaje się, że w tym przypadku powodem są ograniczenia i narzuty składniowe języka SQL, w którym nie da się zapisać tak prostych wyrażeń jak 2+2. Najbardziej znany obiektowy język zapytań OQL (standard ODMG) nie różnicuje sposobu wiązania obiektów/atrybutów indywidualnych oraz obiektów/atrybutów będących kolekcjami. Standard ODMG nie zakłada jednak ortogonalnej trwałości. Zapytania w OQL dotyczą więc wyłącznie bazy danych. OQL nie jest zintegrowany z językiem programowania (w stylu PL/SQL). Zatem zapytania w OQL nie pełnią roli wyrażeń, odwołują się wyłącznie do trwałych danych ignorując nietrwałe, jakkolwiek zapytania takie jak 2+2 są w nim wyrażalne. Połączenie OQL z obiektowym językiem programowania nieuchronnie prowadzi do niekorzystnych zjawisk określanych jako "niezgodność impedancji". Mimo że manifest obiektowych baz danych [Atki89] postulował brak niezgodności impedancji, OQL powiązany z językiem Java wykazuje tę niezgodność w najbardziej "nieretuszowanej" formie. Taki "retusz" zastosowano w zagnieżdżonym SQL, gdzie nazwy zmiennych języka programowania są zintegrowane składniowo z zapytaniami. Zapytania OQL są stringami znaków komunikowanymi jako parametry specjalnych metod języka Java, co implikuje, że z semantycznego punktu widzenia są bytami różnymi od wyrażeń języka Java. Wartości zmiennych języka programowania można tam komunikować do zapytań poprzez specjalne parametry tych zapytań, w dość niewygodnej (i prawdopodobnie błędogennej) formie. ODMG uzasadnia te rozwiązania trudnością wypromowania całkowicie nowego języka programowania. Stąd oparcie koncepcji na językach o ugruntowanej pozycji, takich jak C++, Smalltalk i Java. Nieuchronną konsekwencją tego podejścia jest istnienie dwóch odrębnych systemów składni, semantyki i mechanizmów wiązania dla wyrażeń i dla zapytań, a to powoduje, że niezgodności impedancji nie da się uniknąć. Dodatkową okolicznością większości języków zapytań, która ogranicza ich rolę jako wyrażeń, jest to, że zapytanie może zwrócić wartość, ale nie może zwrócić referencji do pewnej danej zapamiętanej w składzie. Uniemożliwia to wykorzystanie zapytań jako składowych zdań imperatywnych, takich jak podstawienie (update w SQL) lub usuwanie (delete w SQL). Loqis jest prawdopodobnie pierwszym w historii systemem, w którym zrealizowano pełny język programowania oparty na wczesnej wersji omawianego w poprzednim rozdziale języka zapytań SBQL. Loqis nie wprowadza wyrażeń innych niż zapytania. Język programowania systemu Loqis posiada zestaw cech, których pełna kombinacja nie występuje w innym języku programowania:
W dalszym ciągu tego rozdziału przedstawimy konstrukcje imperatywne, które można byłoby rozwijać na bazie języka zapytań oraz abstrakcje programistyczne, takie jak procedury, procedury funkcyjne i metody. |
Copyrights © 2006 PJWSTK Materiały zostały opracowane w PJWSTK w projekcie współfinansowanym ze środków EFS. |