www.eprace.edu.pl » obiektowe-bazy » Standardy » Język SQL:1999

Język SQL:1999

SQL:1999 jest długo oczekiwanym standardem, który podczas procesu tworzenia był nazywany SQL3. Planowaną datą opublikowania nowego standardu, który miał znacznie rozszerzać możliwości SQL’a drugiej generacji (SQL-92), był rok 1996. Niestety, rzeczywistość rozminęła się z planami i zamiast planowanych trzech do czterech lat, rozwój nowego standardu zajął twórcom siedem lat. Jak wskazuje nazwa, SQL trzeciej generacji został opublikowany w 1999 roku.

SQL3 był charakteryzowany jako „SQL zorientowany obiektowo”. W dalszej części pracy pokazano, iż SQL:1999 jest czymś więcej, niż tylko językiem SQL-92 wzbogaconym o technologię obiektową. Nowy standard wzbogacono także o dodatkowe cechy, które można uważać za rozszerzenia relacyjnych cech SQL’a, poddano także całkowitej restrukturyzacji dokumentację standardu, aby ułatwić jego rozwój w przyszłości.

Rozwój standardu

Dwie organizacje aktywnie uczestniczące w tworzeniu standardu i rozwoju języka SQL:1999 to ANSI oraz ISO.

Dokładniej, społeczność międzynarodowa współpracuje poprzez ISO/IEC JTC1 (Joint Technical Committee 1), komitet stworzony przez ISO (International Organization for Standardization) wraz z IEC (International Electrotechnical Commission).

Zadaniem JTC1 jest rozwój i nadzór nad standardami związanymi z ogólnie pojętą informatyką (ang. Information Technology).

W obrębie JTC1 został stworzony komitet SC32 (Data Management and Interchange). Jego zadaniem było przejęcie standaryzacji kilku standardów związanych z bazami danych, które to standardy były rozwijane przez inne organizacje (jak na przykład rozwiązany SC21). Z kolei SC32 stworzył kilka grup zajmujących się stroną techniczną. Przykładowo WG3 (Working Group 3) jest grupą odpowiedzialną za standard SQL, podczas gdy WG4 (Working Group 4) zajmuje się rozwojem SQL/MM (SQL MultiMedia).

W Stanach Zjednoczonych standardy informatyczne rozwijane są przez komitet NCITS (National Committee for Information Technology Standardization), będący częścią ANSI (American National Standards Institute). Komitet NCITS (uprzednio „X3H2”) jest odpowiedzialny za kilka standardów związanych z zarządzaniem danymi, między innymi SQL oraz SQL/MM.

Kiedy projektowana była pierwsza generacja SQL’a (SQL-86 i jego rozszerzenie SQL-89), większość prac została wykonana w Stanach Zjednoczonych przez X3H2, a także przez społeczność międzynarodową, która aktywnie uczestniczyła w recenzowaniu propozycji ANSI. Zanim standard SQL-89 został opublikowany, społeczność międzynarodowa stawała się coraz bardziej aktywna w zgłaszaniu nowych propozycji, które znalazły odzwierciedlenie w standardzie SQL-92. Podobnie wyglądał proces rozwoju obecnego standardu SQL:1999. Z całą pewnością można zatem stwierdzić, iż SQL jest efektem międzynarodowej współpracy.

W dalszej części pracy przedstawione zostały rozszerzenia wprowadzone do standardu SQL:1999.

Informacje zawarte w kolejnych podrozdziałach pochodzą w dużej mierze z opracowania [Eisenberg 1999], którego autorzy brali czynny udział w rozwoju standardu. Podobnie jak we wspomnianej pracy, także tutaj nowe cechy SQL’a zostały podzielone na cechy relacyjne i obiektowe.

Cechy relacyjne

Opisane poniżej cechy zostały nazwane cechami relacyjnymi, choć bardziej poprawne wydaje się nazwanie ich cechami odnoszącymi się do tradycyjnej roli i modelu danych SQL’a. Cechy opisane poniżej nie są ograniczone jedynie do modelu relacyjnego, lecz nie są także powiązane z obiektowością jako taką.

Cechy te zazwyczaj są dzielone na pięć grup: nowe typy danych, nowe predykaty, poprawiona semantyka, dodatkowe bezpieczeństwo oraz aktywność bazy danych.

Poniżej przedstawiono poszczególne grupy.

Nowe typy danych

