Spis treści

Standardy SQL

SQL jest językiem zapytań wykorzystywanym do tworzenia i modyfikacji baz danych oraz dodawania i pobierania danych z baz danych. W 1986 SQL stał się standardem wspieranym przez ISO. W początkowych wersjach specyfikacja SQL dawała wiele swobody różnym implementacjom. Z czasem zaszła potrzeba ściślejszego zdefiniowania standardu tak, aby możliwa była współpraca z wieloma różnymi bazami danych. W ten sposób został określony standard SQL-92, który do dziś jest podstawą dla wielu rozwiązań komercyjnych.

Formalną nazwą dla standardu SQL jest ISO/IEC 9075. Do tej pory zostało zatwierdzonych 6 wersji przy czym ostatnia aktualizacja miała miejsce w 2008 roku (formalna nazwa: ISO/IEC 9075:2008 lub SQL:2008). Poprzednie wersje to SQL:2003, SQL:99, SQL-92. Każde kolejne wydanie standardu zastępuje poprzednie, przez co funkcjonalności dostępne w różnych wersjach nie zawsze znajdują się w kolejnych.

Standardy SQL:2003 oraz SQL:2008 zostały podzielone na części:

Standardy uwzględniane w przeprowadzanych badaniach

Systemy DBMS

SQLite

Kompaktowy sytem zarządzania bazą danych obsługujący jezyk SQL. Jest dostępny w postaci małej biblioteki zaimplemntowanej w języku C. Silnik bazy danych w SQLite w przeciwieństwie do większości dostępnych rozwiązań nie potrzebuje być uruchamiany w osobnym procesie - co jest bardzo korzystnym rozwiązaniem szczególnie dla systemów wbudowanych. Biblioteka SQLite staje się integralną częścią aplikacji.

SQLite używa dynamicznej i słabo typizowanej składni SQL. Pozwala na równoległe odczyty. Zapisy do bazy danych odbywają się pojedyńczo. Dostępne są również API w innych językach niż C:

Dostępny jest też interfejs powłokowy. Baza może łączyć się przez ODBC. Baza SQLite przechowywana jest na dysku (lub w pamięci) w postaci B-drzew. Dla każdej tabeli i każdego indeksu istnieje osobne drzewo. SQLite oparty jest głównie na standardzie SQL:92 - implementuje większość jego funkcjonalności. Baza udostępnia transakcje ACID.

Obsługiwane funkcjonalności:

Niezaimplementowane elementy z standardu SQL:92

Przykłady nieobsługiwanych zapytań SQL











Zastosowania SQLite

SQLite jest bazą danych używaną w sytuacjach gdzie prostota ma większe znaczenie. Przykładowe zastosowania to między innymi:

Możliwość utworzenia bazy w pamięci pozwala efektywnie wykonywać operacje wyszukiwania, czy filtrowania na dużych zbiorach danych. Może być lepszym rozwiązaniem niż standardowe operacje na kolekcjach oferowane przez dany język.

Innym często spotykanym zastosowaniem jest sprawdzenie poprawności działania ORM dla modelu danych. SQLite pozwala na utworzenie tymczasowej bazy w pamięci, oraz przetestowanie odwzorowania. W trakcie budowy aplikacji może posłużyć za lokalną bazę danych wykorzystaną w testach jedostkowych.

W przypadku aplikacji desktopowych plikowa baza danych może być wygodną alternatywą dla plików XML lub własnych formatów.

PostgreSQL

PostgreSql jest jednym z najpopularniejszych obiektowo-relacyjnych systemów zarządzania bazą danych typu OpenSource. Jendnym z założeń systemu jest zgodność ze standardem SQL. Dostępny jest na wielu platformach między innymi:

Rdzeń PostgreSQL pokrywa 1, 2, 9, 11 i 14 część standardu SQL. Część 3 pokryta jest przez sterownik ODBC, a 13 implementuje plug-in PL/Java. PostgreSQL wspiera większość głównych cech SQL:2008. Dodatkowo system oferuje wiele dodatkowych funkcji.

Główne cechy PostgreSQL

Niezaimplementowane funkcje standardu

