Wstęp Structured Query Language (SQL) to strukturalny język zapytań używany do tworzenia, modyfikowania baz danych, oraz do umieszczania i pobierania danych z baz danych. Język SQL jest językiem deklaratywnym. Decyzję o sposobie przechowywania i pobrania danych pozostawia się systemowi zarządzania bazą danych DBMS. Jest to język programowania opracowany w latach siedemdziesiątych w firmie IBM. Stał się on standardem w komunikacji z serwerami relacyjnych baz danych. Wiele współczesnych systemów relacyjnych baz danych używa do komunikacji z użytkownikiem SQL dlatego mówi się że korzystanie z relacyjnych baz danych, to korzystanie z SQL-a. Pierwszą firmą, która włączyła SQL do swojego produktu komercyjnego, był Oracle. Dalsze wprowadzanie SQL-a, w produktach innych firm, wiązało się nierozłącznie z wprowadzaniem modyfikacji pierwotnego języka. Wkrótce utrzymanie dalszej jednolitości języka wymagało wprowadzenia standardu. Standardy SQL W 1986 roku SQL stał się oficjalnym standardem, wspieranym przez Międzynarodową Organizację Normalizacyjną (ISO) i jej członka, Amerykański Narodowy Instytut Normalizacji (ANSI). Wczesne wersje specyfikacji (SQL86 i SQL89) były w dużej mierze jedynie określeniem wspólnej płaszczyzny łączącej różne istniejące wówczas produkty i pozostawiały wiele swobody twórcom implementacji. Z czasem jednak systemy komputerowe uległy integracji i rynek zaczął domagać się aplikacji oraz ich funkcji faktycznie współpracujących z wieloma różnymi bazami danych. Pojawiła się potrzeba określenia standardu ściślejszego. Mógł on jednocześnie obejmować nowe elementy, nieujęte do tej pory w języku. Tak powstał SQL92, obowiązujący w produktach komercyjnych do dziś. Funkcje silnika i middleware Produkty związane z relacyjnymi bazami danych to nie tylko serwery. Sam serwer określa się często takimi nazwami jak "back end", "engine", czy też "motor/silnik bazy danych". Przechowuje on dane oraz zapewnia ich pobieranie i aktualizacje w odpowiedzi na pobierane instrukcje w SQLu. Uzupełnieniem serwera jest zazwyczaj "front end", "middleware" czy też "fronton" narzędzia upraszczające komunikację z serwerem i wyposażone w mechanizmy pozwalające wykorzystać pobrane dane. Należą do nich mechanizmy generowania i obsługi formularzy oraz raportów, języki czwartej generacji (4GL), graficzne języki zapytań, narzędzia konstrukcyjne użytkownika, oprogramowanie do prezentacji multimedialnych, systemy tworzenia hipertekstu, systemy CAD/CAM, arkusze kalkulacyjne, jak również interfejsy dostępu bezpośredniego. Wszystkie one wykorzystują, do komunikacji z serwerem i wykonywania za jego pośrednictwem różnych operacji, język SQL. Serwer odpowiada za przechowywanie, porządkowanie i pobieranie danych, zapewnia ich integralność, bezpieczeństwo oraz zabezpiecza przed ewentualnymi konfliktami między użytkownikami. 1 Formy SQL-a Z technicznego punktu widzenia, SQL jest podjęzykiem danych. Oznacza to, że jest on wykorzystywany wyłącznie do komunikacji z bazą danych. Nie posiada on cech pozwalających na tworzenie kompletnych programów. Jego wykorzystanie może być trojakie i z tego względu wyróżnia się trzy formy SQLa: 1. SQL interakcyjny lub autonomiczny wykorzystywany jest przez użytkowników w celu bezpośredniego pobierania lub wprowadzania informacji do bazy. Przykładem może być zapytanie prowadzące do uzyskania zestawienia aktywności kont w miesiącu. Wynik jest wówczas przekazywany na ekran, z ewentualną opcją jego przekierowania do pliku lub drukarki. 2. Statyczny kod SQL (Static SQL) nie ulega zmianom i pisany jest wraz z całą aplikacją, podczas której pracy jest wykorzystywany. Nie ulega zmianom w sensie zachowania niezmiennej treści instrukcji, które jednak zawierać mogą odwołania do zmiennych lub parametrów przekazujących wartości z lub do aplikacji. Statyczny SQL występuja w dwóch odmianach. 1. Embedded SQL (Osadzony SQL) oznacza włączenie kodu SQL do kodu źródłowego innego języka. Większość aplikacji pisana jest w takich językach jak C++ czy Java, jedynie odwołania do bazy danych realizowane są w SQL. W tej odmianie statycznego SQLa do przenoszenia wartości wykorzystywane są zmienne. 2. Język modułów. W tym podejściu moduły SQL łączone są z modułami kodu w innym języku. Moduły kodu SQL przenoszą wartości do i z parametrów, podobnie jak to się dzieje przy wywoływaniu podprogramów w większości języków proceduralnych. Jest to pierwotne podejście, zaproponowane w standardzie SQL. Embedded SQL został do oficjalnej specyfikacji włączony nieco później. 3. Dynamiczny kod SQL (Dynamic SQL) generowany jest w trakcie pracy aplikacji. Wykorzystuje się go w miejsce podejścia statycznego, jeżeli w chwili pisania aplikacji nie jest możliwe określenie treści potrzebnych zapytań powstaje ona w oparciu o decyzje użytkownika. Tę formę SQL generują przede wszystkim takie narzędzia jak graficzne języki zapytań. Utworzenie odpowiedniego zapytania jest tu odpowiedzią na działania użytkownika. Wymagania tych trzech form różnią się i znajduje to odbicie w wykorzystywanych przez nie konstrukcjach językowych. Zarówno statyczny, jak i dynamiczny SQL uzupełniają formę autonomiczną cechami odpowiednimi tylko w określonych sytuacjach. Większość języka pozostaje jednak dla wszystkich form identyczna. Składnia SQL Użycie SQL, zgodnie ze jego nazwą, polega na zadawaniu zapytań do bazy danych. Zapytania można zaliczyć do jednego z dwóch głównych podzbiorów: SQL DML (ang. Data Manipulation Language, czyli Język Manipulacji Danymi), SQL DDL (ang. Data Definition Language, czyli Język Definicji Danych). 2 Instrukcje SQL w obrębie zapytań tradycyjnie zapisywane są wielkimi literami, jednak nie jest to wymóg. Każde zapytanie w SQL-u musi kończyć się znakiem ";" (średnik). Dodatkowo, niektóre interpretery SQL (np. psql w przypadku PostgreSQL), używają swoich własnych instrukcji, z poza standardu SQL, które służą np. do połączenia się z bazą, wyświetlenia dokumentacji, itp. DML DML służy do operacji na danych - do ich umieszczania w bazie, kasowania, przeglądania, zmiany. Najważniejsze polecenia z tego zbioru to: SELECT - pobranie z bazy danych, INSERT - umieszczenie danych w bazie, UPDATE - zmiana danych, DELETE - usunięcie danych z bazy. Dane tekstowe podawane muszą być zawsze w formie ograniczonej znakami pojedynczego cudzysłowia ('). DDL Dzięki DDL natomiast, można operować na strukturach, w których te dane są przechowywane - czyli np. dodawać, zmieniać i kasować tabele lub bazy. Najważeniejsze polecenia tej grupy to: CREATE (np. CREATE TABLE, CREATE DATABASE, ...) - utworzenie struktury (bazy, tabeli, indeksu, itp.), DROP (np. DROP TABLE, DROP DATABASE, ...) - całkowite usunięcie struktury, ALTER (np. ALTER TABLE ADD COLUMN ...) - zmiana sturktury (dodanie kolumny do tabeli, zmiana typu danych w kolumnie tabeli). Przykładowe zapytania Przykładowe użycie wyżej wymienionych rodzajów zapytań. SELECT * FROM pracownicy WHERE pensja > 2000 ORDER BY staz DESC; Wyświeta z tabeli pracownicy (FROM pracownicy) wszystkie kolumny (*) dotyczące tych pracowników, których pensja jest większa niż 2000 (WHERE pensja > 2000) i sortuje wynik malejąco według stażu pracy (ORDER BY staz DESC). INSERT INTO pracownicy (imie, nazwisko, pensja, staz) VALUES ('Jan', 'Kowalski', 5500, 1); Dodaje do tabeli pracownicy (INTO pracownicy) wiersz (rekord) zawierający dane pojedynczego pracownika. 3 UPDATE pracownicy SET pensja = pensja * 1.1 WHERE staz > 2; Podnosi o 10% (SET pensja = pensja * 1.1) pensję pracownikom, których staż jest większy niż 2 (np. lata). DELETE FROM pracownicy WHERE imie = 'Jan' AND nazwisko = 'Kowalski'; Usuwa z tabeli "pracownicy" wiersz (rekord) dotyczący pracownika o imieniu "Jan" i nazwisku "Kowalski". CREATE TABLE pracownicy (imie varchar(255), nazwisko varchar(255), pensja float, staz int); Tworzy tabelę "pracownicy" zawierającą tekstowe (varchar - zmiennej długości pole tekstowe) pola "imię" i "nazwisko", o maksymalnej długości 255 znaków, zapisaną za pomocą liczby rzeczywistej (float od ang. floating point) pensję oraz zapisany za pomocą liczby całkowitej (int od ang. integer) staż. DROP TABLE pracownicy; Usuwa z bazy całkowicie tabelę "pracownicy". ALTER TABLE pracownicy ADD COLUMN dzial varchar(255); Dodaje do struktury tabeli "pracownicy" kolumnę "dzial" (dział), jako pole tekstowe o długości max. 255 znaków. SQL:2003 W roku 2003 przedstawiono SQL:2003 – nowy standard języka SQL. opublikowano w Sigmod Record Vol.33 Nr.1 Marzec 2004 (http://www.acm.org/sigmod/record/issues/0403/E.JimAndrew-standard.pdf). Jest to głównie poprawione SQL:1999 z wyjątkiem części SQL/XML oraz kilku dodatkowych właściwości. W SQL:2003 wprowadzono: 1. 2. 3. 4. 5. 6. 7. 8. 9. Nowe typy danych (BIGINT, MULTISET oraz XML) Usunięto typy BIT oraz BIT VARYING Rozszerzenia w sposobie wywoływania procedur Poszerzono instrukcję CREATE TABLE (CREATE TABLE { LIKE | AS } ) Wprowadzono instrukcję MERGE Wprowadzono nowy obiekt schematu – generator sekwencji Wprowadzono dwa nowe typy kolumn – identyfikatory oraz generowane Retrospektywne sprawdzanie więzów integralności Rozszerzenia dla OLAP w formie wbudowanych funkcji (skalarnych i agregujących) 10. Klauzula WINDOW Prowadzone są również prace nad alternatywnymi językami zapytań opartymi na SQL. Przykładem takiego języka może być język ciągłych zapytań CQL lub język SQL wyposażony w możliwość przetwarzania sekwencji danych AQuery. 4 Systemy bazodanowe używające SQL DB2 Pochodzenie DB2 Doświadczenia firmy IBM związane z bazami danych sięgają początku ich istnienia. To właśnie pracownicy IBM opracowali podstawy relacyjnych baz danych oraz język SQL, a baza danych IBM DB2 uznawana jest za pierwszą komercyjną implementację relacyjnej bazy danych. Relacyjne bazy danych były rozwiajane w IBM w ramach projektów z rodziny System R. W roku 1982 rozwiązanie o nazwie SQL/DSTM zostało zintegrowane w ramach systemu serwerowego SYSTEM/38. Następnie w roku 1983 wyodrębnił się formalnie projekt ochrzczony nazwą DB2 na systemie MVSTM - pierwotnie określany mianem DATABASE 2. Aktualnie z DB2 Universal Database korzysta ponad 60 milionów użytkowników w ponad 425 000 firmach na całym świecie. Cechy bazy danych IBM DB2 DB2 to pierwsza baza ze wsparciem dla języka Java DB2 to pierwsza na świecie baza certyfikowana na Windows 2000 DB2 posiada silne wsparcie dla systemów Linux, także 64-bitowych DB2 to pierwsza baza z optymalizatorem kosztowym (rozwijanym od ponad 20 lat) DB2 to pierwsza baza z przepisywaniem SQL do optymalnej postaci DB2 to pierwsza baza relacyjna pozwalająca na obiektowe rozszerzenia DB2 jest dostępna na wszystkie wiodące platformy sprzętowe o AIX (32, 64 bit) o Solaris UltraSparc (32, 64 bit) o HP-UX oparte na HP PA-RISC (32, 64 bit) o HP-UX oparte na Intel Itanium (32, 64 bit) o iSeries (OS/400) o zSeries (OS/390 oraz z/OS) o GNU/Linux 32, 64 bit na platformach Intel, pSeries, iSeries oraz zSeries (S/390) o Microsoft Windows 32 bit (Intel+AMD) o Microsoft Windows 64 bit oparte na Intel Intanium i AMD Athlon/Opteron DB2 posiada możliwości auto-konfiguracji i samo-zarządzania DB2 Posiada pełne wsparcie dla istniejących przemysłowych standardów tworzenia aplikacji, w tym również w szczególności możliwości tworzenia procedur składowanych w języku Java, C, C++, C# i środowisku .NET. 5 Cechy funkcjonalne DB2 Optymalizator zapytań DB2 - LEO (ang. Learing Optimizer) wybiera najwydajniejszą strategię realizacji zapytań w oparciu o doświadczenia z przeszłości. Optymalizator LEO uwzględnia fizyczne aspekty instalacji DB2 (ilość i wydajność procesorów, pamięć operacyjną dostępną dla bazy, wydajność dysków) oraz zgromadzone wcześniej informacje o samych danych, tzw. statystyki. Statystyki określają zakres informacji o danych, jakimi powinna dysponować baza, by najefektywniej obsłużyć wykonywane zapytania SQL. Optymalizator DB2 może zostać wprowadzony w tryb uczenia się, który pozwoli samoczynnie przygotować profile statystyk na podstawie danego obciążenia. Dzięki tej funkcjonalności znacząco może być skrócony czas strojenia systemu, ale także baza może elastycznie dostosować się do późniejszych zmian w aplikacji oraz właściwie zareagować na znaczny przyrost danych. Optymalizator DB2 wykorzystuje wiele opatentowanych algorytmów pozwalających na przepisywanie złożonych zapytań do optymalnej postaci (np. uwzględnienie więzów spójności w filtracji warunków zapytania, wykorzystanie tabel zawierających częściowo przetworzone wyniki zapytania). Optymalizator zapytań DB2 wybiega znacznie poza możliwość konkurencyjnych baz. Pozwala nie tylko optymalizować zapytania skierowane do bazy DB2, ale także rozproszone zapytania z wykorzystaniem innych systemów baz danych (np. Oracle, MsSQL, itd.). Tak jak pokazano na poniższym rysunku tabele innych systemów baz danych mogą być obsługiwane jak lokalne tabele DB2. DB2 gromadzi w tzw. globalnym katalogu informacje o zdalnych tabelach i podczas optymalizacji bierze pod uwagę także aspekty zdalnej bazy (np. indeksy założone na tabeli, wielkość tabel, wydajność zdalnej bazy, buforowanie zdalnych obiektów). Do innych unikalnych funkcjonalności można także zaliczyć: Wielowymiarowe klastrowanie danych (ang. Multidimensional Clustering) pozwalające na fizyczną organizację danych na dysku, zgodnie ze zdefiniowanymi kombinacjami pól Budowanie rozwiązań klastrowych w architekturze „Shared-nothing” z możliwością dołączania do 1000 klastrów (ADTmag.com, „DB2 for Linux Clustering scales to 1000 nodes”) Rozwiązania wysokiej dostępności bazy danych z przełączaniem się na serwer zapasowy bez utraty połączenia do bazy danych (HADR) Zintegrowane mechanizmy replikacji transakcji (także dwukierunkowej) z wykorzystaniem kolejki komunikatów WebSphere MQ Połączenie autonomicznych cech samo-zarządzania bazy z możliwością pełnej kontroli administratora: o pamięć może być dynamicznie alokowana, przy czym administrator może narzucić określone ograniczenia, co do maksymalnej wielkości zaalokowanej pamięci dla odseparowania obciążenia o dla wybranych tabel administrator może zdefiniować dowolną liczbę puli buforów bądź pozostawić jedną i zdać się na optymalizację bazy 6 w każdym momencie administrator może dynamicznie obniżyć priorytet działających operacji administracyjnych, także tych wyzwalanych automatycznie. o Firebird Relacyjna baza danych na licencji MPL, rozwijana na podstawie uwolnionego kodu InterBase SQL 6.0. Przez pewien czas także nazwa przeglądarki internetowej, nazwanej ostatecznie Mozilla Firefox. InterBase SQL InterBase SQL firmy Inprise (Borland) jest darmowym systemem relacyjnych baz danych, w którym została zaimplementowana pełna składnia języka SQL. Jest to w pełni profesjonalny i łatwy w obsłudze i administrowaniu system, dostępny dla środowisk Microsoft Windows, Solaris i Linux. Po otwarciu kodu źródłowego na jego podstawie powstał niezależny projekt bazy danych na licencji MPL o nazwie Firebird. MaxDB znana jako SAP DB SAP jest prostym w obsłudze słownikiem polsko-angielskim/angielsko-polskim autorstwa Bohdana R. Rau oraz Daniela Mealha Cabrita. Stworzony pierwotnie dla systemów operacyjnych z rodziny Unix, obecnie dostępny jest także dla platform Windows oraz Amiga. Program działa w trybie konsoli tekstowej. Microsoft Access Microsoft Access - system obsługi relacyjnych baz danych wchodzący w skład pakietu biurowego Microsoft Office dla środowiska Windows. Umożliwia szybko stworzyć gotową aplikacje zawartą w jednym pliku wykonywalnym. Do przykładowych zastosowań można zaliczyć analizę danych i aplikacje dla średniego biznesu. Access można również wykorzystać do szybkiego planowania bazodanowych aplikacji. Cechy MS Access W obecnej wersji (MS Access 2003) Access ma następujące ograniczenia: maksymalny rozmiar bazy danych to 2 GiB (w tej przestrzeni muszą się również zmieścić obiekty systemowe, np. indeksy), maksymalna liczba obiektów w bazie: 32 768, 7 maksymalna liczba jednoczesnych użytkowników: 255 (w praktyce dużo mniej), maksymalna liczba pól w tabeli: 255, maksymalny rozmiar tabeli: 2 GiB (wraz z obiektami systemowymi) Poza tym, Microsoft Access zawiera wbudowany interpreter VBA (ang. Visual Basic for Applications). MySQL MySQL to obok PostgreSQL najpopularniejszy z wolnodostępnych silników relacyjnych baz danych. W odróżnieniu jednak od rozwijanego przez społeczność open-source PostgreSQL-a, MySQL tworzony jest przez pojedynczy podmiot szwedzką firmę MySQL AB. Wady i zalety MySQL MySQL był pisany raczej z myślą o szybkości, niż kompatybilności ze standardem SQL – przez dłuższy czas MySQL nie obsługiwał nawet transakcji, co było zresztą głównym argumentem przeciwników tego silnika bazodanowego (najczęściej zwolenników PostgreSQL) – w nowszych wersjach (>=4) jest jednak zaimplementowana większość istotnych funkcji, a z każdą nowszą wersją, wsparcie SQL staje się coraz bardziej kompletne. Cieszy się natomiast opinią jednego z szybszych serwerów bazodanowych, dzięki czemu znakomicie nadaje się jako serwer dla często odwiedzanych witryn WWW. Platformy dla których dostępny jest MySQL Serwer dostępny jest dla właściwie wszystkich popularnych platform i różnorakich architektur, a także w wersji źródłowej, umożliwiającej skompilowanie go dla innej, normalnie nie wspieranej platformy. Oficjalnie oferowane są wersje binarne dla następujących platform i architektur (MySQL 4.1): Linux (x86, S/390, IA64 (Itanium), Alpha, PowerPC, AMD64 / EM64T), Windows (x86), Solaris (SPARC, x86), FreeBSD (x86), MacOS X, HP-UX (PA-RISC, IA64) AIX (RS6000) QNX (x86), Novell Netware (x86), SGI, DEC OSF. 8 Według informacji z dokumentacji serwera, MySQL można bez problemu skompilować również dla platform: Amiga, BSDI, Digital Unix, NetBSD, OpenBSD, OS/2 Warp, SCO OpenServer, SCO UnixWare, SunOS, Tru64 Unix. Podobnie ma się sprawa z bibliotekami klienckimi MySQL, umożliwiającymi korzystanie z tego serwera bazodanowego z poziomu aplikacji. Dostępne są również dla wielu platform i języków programowania - m. in. dla C, C++, Delphi, czy PHP. Rodzaje obsługiwanych tabel MySQL oferuje wiele różnych typów tabel, z których każdy nadaje się do innego zastosowania. Są to między innymi: MyISAM – domyślny, nie obsługuje transakcji, HEAP – najszybszy, gdyż wszystko jest przechowywane wyłącznie w pamięci RAM. Posiada jednak kilka ograniczeń, między innymi nie przechowuje danych po wyłączeniu serwera MySQL, InnoDB – obsługuje transakcje, BerkeleyDB – obsługuje transakcje, jak dotychczas nie w pełni zintegrowany z MySQL. Licencjonowanie MySQL jest dostępny na licencji GPL, jednakże można nabyć również wersje z licencjami zamkniętymi. Zastosowanie Wraz z serwerem Apache i parserem PHP zaimplementowanymi na platformie Linux stanowi popularne środowisko serwerowe – LAMP. PostgreSQL PostgreSQL to, obok MySQL, jeden z dwóch najpopularniejszych wolnodostępnych systemów zarządzania relacyjnymi bazami danych. Początkowo opracowywany na Uniwersytecie Kalifornijskim Berkeley i opublikowany pod nazwą Postgres. W miarę rozwoju i zwiększania funkcjonalności, baza danych otrzymała nazwy Postgres95 i ostatecznie PostgreSQL, aby upamiętnić pierwowzór oraz zaznaczyć zgodność ze standardem SQL. PostgreSQL zalicza się do baz typu RDBMS, z rozszerzeniami obiektowymi. Ponadto w samej bazie można umieścić krótkie procedury w jednym z wybranych języków programowania (pgSQL, Java, Perl, Python, C, R, ...). Silnik ten zawiera wiele obiektowych rozszerzeń takich jak możliwość definiowania nowych typów podstawowych, nowych operatorów i dziedziczenia typów tablic. Posiada mechanizm wyzwalaczy, zaawansowany system transakcji, możliwość dodawania funkcjonalności dzięki modułom zawartym w contribie. 9 Jednym z pierwszorzędnych celów twórców PostgreSQL jest jak największa zgodność ze standardem SQL. PostgreSQL jest dostępny na wiele platform, m.in. Linux i Windows. Od 19 stycznia 2005 aktualną wersją jest 8.0 PostgreSQL jest dostępny na licencji BSD. SQLite SQLite - to baza danych/biblioteka C implementująca silnik (ang. engine) SQL (ang. Structured Query Language). Została stworzona przez Richard'a Hipp'a i jest dostępna na licencji public domain. Projekt został rozpoczęty w roku 2000. Biblioteka implementuje silnik SQL, która daje możliwość używania bazy danych bez konieczności uruchamiania osobnego procesu RDBMS, co w wielu zastosowaniach jest najpraktyczniejszym rozwiązaniem. SQLite posiada również API do innych niż C języków programowania, a mianowicie do języka: Perl, PHP, Ruby, C++, Python, Java, Tcl, Visual Basic, .NET i wiele innych; a także interfejs shellowy. Baza może łączyć sie przez ODBC. Zawartość bazy danych przetrzymywana jest w jednym pliku (do 2 TB).Baza SQLite jest utrzymywana na dysku przy użyciu drzew binarnych (ang. B-Tree). Osobne drzewo jest używane dla każdej z tabel i każdego z indeksów. SQLite udostępnia transakcje ACID oraz większość standardu SQL 92. SQLite jest często wykorzystywany w większych aplikacjach, takich jak Kexi. Bazy danych zapisywane są jako pliki binarne. Ich bezpieczeństwo jest oparte na zabezpieczeniach oferowanych przez używany system plików. Istnieje też projekt oferujący szyfrowanie baz danych SQlite na bieżąco. SQLite ma kilka ciekawych rozwiązań takich jak: Obsługa zapytań zagnieżdżonych Obsługa widoków Obsługa transakcji Obsługa triggerów (niepełna) Możliwość definiowania własnych funkcji Należy zaznaczyć że niektórych z nich brakuje nawet w tak rozbudowanych serwerach baz danych jak MySQL. Inne mniej istotne systemy bazodanowe: Sybase SQL/DS mSQL OpenLink Virtuoso ( Oracle Oracle Rdb Microsoft SQL Server Mimer SQL 10 First SQL Ingres Informix Caché Computer Associates Ingres 11