SQL:1999 posiada cztery nowe typy danych.

Pierwszym z nich jest typ LARGE OBJECT (LOB). Typ ten posiada dwa warianty: CHARACTER LARGE OBJECT (CLOB) oraz BINARY LARGE OBJECT (BLOB). Typy te zostały zdefiniowane w celu obsługi bardzo dużych obiektów.

Typ CLOB zachowuje się podobnie jak ciąg znaków, lecz posiada ograniczenia uniemożliwiające jego wykorzystywanie w wyrażeniach UNIQUE jako klucza podstawowego, klucza obcego oraz w porównaniach innych niż testy równości i nierówności.

Typ BLOB posiada podobne ograniczenia.

Tym samym typ LOB nie może być także wykorzystywany w wyrażeniach GROUP BY oraz ORDER BY. Aplikacje nie przekazują właściwych wartości LOB do i z bazy danych, lecz manipulują nimi poprzez specjalny typ, znajdujący się po stronie klienta, zwany LOB lokalizator (ang. locator). W SQL:1999 lokalizator jest unikalną wartością binarną, która zachowuje się jak zastępca wartości przechowywanej w bazie danych. Lokalizator może być wykorzystywany w różnych operacjach bez konieczności występowania dodatkowego nakładu związanego z przekazywaniem właściwej wartości LOB pomiędzy klientem i serwerem.

Kolejnym nowym typem danych jest typ BOOLEAN, który umożliwia bezpośrednie wskazywanie wartości true, false oraz unknown.

SQL:1999 posiada także dwa nowe typy zbiorowe: ARRAY oraz ROW.

Typ ARRAY umożliwia przechowywanie zbioru wartości bezpośrednio w kolumnie tabeli bazy danych. Przykładowo:

WEEKDAYS VARCHAR(10) ARRAY[7]

Powyższa definicja pozwala na przechowywanie nazw wszystkich siedmiu dni tygodnia w jednym wierszu tabeli.

Nasuwa się tutaj pytanie, czy SQL:1999 pozwala na tworzenie baz danych, które nie spełniają założeń pierwszej postaci normalnej.9 Jest tak rzeczywiście, w sensie zezwalania na „powtarzane grupy”, które nie są dopuszczane przez pierwszą postać normalną. Jednakże słychać opinie, iż typ ARRAY pozwala jedynie na przechowywanie informacji, które mogą być dekomponowane (podobnie jak funkcja SUBSTRING dekomponuje ciągi znaków), dlatego też nie łamie w pełni założeń pierwszej postaci normalnej.

Typ ROW w SQL:1999 udostępnia twórcom możliwość przechowywania wartości strukturalnych w pojedynczych kolumnach bazy danych. Przy rozpatrywaniu tego typu także mogą nasunąć się wątpliwości odnośnie zasad pierwszej postaci normalnej, jednakże są one rozpatrywane podobnie jak dla opisanego powyżej typu ARRAY.

Ostatnim typem jest typ rozróżniony (ang. distinct type). Umożliwia on tworzenie deklaracji powodujących, że dwie normalnie równoważne deklaracje typu są traktowane jako różne typy danych.

Jakiekolwiek próby traktowania instancji jednego typu jako instancji drugiego będą skutkowały wystąpieniem błędu, pomimo tego, iż oba typy posiadają taką samą reprezentację.

Nowe predykaty

SQL:1999 wprowadził trzy nowe predykaty. Dwa z nich to predykaty SIMILAR oraz DISTINCT, które przedstawione zostały poniżej.

Predykat SIMILAR umożliwia użycie wyrażeń regularnych przy porównywaniu wzorców, podobnie jak ma to miejsce w systemie UNIX. Niestety, składnia wyrażeń używanych w tym predykacie nie jest identyczna ze składnią wyrażeń regularnych UNIX’a. Jest to spowodowane tym, iż niektóre ze znaków wykorzystywanych w tym celu w UNIX’ie miały już inne zastosowanie w języku SQL.

Kolejnym nowym predykatem jest DISTINCT, który w zastosowaniu jest bardzo podobny do predykatu UNIQUE. Ważną różnicą pomiędzy tymi predykatami jest traktowanie wartości NULL.10 Dwie wartości NULL są uważane jako nierówne i w związku z tym spełniają predykat UNIQUE. Jednak nie zawsze takie zachowanie jest pożądane. Predykat DISTINCT traktuje dwie wartości NULL jako nie różniące się między sobą i w związku z tym te dwie wartości NULL nie będą spełniały predykatu DISTINCT.