Standard SQL definiuje pewien podzbiór funkcji (Core), które muszą być zaimplementowane, aby zachować z nim zgodność. Pozostałe cechy są opcjonalne. PostgreSQL obecnie nie wspiera 14 głównych (Core) funkcji. Dwie z nich odnoszą się do modułów działających po stronie klienta, przez co nie są wymagane jeśli implementacja zapewnia wbudowany język np(ECPG).

Brakujące funkcjonalność:




Powyższe brakujące funkcjonalności odnoszą się do głównych(Core) elementów standardu SQL. Poza wymaganymi cechami standard definiuje wiele dodatkowych funkcjonalności. Wykaz zarówno zaimplementowanych jak i niezaimplementowanych funkcji standardu SQL:2008 można znaleźć w oficjalnej dokumentacji PostgreSQL

MySQL

MySQL to jeden z najpopularniejszych systemów RDBMS. Dostępny jest nie tylko oprogramowanie darmowe, istnieją też licencje komercyjne. Bazy MySQL są wykorzystywane przez wiele projektów open source, takich jak Joomla, WordPress czy phpBB. MySQL jest częścią rozwiązania LAMP (Linux/Apache/MySQL/Perl/PHP/Python), które pozwala łatwo i niewielkim kosztem uruchomić serwer webowy.

Różnice między MySQL a standardem

SELECT INTO TABLE

MySQL nie obsługuje polecenia SQL



W zamian należy użyć polecenia



Polecenie SELECT … INTO jest obsługiwane w wypadku zmiennych użytkownika.

UPDATE

Jeśli w poleceniu zawierającym UPDATE znajdzie się odwołanie do kolumny z tabeli, która jest aktualizowana, to zostanie wykorzystana aktualna wartość kolumny, a nie wartość sprzed wykonania polecenia.

Dla tabeli example

example_column_1 example_column_2
2 4
3 2

wykonanie polecenia



da efekt w postaci

example_column_1 example_column_2
8 10
8 10

Według standardu SQL po takim poleceniu tabela powinna mieć postać

example_column_1 example_column_2
8 6
8 4

Transakcje i operacje atomiczne

InnoDB

Silnik InnoDB zapewnia pełną zgodność z ACID. Obsługa błędów w trakcie transakcji różni się nieco od opisanej w standardzie SQL.

MyISAM

Silnik MyISAM działa analogicznie do trybu

autocommit=1

Do programisty należy decyzja, czy bardziej odpowiada mu bezpieczeństwo przetwarzania transakcyjnego, czy wydajność operacji atomicznych. Decyzja może być podejmowana na poziomie poszczególnych tabel. Brak przetwarzania transakcyjnego można „obejść” stosując blokady




oraz sprawdzając odpowiednie warunki, specyficzne dla przetwarzanych danych.

Klucze obce

Obecnie MySQL przy wykorzystaniu silnika InnoDB wspiera operacje związane z ograniczeniami dla kluczy obcych, m. in. takie jak CASCADE, ON DELETE, ON UPDATE. W wypadku innych silników, MySQL rozpoznaje składnię FOREIGN KEY w poleceniu CREATE TABLE, ale nie korzysta z niej, ani nie zapisuje nigdzie odpowiednich informacji. Planowane jest zaimplementowanie przechowywania tych informacji w pliku opisującym tabelę, tak aby można było je odzyskać korzystając z polecenia mysqldump albo z ODBC. W dalszej przyszłości planuje się wprowadzenie obsługi ograniczeń dla kluczy obcych w silniku MyISAM.

Komentarze

Standard SQL wykorzystuje komentarze w stylu C

/* komentarz */

MySQL obsługuje takie komentarze, co więcej, pozwala na wykonywanie kodu specyficznego dla MySQL umieszczonego w takich komentarzach, dzięki czemu można osadzać kod specyficzny dla MySQL w skryptach, które będą wykonywane również na innych serwerach baz danych.

Standard SQL zezwala również na komentarze rozpoczynające się od --



MySQL wykorzystuje komentarze rozpoczynające się od '#'



Wyrażenia rozpoczynające się od -- są traktowane przez MySQL jako komentarze, ale tylko jeśli po symbolach -- znajduje się np. spacja czy znak nowej linii. To wymaganie uzasadnione jest przypadkami takimi jak ten: Chcemy wykonać polecenie



