SQLite

SQLite

Informacja
Opracowany przez D. Richard Hipp
Pierwsza wersja Sierpień 2000
Ostatnia wersja 3.36.0 (18 czerwca 2021)
Kaucja www.sqlite.org/src
Napisane w VS
System operacyjny Wieloplatformowy
Czytaj formaty Format pliku bazy danych SQLite ( d ) , baza danych SQLite 3.x ( d ) i dziennik rollbak SQLite ( d )
Pisemne formaty Format pliku bazy danych SQLite ( d ) , baza danych SQLite 3.x ( d ) , skompresowana baza danych SQLite Zipvfs ( d ) i dziennik rollbak SQLite ( d )
Rodzaj Wbudowany system zarządzania bazą danych ( d )
Licencja Domena publiczna
Stronie internetowej sqlite.org

SQLite (wymawiane [ ɛs.ky.ɛl.ajt ]) to biblioteka napisana w języku C, która oferuje silnik języka SQL dostępnegodla relacyjnych baz danych . SQLite w dużej mierze implementuje standard SQL-92 i właściwości ACID .

W przeciwieństwie do tradycyjnych serwerów baz danych, takich jak MySQL czy PostgreSQL , jego cechą szczególną nie jest odtworzenie zwykłego schematu klient-serwer , ale bezpośrednie zintegrowanie z programami . Cała baza danych (deklaracje, tabele, indeks i dane) jest przechowywana w pliku niezależnym od platformy .

D. Richard Hipp , twórca SQLite, zdecydował się umieścić tę bibliotekę i jej kod źródłowy w domenie publicznej , co pozwala na jej nieograniczone wykorzystanie zarówno w projektach open source, jak i zastrzeżonych . Twórca i niektórzy z głównych programistów SQLite są zatrudnieni przez amerykańską firmę Hwaci .

SQLite jest najczęściej używanym silnikiem baz danych na świecie, dzięki zastosowaniu:

Ze względu na swoją ekstremalną lekkość (mniej niż 600 KiB ), jest również bardzo popularny w systemach wbudowanych , zwłaszcza na większości nowoczesnych smartfonów i tabletów : mobilne systemy operacyjne iOS , Android i Symbian używają go jako bazy danych. W sumie możemy policzyć ponad miliard znanych i zgłoszonych egzemplarzy biblioteki.

Historyczny

D. Richard Hipp i jego kolega zaczęli projektować SQLite na początku 2000 roku , pracując w General Dynamics , a następnie na podstawie kontraktu z US Navy . SQLite miał być używany w kierowanych pociskach rakietowych , w celu zastąpienia baz danych IBM Informix działających na maszynach HP-UX . Głównym celem było to, aby móc obejść się bez instalacji lub administracji: instalacja lub aktualizacja bazy danych może zająć cały dzień.

W sierpniu 2000 została wydana pierwsza wersja SQLite. Używała gdbm ( GNU Menedżer bazy danych) do manipulowania B Drzewa .

SQLite 2.0 usuwa zależność od gdbm i dodaje obsługę transakcji.

SQLite 3.0, wyprodukowany przy pomocy AOL , został wydany w 2004 roku i dodaje między innymi regionalizację (z obsługą sortowania i Unicode ) oraz deklarację typów.

Charakterystyka

Wbudowana baza danych

Architektura SQLite French.svg

Większość systemów zarządzania bazami danych jest zbudowana zgodnie z paradygmatem klient-serwer , tzn. biblioteka oprogramowania klienckiego jest zintegrowana i używana w jednej lub kilku aplikacjach podczas pracy silnika bazy danych we własnej przestrzeni wykonawczej lub nawet na innej maszynie, jako dział IT .

Natomiast SQLite jest bezpośrednio zintegrowany z aplikacją, która korzysta z jego biblioteki oprogramowania z silnikiem bazy danych. Dostęp do bazy danych za pomocą SQLite odbywa się poprzez otwarcie odpowiadającego jej pliku: każda baza danych jest zapisywana w specyficznym dla niej pliku, z jej deklaracjami, tabelami i indeksami, ale także danymi.