Nowa semantyka

Długo oczekiwanym przez twórców aplikacji elementem jest aktualizacja perspektyw (ang. view updating). Wiele środowisk wykorzystuje perspektywy jako mechanizm bezpieczeństwa, bądź też jako uproszczenie aplikacyjnego widoku bazy danych. Jednakże jeśli perspektywy nie mogą być aktualizowane, wówczas aplikacje muszą rezygnować z wykorzystywania perspektyw i polegać na bezpośredniej aktualizacji tabel, co jest rozwiązaniem niezadowalającym.

SQL:1999 znacząco zwiększył zakres perspektyw, które mogą być aktualizowane przy wykorzystaniu tylko dodatkowych funkcji dostarczonych w standardzie. Działanie tego mechanizmu w dużym stopniu opiera się na funkcjonalnych zależnościach, od których zależy, jakie perspektywy mogą być aktualizowane, a także w jaki sposób należy wykonywać zmiany w tabelach bazy odwzorowujące owe uaktualnienia.

Kolejnym rozszerzeniem są zapytanie rekurencyjne. Stworzenie takiego zapytania polega na określeniu wyrażenia, które chcemy poddać rekurencji i nadaniu mu odpowiedniej nazwy. Następnie wykorzystuje się tę nazwę w skojarzonym zapytaniu. Obrazuje to poniższy przykład:

WITH RECURSIVE

Q1 AS SELECT...FROM...WHERE...,

Q2 AS SELECT...FROM...WHERE...,

SELECT...FROM Q1, Q2 WHERE...

W rozdziale o nowych typach danych wspomniano o lokalizatorach jako wartościach, które reprezentują znajdujące się po stronie serwera wartości typu LOB. Lokalizatory mogą być wykorzystywane w taki sam sposób do reprezentacji wartości tablicowych (ARRAY) w związku z tym, iż tablice bardzo często są zbyt duże, aby przesyłać je pomiędzy aplikacją i serwerem. Ostatnim wykorzystaniem lokalizatorów może być reprezentowanie wartości typów definiowanych przez użytkownika, omawiane w dalszej części pracy, które to typy także mogą być znacznych rozmiarów.

Ostatnim elementem, który zostanie zaprezentowany jest pojęcie określane jako punkt składowania (ang. savepoint). Jest to mechanizm będący rodzajem podtransakcji, polegający na tym, iż aplikacja może cofnąć operacje wykonane po ustawieniu punktu składowania, bez konieczności anulowania wszystkich operacji w obrębie transakcji. SQL:1999 zezwala na wykonywanie zapytań postaci ROLLBACK TO SAVEPOINT oraz RELEASE SAVEPOINT, które działają podobnie jak podtransakcje.

Dodatkowe bezpieczeństwo

Rozszerzeniem bezpieczeństwa w języku SQL:1999 jest zastosowanie mechanizmu określanego mianem roli (ang. role). Do ról mogą być przypisywane przywileje, w taki sam sposób jak do indywidualnych użytkowników. Role mogą być przypisywane do poszczególnych użytkowników, a także do innych ról. Zastosowanie tego elementu znacznie upraszcza definiowanie złożonych zbiorów przywilejów.

Aktywność bazy danych

Element ten jest dostarczany poprzez zastosowanie wyzwalaczy (ang. triggers). Jest to mechanizm pozwalający twórcy bazy danych na zaprogramowanie jej w ten sposób, ażeby system bazy wykonywał pewne specyficzne operacje za każdym razem, gdy aplikacja wykona określone działania na pewnych tabelach.

Wyzwalacze czasami nazywane są regułami zdarzenie-warunek-akcja (ang. ECA rules).

Instrukcja wyzwalacza udostępnia wiele opcji w zakresie każdego elementu: zdarzenia, warunku i akcji. Podstawowe właściwości są następujące:

Cechy obiektowe

Oprócz cech opisanych do tej pory, rozwój SQL:1999 koncentrował się głównie na wzbogaceniu języka o cechy obiektowości.

Część z cech opisywanych w tej kategorii została po raz pierwszy zdefiniowana w standardzie SQL/PSM, opublikowanym w roku 1996.

Strukturalne typy definiowane przez użytkownika