Jeżeli payment ma wartość ujemną, np. -1, po podstawieniu otrzymamy kod



Zgodnie ze standardem SQL -- oznacza początek komentarza, czyli ostatecznie wykonałoby się polecenie



które nie zmieniłoby wartości kolumny credit.

Dodatkowo narzędzie mysql dla linii komend ignoruje linie rozpoczynające się od --

Rozszerzenia standardu SQL zaimplementowane w MySQL

Jak już napisano w sekcji dotyczącej obsługi komentarzy, MySQL pozwala na korzystanie z funkcjonalności specyficznych dla tej bazy danych w taki sposób, aby skrypty wykonywały się również na innych serwerach baz danych SQL. Kod specyficzny dla MySQL należy wstawić do komentarza w następujący sposób



Wstawienie liczby zaraz za wykrzyknikiem spowoduje wykonanie takiego kodu tylko przez odpowiednie wersje serwera



Taki kod uruchomi się tylko na serwerach MySQL w wersji 3.23.02 lub wyższej.

Organizacja danych na dysku twardym

Każda baza danych jest mapowana przy pomocy odpowiedniej struktury plików i katalogów. Konsekwencjami takiego działania są:

Składnia języka

Składnia wyrażeń SQL

Funkcje i operatory

Oracle

System zarządzania bazami danych Oracle był pierwszym komercyjnym RDBMS wspierającym język SQL. Aktualnie Oracle konkuruje z bazami Microsoft SQL Server oraz IBM DB2 UDB.

Oracle w wersji 11g Release 2 zapewnia zgodność z większością elementów standardu SQL:2008.

Core SQL:2008

Zgodność zapewniona jest przez następujące produkty:

Zgodność z poszczególnymi punktami części Core jest zaimplementowana na jednym z 5 poziomów:

Szczegółowy opis implementacji poszczególnych punktów standardu Core SQL:2008 znajduje się w dokumentacji producenta

Opcjonalne elementy SQL/Foundation:2008

Podobnie jak w wypadku Core SQL, przepisywanie tabeli z dokumentacji wydaje się być bezcelowe.

SQL/CLI:2008

Sterownik ODBC firmy Oracle jest zgodny ze standardem SQL/CLI:2008

SQL/PSM:2008

Język Oracle PL/SQL zapewnia funkcjonalność równoważną do opisanej w standardzie SQL/PSM:2008. Możliwe są niewielkie różnice w składni, takie jak nazwy, czy też kolejność słów kluczowych.

SQL/MED:2008

Baza Oracle nie jest zgodna z SQL/MED:2008

SQL/OLB:2008

Baza Oracle jest zgodna z SQL/OLB:1999. Prace nad zapewnieniem zgodności z SQL/OLB:2008 trwają.

SQL/JRT:2008

Baza Oracle zapewnia zgodność ze standardem, jej możliwości są po części rozszerzeniem zbioru funkcjonalności zdefiniowanego w standardzie.

SQL/XML:2008

Wg standardu typem danych dla XML jest XML. W bazie Oracle jego odpowiednikiem jest XMLType. Jest to jedyna różnica w stosunku do standardu i w takim wypadku (tj. gdy jedyna różnica, to nazwa typu danych) zwykło się uznawać standard za w pełni zaimplementowany.

Szczegółowy opis wsparcia dla poszczególnych elementów standardu

Mapowanie danych

Opracowano na podstawie dokumentacji producenta.

Typ danych opisany w XML schema Typ danych w bazie Oracle
float BINARY_FLOAT
double BINARY_DOUBLE
pozostałe typy numeryczne NUMBER
dayTimeDuration INTERVAL DAY TO SECOND
yearMonthDuration INTERVAL YEAR TO MONTH
pozostałe typy dotyczące daty i czasu TIMESTAMP WITH TIME ZONE
string, normalizedString, untypedAtomic VARCHAR2(4000)

Porównanie implementacji SZBD z Standardem

Widoki