Ta cecha sprawia, że ​​SQLite jest interesujący jako alternatywa dla plików tekstowych, używany jako środek zintegrowanego przechowywania w wielu aplikacjach ( parametry , historia , pamięć podręczna ...), ponieważ sprawia, że ​​dostęp do danych jest szybszy, bezpieczniejszy, bardziej ustrukturyzowany, łatwiejszy i całkowicie niezależne od platformy , jednocześnie nie wpływając na łatwość wdrożenia aplikacji, która z niej korzysta.

Usunięcie pośrednika między aplikacją a danymi również nieznacznie zmniejsza opóźnienie dostępu do danych w porównaniu z systemami wykorzystującymi paradygmat klient-serwer.

Jednak ta architektura stwarza kilka problemów:

Nie ma określonego rozszerzenia dla plików baz danych SQLite, ale często spotyka się rozszerzenia takie jak .sqlite lub .db , po których czasami następuje numer wersji biblioteki ( .sqlite3 , .db2 , itp.). Możliwe jest korzystanie z bazy danych zapisanej tylko w pamięci RAM bez tworzenia pliku bazy danych na dysku, poprzez specjalną nazwę pliku : memory: .

Ogólnie rzecz biorąc, zaleca się używanie SQLite tam, gdzie dane nie są scentralizowane i gdzie zwiększenie rozmiaru bazy danych nie będzie miało większego znaczenia. Jeśli celem bazy danych jest scentralizowanie dużej masy danych i dostarczenie jej do dużej liczby klientów, preferowane jest stosowanie DBMS opartych na paradygmacie klient-serwer. SQLite ma zastąpić pliki tekstowe, a nie tradycyjne serwery baz danych.

Kompilator i maszyna wirtualna

Architektura wewnętrzna SQLite French.svg

Kiedy zapytanie SQL jest przekazywane do SQLite przez interfejs programowania , jest kompilowane przed wykonaniem.

Sekwencer kompilatora dzieli polecenia na części, które mogą być przetwarzane oddzielnie (na przykład zapytanie i jego podzapytanie), które są przekazywane do parsera, który zajmuje się rozbiciem zapytań na różne obiekty reprezentujące różne porządki. klauzule języka SQL. Obiekty te są przekazywane do generatora kodu, który tworzy kod pośredni niskiego poziomu, czyli bytecode .

Wynikowy kod to zestaw instrukcji (137 różnych instrukcji) zwanych OpCodes . Jest to uruchamiane na maszynie wirtualnej SQLite, która postrzega je jako małe programy opisujące operacje wyszukiwania, odczytu i modyfikacji danych.

Gdy maszyna wirtualna interpretuje te instrukcje, zadzwoniła do kierownika B-drzewa w oparciu o warstwy niższego poziomu, który ukrywa się stron płyty i warstwy abstrakcji sprzętu .

Zarządzanie prawami

SQLite nie integruje zarządzania prawami dostępu i modyfikacją danych. Zarządzanie odbywa się przez system plików w systemie operacyjnym  : jeśli plik zawierający bazę danych, nie ma prawa zapisu dla użytkownika, użytkownik będzie również w stanie modyfikować rekordy i podstawową strukturę danych.

Zarządzanie prawami za pomocą GRANT i REVOKE nie istnieje, chociaż są one częścią specyfikacji SQL-92 .

Korzystanie z bazy danych SQLite nie wymaga żadnej procedury instalacyjnej ani konfiguracyjnej.

Ruchliwość

Biblioteka jest w całości napisana w C-ANSI , standardowej wersji języka programowania C i nie używa żadnych zewnętrznych bibliotek innych niż standardowa biblioteka językowa . To sprawia, że ​​SQLite jest kompilowalny bez większych modyfikacji na wszystkich architekturach komputerowych, zapewniając kompilator C zgodny ze standardem ANSI.