Najbardziej fundamentalnym udogodnieniem wspierającym obiektowość w języku SQL:1999, jest strukturalny typ definiowany przez użytkownika (ang. Structured User-Defined Type). Słowo „strukturalny” odróżnia ten typ od typu rozróżnionego, który także jest typem definiowanym przez użytkownika, lecz w obecnej wersji języka musi on bazować na typach wbudowanych SQL’a i w związku z tym nie posiada skojarzonej struktury.

Typy strukturalne posiadają wiele cech, z których najważniejsze to:

Przykładowa definicja typu strukturalnego może wyglądać następująco:

CREATE TYPE emp_type

UNDER person_type

AS (EMP_ID INTEGER,

SALARY REAL)

INSTANTIABLE

NOT FINAL

REF (EMP_ID)

INSTANCE METHOD

GIVE_RAISE

(ABS_OR_PCT BOOLEAN,

AMOUNT REAL)

RETURNS REAL

Zdefiniowany powyżej nowy typ emp_type jest podtypem innego typu strukturalnego person_type, ogólnie opisującego osoby. Zdefiniowany powyżej typ posiada nowe atrybuty takie jak ID pracownika oraz jego pensję (EMP_ID, SALARY). Typ ten został zadeklarowany jako INSTANTIABLE, co oznacza, że mogą być tworzone wartości tego typu. Oznaczenie NOT FINAL informuje, że typ ten może posiadać podtypy. Powyższa definicja informuje także, iż referencje do tego typu wywodzą się z wartości ID pracownika (EMP_ID). Ostatecznie zadeklarowana została metoda mogąca działać na instancjach tego typu. W dalszej części pracy referencje i metody zostały omówione dokładniej.

Po wielu próbach odnośnie dziedziczenia, kiedy to podtypy mogły posiadać więcej niż jeden bezpośredni nadtyp, SQL:1999 prezentuje model dziedziczenia podobny do pojedynczego dziedziczenia w języku Java.

Podczas definiowania typu można określić, czy dany typ jest INSTANTIABLE, czyli jak wspomniano wyżej, mogą być tworzone konkretne wartości tego typu, czy też jest to typ NOT INSTANTIABLE, co stanowi analogię do typów abstrakcyjnych w innych językach programowania.

Wszystkie miejsca, takie jak przykładowo kolumna, dopuszczające występowanie wartości konkretnego typu strukturalnego muszą zezwalać na pojawianie się tam wartości jego dowolnego podtypu.

W tym miejscu należy wspomnieć o jeszcze jednym istotnym zagadnieniu. Większość obiektowych języków programowania pozwala na definiowanie stopnia hermetyzacji typu. Hermetyzacja na poziomie PUBLIC oznacza, że atrybut jest w pełni dostępny. Modyfikator PRIVATE oznacza, iż poza metodami zadeklarowanymi w obrębie typu, żadne inne nie mają dostępu do tak oznaczonego atrybutu. Ostatecznie PROTECTED informuje, że dostęp do atrybutu posiadają tylko metody danego typu i wszystkich jego podtypów.

Język SQL:1999, pomimo prób zdefiniowania powyższego mechanizmu, ostatecznie go nie posiada. Przewiduje się, iż element ten zostanie rozważony w przyszłych wersjach standardu.

Metody a funkcje

SQL:1999 bardzo wyraźnie rozróżnia zwyczajne funkcje SQL’a od metod. W bardzo dużym uproszczeniu, metoda jest funkcją z pewnymi ograniczeniami i rozszerzeniami.

Poniżej zebrane zostały różnice pomiędzy funkcjami i metodami:

Zarówno funkcje, jak i metody mogą być pisane w języku SQL, lub też w jednym z kilku bardziej tradycyjnych języków programowania, między innymi w Javie.

Zapis funkcjonalny i kropkowy

Dostęp do atrybutów typów definiowanych przez użytkownika może być dwojakiego rodzaju, poprzez zapis funkcjonalny lub kropkowy. W wielu przypadkach bardziej naturalne wydaje się użycie zapisu kropkowego:

WHERE emp.salary > 10000

są jednak przypadki, gdy zapis funkcjonalny jest odpowiedniejszy:

WHERE salary(emp) > 10000