Widoki
Standard SQL:2008 złożony zestaw reguł odnoszący się do akutalizowania widoków. Generalnie widok może być aktualizowany dopuki jego operacja aktualizacji dokonuje jednoznacznej zmiany
SQL-92 jest bardziej restrykcyjny. Widok nie może być aktualizowany jeśli dziedziczy po więcej niż jednej tabeli bazowej
PostgreSQL Posiada widoki. Nie pozwala na bezpośrednią aktualizacje do widoków. Oferuje niestandardowe rozwiązanie polegające na zastosowaniu reguł(rules)
MySql Zgodny z SQL-92
Oracle zgodny z SQL-92

Złączenia

Typ złączenia PostgreSql MySql Oracle
NATURAL joins Tak Tak Tak
Klauzula USING Tak Tak Tak
FULL joins Tak Nie Tak
Jawny CROSS JOIN Tak Tak Tak

Uwagi: Złączenie typu FULL moża emulować poprzez połączenie złączeń LEFT i RIGHT

Operacje DDL

Założenia: Istniejąca tabela t1 ma być skopiowana do nowej tabeli t2 bez kopiowania danych. Tylko struktura tabeli jest kopiowana.

Kopiowanie struktury (DDL)
Standard Klauzula LIKE (opcjonala funkcja - T171)


System zarządzania bazą danych może wspierać rozszerzenie(T173) pozwalające na dokładniejsze specyfikowanie kopiowanych właściwości



Wyzwalacze, ograniczenia i inne niestandardowe cechy tabeli nie są kopiowane

PostgreSql Zgodny z podstawową fukcją standardu. Rozszerzenia wspierane są tylko częściowo.
PostgreSql nie pozala na kopiowanie struktury widoku poprzez użycie


. Wymagana jest konstrukcja typu:


MySql Wspiera podstawową funkcjonalność. Nie wspiera rozszerzeń. Nie pozwala na kopiowane struktury widoku do tabeli
Oracle Nie wspiera standardu. Pozwala na kopiowanie tabel poprzez użycie kunstrukcji


z nieprawdziwym warunkiem w kklauzuli WHERE


Operacje DML

SELECT

Ustalanie porządku wyników
Standard Standardowo relacje są nieuporządkowane, ale wyniki zapytań mogą być zwracane do użytkownika w formie uporządkowanej, poprzez użycie kursora


Bazy danych mogą zawierać dodatkową definicję ORDER BY
Standard nie definiuje w jaki sposób powinny być porządkowane wartości NULL względem wartości nie będących NULL. Systemy baz danych mogą jednak dodatkowo oferować metody sortowania:


PostgreSql Zezwala na definiowanie kursora oraz na użycie ORDER BY.
Domyślnie wartości NULL są traktowane jako wyższe od wartości nie będących NULL. To zachowanie może być zmienione poprzez zastosowanie NULLS FIRST lub NULLS LAST w wyrażeniu ORDER BY
MySql Zezwala na definiowanie kursora oraz na użycie ORDER BY.
Domyślnie wartości NULL są traktowane jako niższe od wartości nie będących NULL.
Oracle Zezwala na definiowanie kursora oraz na użycie ORDER BY.
Domyślnie wartości NULL są traktowane jako wyższe od wartości nie będących NULL. To zachowanie może być zmienione poprzez zastosowanie NULLS FIRST lub NULLS LAST w wyrażeniu ORDER BY.
Oracle traktuje puste stringi i NULL jako taką samą wartość.

Limitowanie wyników zapytań - proste
Standard Standard dostarcza 3 sposobów na wykonywanie prostego limitowania:
- Użycie FETCH FIRST


- Użycie Window function ROW_NUMBER() OVER:



- użycie kursora


PostgreSql Wspiera wszystkie standardowe podejścia
MySql Nie wspiera standardu

Oracle Wspiera ROW_NUMBER, nie wspiera FETCH FIRST


Limitowanie wyników zapytań - top(n)
Standard Standard definiuje dwa podejścia:
- Szybkie:
Sformułowanie zapytania top(n) z wykorzystaniem window function:



- Wolne:
Jeśli SZBD nie wspiera OLAP


PostgreSql Wspiera szybki wariant standardu.
MySql Wspiera wolny wariant standardu. W praktyce w celu uzyskania odpowiedniej wydajności stosuje się rozwiązanie specyficzne dla MySql