Pliki bazy danych SQLite są całkowicie niezależne od systemu operacyjnego i architektury, na której są używane. Ten sam plik bazy danych może być używany na dwóch architekturach o radykalnie odmiennym działaniu, SQLite zapewnia deweloperowi przezroczystą warstwę abstrakcji . Pliki są kompatybilne ze sobą dla każdej głównej wersji biblioteki od wersji 3.0.0 SQLite, więc plik utworzony w wersji 3.0.0 będzie dostępny w wersji 3.6.19 i na odwrót, pliki utworzone między dwoma różnymi wersjami głównymi ( na przykład 2.0.0 i 3.0.0 ) mogą być kompatybilne (szczególnie w przypadku kompatybilności wstecznej), ale nie zawsze tak jest.

Typy danych

SQLite używa dynamicznego typowania dla zawartości komórek, w przeciwieństwie do prawie wszystkich DBMS, które używają typowania statycznego  : podczas tworzenia nowej tabeli w bazie danych jest to zalecany lub nie wymuszany typ powinowactwa danych, które mają być przechowywane w wypełnianej kolumnie a nie typ, który definiuje sposób, w jaki będzie to reprezentowane w pamięci, zadanie to jest zarezerwowane dla samej komórki. Kiedy dane zostaną wprowadzone do bazy danych, SQLite spróbuje przekonwertować nowe dane na zalecany typ, ale nie zrobi tego, jeśli nie będzie to możliwe.

Istnieje kilka typów powinowactwa w SQLite, które definiują sposób działania SQLite podczas wprowadzania nowych danych:

W ten sposób każdy typ powinowactwa może akceptować dowolny typ danych, jedynym wyjątkiem jest konkretny typ INTEGER PRIMARY KEY , gdy jest stosowany do pojedynczej kolumny, ponieważ nie jest to typowy typ, ale od aliasu do wewnętrznej kolumny do Silnik ROWID odpowiadający adresowi rekordu, unikalny w całej tabeli.

Zastosowanie dynamicznego typowania poprawia jednorodność między danymi w bazie danych a typami języka używanego do zapytania, jeśli ten ostatni jest również językiem dynamicznie typowanym (takim jak Python , PHP , Perl lub Ruby ) bez stwarzania realnych problemów z języki wykorzystujące typowanie statyczne (np. C / C++ lub Java ).

Określenie rodzaju powinowactwa

Aby zachować zgodność z innymi relacyjnymi bazami danych , SQLite automatycznie konwertuje nazwy zadeklarowanych typów na najlepiej pasujący typ powinowactwa w następujący sposób:

  • wszystkie nazwy typów zawierające słowo kluczowe INT będą rozpoznawane jako pola typu INTEGER . Jednak tylko instrukcja INTEGER PRIMARY KEY będzie rozpoznawana jako alias ROWID  ;
  • wszystkie nazwy typów zawierające jedno z następujących słów kluczowych: CHAR (w tym VARCHAR ), CLOB lub TEXT będą rozpoznawane jako pola TEXT  ;
  • wszystkie nazwy typów zawierające słowo kluczowe BLOB będą rozpoznawane jako pola z powinowactwem NONE  ;
  • wszystkie nazwy typów zawierające jedno z następujących słów kluczowych: REAL , FLOAT lub DOUBLE będą rozpoznawane jako pola REAL  ;
  • we wszystkich innych przypadkach lub jeśli typ nie zostanie określony, zostanie użyte powinowactwo NUMERYCZNE .

Chociaż SQLite używa dynamicznego typowania, reprezentacja w pamięci i przetwarzanie danych wymaga użycia różnych klas pamięci. Dotyczy to tylko wersji 3 i jej nowszych wersji, ponieważ dane zostały zapisane jako ciągi we wcześniejszych wersjach.