SQL:1999 obsługuje oba zapisy. W rzeczywistości są one zdefiniowane jako syntaktyczne odmiany tej samej funkcjonalności semantycznej, tak długo jak emp jest przechowywaną jednostką, której typem jest jakiś typ strukturalny z atrybutem o nazwie salary, bądź też istnieje funkcja nazwana salary z jednym argumentem typu strukturalnego emp.

Metody w tym przypadku są mniej elastyczne od funkcji. Dla wywoływania metod może być wykorzystywany tylko zapis kropkowy. Jeśli salary jest metodą związaną z typem employee, który jest typem kolumny o nazwie emp, wówczas metoda może być wywołana tylko w poniższy sposób:

emp.salary

Pewna inna metoda o nazwie make_raise może korzystać zarówno z zapisu kropkowego jak i funkcjonalnego:

emp.make_raise(amount)

Obiekty oraz typ REF

Jak dotychczas unikano używania określenia obiekt w stosunku do typów strukturalnych. Jest to związane z tym, iż poza kilkoma właściwościami, takimi jak hierarchiczność czy hermetyzacja, instancje typów strukturalnych języka SQL:1999 są po prostu wartościami, podobnie jak instancje typów wbudowanych. Oczywiście wartość zdefiniowanego wcześniej typu opisującego pracownika jest dużo bardziej złożona, niż na przykład instancja typu INTEGER, lecz mimo tego jest to nadal wartość nie posiadająca swoistej tożsamości.

Aby jednak SQL:1999 mógł dostarczać obiekty posiadające swoją tożsamość, dzięki której możliwe są odwołania do nich w różnych sytuacjach, dodano kolejne rozszerzenie. Rozwiązanie to pozwala twórcom baz danych na specyfikowanie, że określone tabele są zdefiniowane jako tabele typowane (ang. typed tables). Oznacza to, że definicje ich kolumn wywodzą się z atrybutów typu strukturalnego. Obrazuje to poniższy przykład:

CREATE TABLE empls OF emp_type

Tabele takie posiadają jedną kolumnę dla każdego atrybutu odpowiadającego typowi strukturalnemu. Funkcje, metody i procedury zdefiniowane do operowania na instancjach typu działają teraz na wierszach tabeli. Wiersze tabeli są zatem wartościami (instancjami) typu. Każdemu wierszowi jest przyporządkowany unikalny identyfikator, zachowujący się jak identyfikator obiektu. Identyfikator ten jest unikalny w obrębie bazy danych.

SQL:1999 dostarcza specjalny typ referencyjny, oznaczany jako REF, którego wartościami są te unikalne identyfikatory. Dany typ REF jest zawsze skojarzony z określonym typem strukturalnym. Przykładowo, definicja tabeli zawierającej kolumnę o nazwie manager, której wartościami są referencje do wierszy w typowanej tabeli pracowników, wygląda następująco:

manager REF(emp_type)

Wartość typu REF identyfikuje wiersz w tabeli typowanej, lub też nie identyfikuje nic, jeśli usunięto wiersz, który był uprzednio przez nią identyfikowany.

Tabela, na którą wskazuje typ REF musi być znana już w fazie kompilacji. W trakcie tworzenia standardu SQL:1999 podejmowano próby stworzenia typów REF jako bardziej ogólnych. Niestety działania te spotkały się z dużymi trudnościami, których rozwiązanie wymagałoby dalszego opóźnienia publikacji standardu. W związku z tym wprowadzono powyższe ograniczenie. Jednym z korzystnych jego efektów jest ułatwienie implementacji tego mechanizmu w niektórych produktach

Typy REF mogą być oczywiście wykorzystywane w bardziej zaawansowany sposób niż przedstawiony powyżej.

SQL:1999 dostarcza składnię pozwalającą na dostęp do atrybutów wartości typu strukturalnego.

SELECT emps.manager->last_name

Zapis wskaźnikowy jest stosowany do wartości typu REF i prowadzi do wartości skojarzonego typu strukturalnego, który w rzeczywistości jest wierszem typowanej tabeli będącej w zasięgu typu REF.

Opinie o standardzie

Z pewnością nowy standard SQL’a wprowadza dość rewolucyjne zmiany do języka. Pomimo wielu bezsprzecznych ulepszeń, SQL:1999 wprowadza także modyfikacje, które są odbierane dość krytycznie. Poniżej przedstawione zostały uwagi zawarte w pracy [Subieta 1998a].

Autor stwierdza między innymi, że:



komentarze

Copyright © 2008-2010 EPrace oraz autorzy prac.