Oracle Wspiera szybki wariant standardu. Oracle nie obsługuje AS po podzapytaniach przez co rozwiązanie można zapisać w postaci:


Limitowanie wyników zapytań - z offsetem
Standard Standard dostarcza 3 rozwiązania
- Używając OFFSET i FETCH FIRST


- Używając window function



- Używając kursora


PostgreSql Wspiera wszystkie rozwiązania standardu
MySql Nie wspiera standardu. Alternatywne rozwiązanie:

Oracle Wspiera ROW_NUMBER()

INSERT

Wstawianie kilku wierszy w tym samym czasie
Standard


jest skróconą formą


PostgreSql Zgodnie z standardem
MySql Zgodnie z standardem
Oracle

Typy danych

Boolean

Standard W standardzie typ BOOLEAN jest opcjonalny. Może przyjmować literały w postaci:
- TRUE
- FALSE
- UNKNOWN lub NULL
SZBD może interpretować NULL jako UNKNOWN, ale nie jest to dokładnie sprecyzowane.
Jest zdefiniowany TRUE > FALSE
PostgreSql Zgodnie z standardem. Traktuje NULL jako literał. Nie akceptuje UNKNOWN
MySql BOOLEAN jest aliasem typu TINYINT(1). Akceptuje literały TRUE i FALSE (odpowiednio 1 i 0 ) lub NULL.
Oracle Nie wspiera typu BOOLEAN

Char

Standard - Powoduje błąd jeśli wstawiany łańcuch jest za długi. Jeśli znaki przekraczające długość są spacjami, działa poprawnie
- Wypełnia kolumnę typu CHAR spacjami jeśli wpisany łańcuch jest za krótki
- Wypełnia spacje w przypadku rzutowania i porównywania z innymi typami podobnymi do łańcucha znaków (VARCHAR)
PostgreSql Wypełnia kolumnę CHAR spacjami, ale usuwa je przed wykonaniem większości funkcji
MySql Usuwa spacje na końcu łańcucha znaków
Oracle Zgodnie z standardem. Powoduje błąd w przypadku, gdy znaki spacji przekraczają długość CHAR

Data i czas

Standard Część głównych wymagań standardu. Zapisuje rok, miesiąc, dzień, godzina, minuta, sekunda(z dokładnością do 6 cyfr). Rozszerzenia pozwalają dodatkowo zapisać strefę czasową
Przykład TIMESTAMP


Przykład TIMESTAMP WITH TIME ZONE


PostgreSql Zgodnie ze standardem z wyjątkiem:
W niektórych przypadkach TIMESTAMP '2003-08-23 01:02:03 +02:00' jest interpretowane jako TIMESTAMP WITHOUT TIME ZONE, a nie jak TIMESTAMP WITH TIME ZONE
Poprawny kod:


Niepoprawny kod:


MySql MySql nie zapisuje ułamkowych części sekund oraz strefy czasowej( typ TIME akceptuje czas wraz z częścią ułamkową, ale nie zapisuje jej).
MySql posiada typ TIMESTAMP - jest to typ daty, który jest automatycznie aktualizowana do obecnej daty i godziny w przypadku spełnienia pewnych kryteriów.
MySql posiada typ DATETIEME - typ daty podobny do TIMESTAMP, ale nie jest automatycznie aktualizowany.
Domyślne sprawdzanie poprawności dat przez MySql jest słabej jakości. Dla pewności należy ręcznie sprawdzić poprawność zapisanych danych w DATETIME
Oracle Zgodnie ze standardem

Funkcje SQL

CHARACTER_LENGTH

Standard CHARACTER_LENGTH(argument)
Zwraca NUMERIC. Zwraca NULL jeśli wejście jest NULL.
Alias: CHAR_LENGTH.
Argument może być typy CHAR lub VARCHAR.
Część głównych wymagań standardu.
Powiązane funkcje: OCTET_LENGTH.
PostgreSql Zgodnie ze standardem. CHARACTER_LENGTH (i CHAR_LENGTH).
Usuwa końcowe spacje przed zliczaniem
MySql Posiada CHARACTER_LENGTH.
Aliasy: CHAR_LENGTH, LENGTH.
Usuwa spacje przed zliczaniem.
Oracle Nie posiada CHARACTER_LENGTH. Wprowadza funkcję LENGTH. Podobnie traktuje NULL i pusty łańcuch.
Nie usuwa spacji.