Wszystkie dane manipulowane przez Aparat baz danych używa jednego z następujących typów:

  • NULL  : dane odpowiadają specjalnemu typowi NULL , który wskazuje na brak informacji lub niezdefiniowaną wartość;
  • INTEGER  : dane są liczbą całkowitą ze znakiem i ta jest zapisywana, zgodnie z jej rzędem wielkości, na 1, 2, 3, 4, 6 lub 8 bajtach , ale w pamięci jest konwertowana na 8 bajtów (8 bajtów ze znakiem liczba całkowita);
  • REAL  : dane to liczba zmiennoprzecinkowa zapisana na 8 bajtach zgodnie ze standardem IEEE  ;
  • TEKST  : dane to ciąg znaków zakodowany w UTF-8 (domyślnie), UTF-16-BE lub UTF-16-LE  ;
  • BLOB  : dane są zapisywane tak, jak zostały podane.
Typ NULL

Standard nie definiuje dokładnie, jak powinien być traktowany typ NULL .

Podobnie jak w przypadku większości relacyjnych baz danych, wszystkie rekordy NULL są uznawane za odrębne przez ograniczenie UNIQUE , ale są uważane za identyczne przez operator UNION i słowo kluczowe DISTINCT .

Operacje arytmetyczne, które zawierają w wyrażeniu typ NULL, zwracają UNKNOWN (wartość niezdefiniowana). W operacjach logicznych wartość zwracana może być UNKNOWN, jeśli wystąpi typ NULL, a wyniku nie można określić z pewnością: NULL OR 1 da wartość 1 , ale NULL OR 0 da wartość UNKNOWN, ponieważ operacji nie można rozstrzygnąć z pewnością .

Daktyle

SQLite nie ma typu do reprezentowania dat. Istnieje jednak zestaw funkcji do manipulowania nimi. Przechowywanie daty może być wykonane w ciągu znaków w postaci ISO 8601 lub w postaci liczby całkowitej w postaci znacznika czasu UNIX .

Ograniczenia

SQLite zarządza ograniczeniami w jednej lub kilku kolumnach. Ograniczenia NOT NULL , CHECK , DEFAULT i COLLATE są zadeklarowane w kolumnie, podczas gdy ograniczenia PRIMARY KEY , UNIQUE , CHECK i FOREIGN KEY można zadeklarować w jednej lub kilku kolumnach.

Ograniczenie UNIQUE automatycznie tworzy indeks w kolumnie (kolumnach), do której jest stosowane.

KLUCZ PODSTAWOWY

Kluczem podstawowym ograniczeniem stworzy UNIQUE ograniczenie na kolumnie dotkniętego (S), jednak w odróżnieniu od standardu , SQLite za PRIMARY KEY ograniczenie pozwala wpisy, które są NULL . Jest to niezgodność ze standardem i to odchylenie może zostać rozwiązane w przyszłych wersjach. Dlatego zaleca się dodanie ograniczenia NOT NULL do deklaracji klucza podstawowego.

ROWID i AUTOINCREMENT

Każdy wiersz w tabeli jest identyfikowany przez 64-bitową liczbę całkowitą ze znakiem o nazwie ROWID . Gdy tabela jest zadeklarowana z jedną i tylko jedną kolumną INTEGER PRIMARY KEY , ta kolumna staje się aliasem ROWID . Użycie aliasu z identyfikatorem ROWID zwiększa szybkość wyszukiwania, która może być nawet dwukrotnie większa niż w przypadku normalnego klucza podstawowego powiązanego z jego indeksem unikalności.

Gdy tabela jest pusta, algorytm przypisuje wartość 1 do identyfikatora, który zwiększa dla każdego nowego rekordu, aż do osiągnięcia limitu 64-bitowej liczby całkowitej ze znakiem ( ). Po osiągnięciu tego limitu ponownie wykorzysta miejsca zwolnione przez usunięte rekordy. Przydział identyfikatorów nie jest więc już przyrostowy, lecz losowy.

Możliwe jest użycie słowa kluczowego AUTOINCREMENT . Ten ostatni modyfikuje nieco algorytm: po osiągnięciu limitu liczby całkowitej nie będzie już możliwości wstawienia nowego rekordu. Dzięki temu można zagwarantować, że ten sam identyfikator nigdy nie będzie przechowywany w dwóch odrębnych rekordach, nawet jeśli nie współistnieją one w tym samym czasie.

KLUCZ OBCY

Od wersji 3.6.19 SQLite jest w stanie zarządzać ograniczeniami klucza obcego .

Ze względu na zgodność z poprzednimi wersjami obsługa kluczy obcych nie jest domyślnie włączona. Aktywacji dokonuje pragma kluczy_obcych .

Każda kolumna, do której odwołuje się klucz obcy, musi być zadeklarowana jako UNIQUE ( klucz podstawowy tworzy klucz unikalny ). SQLite nie uwzględnia jeszcze klauzuli MATCH w definicji kluczy obcych.

Wyzwalacze

SQLite zarządza wyzwalaczami w dość kompletny sposób. Wyzwalacze mogą być zgłaszane PRZED , PO lub ZAMIAST . SQLite obsługuje opcję FOR EACH ROW (operacja domyślna), ale nie FOR EACH STATEMENT .

Wyświetlenia

SQLite umożliwia tworzenie widoków w celu skrócenia długości zapytań.

Widoki są tylko do odczytu, ale można użyć wyzwalaczy z właściwością INSTEAD OF, aby zasymulować możliwość ich modyfikowania.

Transakcje

Wszystkie polecenia SQL mające na celu zmianę stanu bazy danych (w zasadzie każde inne polecenie niż SELECT ) wiążą się z utworzeniem dedykowanej dla nich transakcji , o ile transakcja zawierająca dane polecenie nie została jeszcze utworzona. Oznacza to, że wszystkie polecenia są atomowe . Jeśli wykonanie polecenia nie powoduje błędu, modyfikacja jest automatycznie zatwierdzana ( autocommit ), ale jeśli tak nie jest, wszystkie modyfikacje wprowadzone przez polecenie są anulowane.

Wszystkie modyfikacje bazy danych są serializowane: tylko jedna modyfikacja jest wykonywana na raz, a baza danych jest zablokowana do odczytu podczas modyfikacji.

SQLite umożliwia tworzenie transakcji jak również tworzenie punktów zwrotu ( SAVEPOINT ), ale nie pozwala na zarządzanie różnymi stopniami izolacji. W transakcji, podczas pierwszego wywołania polecenia odczytu, aktywowana jest blokada współdzielona, ​​która autoryzuje dostęp do odczytu, ale uniemożliwia jakąkolwiek modyfikację danych przez inną transakcję, podczas pierwszego wywołania zapisu cała baza danych jest zablokowana do odczytu i zapisu dla innych transakcji .

KWAS

Nawet jeśli SQLite na pierwszy rzut oka respektuje zestaw właściwości ACID , które decydują o niezawodności systemu transakcyjnego, nadal można wprowadzić bazę danych w stan niespójny, ponieważ typy nie są wymuszone: można np. wstawić ciąg znaków w kolumnie powinowactwa z którego typ jest zdefiniowany jako liczba całkowita . W swoich ścisłych interpretacjach SQLite nie respektuje zestawu właściwości ACID.

Stoły tymczasowe

SQLite umożliwia tworzenie tabel tymczasowych, których definicja, dane i indeksy nie są zapisywane w pliku bazy danych i dlatego są tracone po zamknięciu bazy danych.

Wirtualne stoły

Możliwe jest stworzenie bezpośrednio z biblioteki własnego silnika pamięci masowej do symulacji tabeli bazy danych. Tworzenie wirtualnej tabeli odbywa się poprzez implementację zestawu funkcji. Dostęp do tabeli jest całkowicie transparentny, poza brakiem pewnych funkcjonalności (niemożliwe jest tworzenie wyzwalaczy lub indeksów lub modyfikowanie struktury tabeli).

Mechanizm ten umożliwia dostęp za pomocą języka SQL do dowolnego źródła danych, takiego jak pliki CSV lub XML .

Funkcje użytkownika

SQLite oferuje interfejs programistyczny, poprzez swoją bibliotekę, do tworzenia funkcji użytkownika. Zestaw funkcji zdefiniowanych przez bibliotekę można przeciążyć , aby przedefiniować ich implementację. Niektóre operatory, takie jak LIKE, używają tytułowych funkcji jako warstwy podrzędnej, którą można również zastąpić funkcjami zdefiniowanymi przez użytkownika.

SQLite nie obsługuje tworzenia procedur , ale ich zapotrzebowanie jest mniejsze ze względu na wbudowaną architekturę.

Indeks

SQLite umożliwia tworzenie indeksów na jednej lub kilku kolumnach. Indeksy mogą być rosnące ( ASC ) lub malejące ( DESC ), a także unikalne (jest to podobne do tworzenia ograniczenia unikalności). SQLite używa swojego indeksu B-tree .

SQLite wprowadza słowo kluczowe EXPLAIN, które jest używane do opisania kroków wymaganych do wykonania polecenia oraz użytych indeksów.

Pragmas

Pragmy to pary klucz/wartość konfiguracji SQLite. Są one wewnętrznymi elementami bazy danych i pozwalają opisać, jak SQLite powinien interpretować określone operacje. Umożliwiają również aktywację lub dezaktywację niektórych funkcji, w szczególności ze względu na kompatybilność wsteczną.

Przyjęcie

Oprócz oficjalnej implementacji w C , istnieją powiązania dla innych języków ( C++ , Perl , Ruby , TCL , języki korzystające z frameworka .NET za pośrednictwem sterownika ADO.NET ...).

Niektóre języki programowania zawierają SQLite w swojej standardowej bibliotece , na przykład Python (od wersji 2.5) i PHP (od wersji 5).

SQLite jest używany w wielu darmowych programach, takich jak Mozilla Firefox , w wielu dystrybucjach GNU/Linux , w systemach operacyjnych dla serwerów i komputerów stacjonarnych , takich jak Solaris lub urządzenia mobilne, takie jak Android lub Symbian , w niektórych programach Apple , Google , Adobe i McAfee, a także w niektórych urządzenia Philips .

SQLite jest również dostępny z wersją 8.4 oprogramowania Primavera P6 firmy Oracle.

Opublikowany przez W3C projekt dotyczący przechowywania bazy danych SQL po stronie przeglądarki internetowej stwierdza również, że oprogramowanie implementujące tę funkcję musi umieć poprawnie interpretować dialekt SQLite w wersji 3.6.19 . Chociaż SQLite nie jest egzekwowany przez W3C, Google Chrome , Apple Safari i Opera Browser używają go do tego celu.

Różne wersje

SQLite istnieje w 2 głównych wersjach: 2.xi 3.x. Wersje SQLite 2 i 3 wyróżniają się kilkoma ewolucjami:

  • pliki bazy danych nie zawsze są ze sobą kompatybilne. Oznacza to, że baza danych w formacie SQLite 2 nie może być z pewnością odczytana przez SQLite 3 i odwrotnie  ;
  • Składnia SQL nie występuje w SQLite 2: IF NOT EXISTS dla zapytań oraz CREATE TABLE , ADD COLUMN i RENAME COLUMN dla zapytań ALTER TABLE  ;
  • tylko najnowsze wersje SQLite obsługują pewne bardziej zaawansowane funkcje, takie jak zarządzanie kluczami obcymi lub ograniczenia CHECK  ;
  • SQLite 3 obsługuje standardy UTF-8 i UTF-16  ;
  • SQLite 3 koduje identyfikatory wierszy na 64 bitach, a nie na 32 bitach , co pozwala na prawie nieograniczoną liczbę wierszy;
  • PHP używa klasy PDO lub, w PHP 5.3, funkcji sqlite3 _ * () do obsługi SQLite 3, podczas gdy używa funkcji sqlite _ * () dla SQLite 2.

Uwagi i referencje

  1. „  SQLite Release 3.36.0 18.06.2021  ” (dostęp 18 czerwca 2021 r. )
  2. „  Prawa autorskie SQLite  ” , na www.sqlite.org
  3. „  O SQLite  ” , na www.sqlite.org
  4. „  Dobrze znani użytkownicy SQLite  ” , na stronie www.sqlite.org
  5. „  Najbardziej wdrożony silnik bazy danych SQL  ” , na stronie www.sqlite.org
  6. (w) Michael Owens , The Definitive Guide to SQLite , Berkeley, Apress,2006( ISBN  978-1-59059-673-9 , DOI  10.1007 / 978-1-4302-0172-4_1 )
  7. „  The SQLite Bytecode Engine  ” , na stronie www.sqlite.org
  8. „  Wirtualny silnik bazy danych SQLite  ” , na stronie www.sqlite.org
  9. „  Architektura SQLite  ” , na www.sqlite.org
  10. "  Funkcje SQL, których SQLite nie implementuje  " , na www.sqlite.org
  11. „  Konfiguracja zerowa  ” na stronie www.sqlite.org
  12. „  SQLite to samodzielny system  ” , na stronie www.sqlite.org
  13. „  SQLite: baza danych pojedynczego pliku  ” , na www.sqlite.org
  14. "  Typy danych w SQLite wersja 3  " , na www.sqlite.org
  15. „  Język zapytań SQLite: CREATE TABLE  ” , na www.sqlite.org
  16. „  Przegląd SQLite w wersji 3  ” , na stronie www.sqlite.org
  17. „  Obsługa NULL w SQLite  ” , na www.sqlite.org
  18. „  Język zapytań SQLite: funkcje daty i czasu  ” , na stronie www.sqlite.org
  19. „  Diagramy składni dla SQLite  ” , na www.sqlite.org
  20. „  Autoinkrementacja SQLite  ” , na stronie www.sqlite.org
  21. „  Obsługa kluczy obcych SQLite  ” , na stronie www.sqlite.org
  22. „  Język zapytań SQLite: CREATE TRIGGER  ” , na stronie www.sqlite.org
  23. „  Język zapytań SQLite: CREATE VIEW  ” , na stronie www.sqlite.org
  24. „  Język zapytań SQLite: SAVEPOINT  ” , na stronie www.sqlite.org
  25. „  Blokowanie plików i współbieżność w SQLite w wersji 3  ” , na www.sqlite.org
  26. „  Język zapytań SQLite: BEGIN TRANSACTION  ” , na www.sqlite.org
  27. „  The Virtual Table Mechanism of SQLite  ” , na www.sqlite.org
  28. „  Język zapytań SQLite: podstawowe funkcje  ” , na stronie www.sqlite.org
  29. „  Język zapytań SQLite: CREATE INDEX  ” , na stronie www.sqlite.org
  30. „  Język zapytań SQLite: EXPLAIN  ” , na stronie www.sqlite.org
  31. „  Oświadczenia Pragma obsługiwane przez SQLite  ” , na stronie www.sqlite.org
  32. http://sqlite.phxsoftware.com/
  33. "  sqlite3 - interfejs DB-API 2.0 dla baz danych SQLite - dokumentacja Python 3.7.3  " , na docs.python.org
  34. „  PHP: Preprocesor hipertekstu  ” , na www.php.net
  35. „  Web SQL Database  ” na dev.w3.org
  36. „  Więcej zasobów dla programistów  ”
  37. "  WebKit HTML 5 SQL Storage Notes Demo  " , na webkit.org
  38. „  Dev.Opera - Blog  ” , na dev.opera.com

Linki zewnętrzne