SUBSTRING

Standard Standard definiuje dwa warianty funkcji SUBSTRING:
1. Standardowa funkcja SUBSTRING pobiera znaki z łańcucha


Łańcuch rozpoczyna się od pozycji 1
- start-position - numeryczna wartość
- length - jeśli nie jest podany przyjmuje nieskończoność.
Jeśli którykolwiek z argumentów jest NULL to wynikiem jest NULL.
Jeśli wartość atrybutu start-position jest mniejsza od 1 to przyjmuje on wartość 1 i wówczas argument length przyjmuje 1+abs(start-position)

2. Funkcja SUBSTRING z obsługą wyrażeń regularnych



String wzorca musi posiadać trzy części: Część która jest zgodna z łańcuchem przed wystąpieniem szukanej frazy oraz część, która ma być po szukanej frazie


PostgreSql Obsługuje trzy rodzaje metody SUBSTRING.
- Podstawowe rozwiązanie standardu
- z obsługą wyrażeń regularnych POSIX
- z obsługą wyrażeń regularnych Standardu. Zwraca NULL jeśli wzorzec nie pasuje
MySql Obsługuje podstawową wersję Standardu. Działanie funkcji różni się w przypadku ujemnych wartości pozycji startowej
Oracle Nie wspiera standardu. Wprowadza funkcję SUBSTR(input, start-pos[,length]) oraz wiele jej wariantów. Do obsługi wyrażeń regularnych używa funkcji REGEXP_SUBSTR

TRIM

Standard TRIM(where characters FROM string_to_be_trimmed)
where - LEADING, TRAILING lub BOTH, pominięty oznacza BOTH
characters - znak który ma być usunięty, pominięty oznacza ' ' spację
Skrócona postać


jest równoznaczna



TRIM(NULL) zwraca NULL

PostgrSql Zgodnie ze standardem
MySql Zgodnie ze standardem
Oracle Zgodnie ze standardem z wyjątkiem:
- Nie można usuwać wielu znaków
- Inaczej obsługuje NULL i pusty łańcuch znaków

LOCALTIMESTAMP

Standard aktualny TIMESTAMP ( bez strefy czasowej ) uzyskiwany jest z funkcji LOCALTIMESTAMP

PostgrSql Zgodnie ze standardem
MySql Zgodnie ze standardem
Oracle Zgodnie ze standardem

Konkatenacja

Standard Dokonuje konkatenacji dwóch stringów przy użyciu operatora ||


Jeśli którykolwiek operand jest równy NULL to wynikiem jest NULL

PostgrSql Zgodnie ze standardem. Automatycznie rzutuje połączone wartości do odpowiednich typów
MySql Niezgodny ze standardem ( re definiuje || na OR.
Oferuje funkcję CONCAT(string, string). Automatycznie rzutuje połączone wartości do odpowiednich typów. Jeśli którykolwiek operand jest równy NULL to wynikiem jest NULL
Oracle Częściowo zgodnie ze standardem. Automatycznie rzutuje połączone wartości do odpowiednich typów. Niestandardowo obsługuję NULL i puste łańcuchy znaków.

Operacje masowe

TRUNCATE TABLE
Standard Standard SQL oferuje wyrażenie TRUNCATE TABLE tablename:
Usuwa wszystkie wiersze tabeli bez uruchamiania akcji wyzwalaczy.
Standard nie specyfikuje czy
- TRUNCATE TABLE może być umieszczany w transakcji z innymi operacjami
- TRUNCATE TABLE powinien automatycznie wykonywać COMMIT
PostgreSql Zgodnie ze standardem. Pozwala na umieszczanie w transakcji TRUNCATE TABLE razem z innymi operacjami. Nie Wywołuje COMMIT
MySql Posiada TRUNCATE TABLE, ale nie jest zgodny ze standardem. Zachowania zależy od storage engine (np. InnoDB)
Oracle Zgodnie ze standardem. TRUNCATE TABLE automatycznie wykonuje COMMIT

Linki: