![]() |
|
Programowanie:
Artykuły
FAQ
Download
Książki
WWW:
Artykuły
Narzędzia
Kursy
Darmowe
FAQ
Skrypty
Humor
Inne:
Forum
Wiki
Liczniki
Linki
Chat
Grafika
Video
Inne
|
Poznajemy SQLitew aspekcje języka PHP zorientowanego strukturalnie
Autor: y00da
Wstęp Co to jest i jak to działa ? Plusy i minusy Skąd to wziąć i jak zainstalować ? Typy danych Implementacja Tytułem zakończeniaWstępCelem tego artykułu jest przedstawienie coraz większego konkurenta MySQL a mianowicie SQLite. Postaram się w nim przybliżyć zarówno plusy jak i minusy tego rozwiązania, a także sposób implementacji w języku PHP. No to zaczynamy [; .Co to jest i jak to działa ?SQLite to biblioteka napisana w języku C#, implementująca silnik SQL. Została stworzona przez Richard'a Hipp'a i jest dostępna na licencji public domain*.Biblioteka ta daje możliwość używania bazy danych bez konieczności uruchamiana oddzielnego procesu jak to jest np. w przypadku MySQL. Zawartość bazy danych przetrzymywana jest w jednym pliku binarnym(do 2 TB wielkości). SQLite jest utrzymywany na dysku przy użyciu drzew binarnych**.Osobne drzewo jest używane dla każdej z tabel i każdego z indeksów. SQLite rozwiązuje odwieczny problem programistów przechowujących dane w plikach płaskich, a mianowicie blokowanie i dostęp współbieżny. Plusy i minusyGłównym plusem tej bazy danych jest wydajność (szczególnie przy wykonywaniu zapytań typu INSERT i SELECT), a także wieloplatformowość (baza działa na zasadzie rozszerzenia języka PHP). Niestety nie jest to rozwiązanie wolne od wad. Podczas procesu dopisywania nowych danych SQLite musi zablokować cały plik, aż do czasu zakończenia operacji. Zatem rozwiązanie to nie jest wydajne w sytuacjach gdy dane podlegają ciągłym zmianom. Drugim poważnym minusem jest brak pojęcia praw dostępu do bazy danych(znanym chociażby z MySQL'a), przez co nie możemy stworzyć "bezpiecznej" tabeli do której dostęp mieliby tylko uprawnieni użytkownicy. W skrócie oznacza to, że musimy sami stworzyć system kontroli dostępu, poprzez nadawanie praw do zapisu i odczytu odpowiednim plikom. Rozwiązanie takie nie jest wygodne.Podsumowując SQLite nie nadaje się do zastosowań na witrynach gdzie dane podlegają ciągłym zmianom, a także tam gdzie jest wymagany system kontroli dostępu. Jednak na małych i średnich stronach rozwiązanie to może okazać się naprawdę wydajne. W końcu do stworzenia tabeli z kilkunastoma rekordami nie potrzeba całego "kombajna" jakim jest niewątpliwie MySQL. Skąd to wziąć i jak zainstalować ?WindowsRozszerzenie SQLite jest standardowo dostarczane z pakietem PHP5. W pliku php.ini*** wystarczy usunąć średnik sprzed extension=php_sqlite.dll ( w systemach Windows), aby uaktywnić SQLite. W przypadku PHP4 obsługa SQLite jest zaimplementowana w wersjach od 4.3.x wzwyż. Samą bibliotekę jednak trzeba ściągnąć i zainstalować oddzielnie. Pobieramy ją z http://snaps.php.net/win32/PECL_STABLE/php_sqlite.dll a następnie kopiujemy do folderu z rozszerzeniami języka PHP. Pozostało nam już tylko w sekcji Extensions pliku php.ini dodać extension=php_sqlite.dll. Linuks W PHP5 sytuacja jest podobna do systemów Windows. Rozszerzenie powinno być dostarczone razem z pakietem PHP oznaczone numerkiem 5. Zatem w pliku php.ini szukamy slowa kluczowego php_sqlite.so, dalej postepujemy tak jak w przypadku Windows'a. Jeżeli posiadamy PHP w wersji 4 mamy do wyboru dwie opcje instalacji:
Typy danychSQLite pod tym względem jest bardzo ubogi. Wszystko w nim jest łańcuchem znaków. Dla przykładu możemy zdefiniować kolumne typu INT, jednak po wprowadzeniu do tej kolumny ciągu znaków SQLite nie zwróci żadnego błędu. Typ kolumny(nakładany podczas jej tworzenia) ma znaczenie tylko przy sortowaniu np. SQLite musi wiedzieć co będzie pierwsze 3 czy 6 ? Drugim ważnym powodem nakładania typów danych na kolumny jest przejrzystość tabeli( zawsze lepiej wiedzieć gdzie co jest [; ).ImplementacjaW poprzednich punktach poznaliśmy sposób instalacji, zasade działania, a także plusy i minusy SQLite. Czas poznać w praktyce moc SQLite.Podstawy Całość połączenia z bazą danych ogranicza się do podania scieżki dostępu do owej bazy. Odbywa się to za pomocą funkcji sqlite_open() sqlite_open('/sciezka_do_bazy_danych/books.db'); Po "połączeniu" z bazą danych nie musimy wybierać tabeli (jak to ma miejsce np. w MySQL), spowodowane jest to wcześniej wspomnianym brakiem systemu kontroli dostępu. Możemy więc od razu wysłać zapytanie do silnika SQL. sqlite_query($uchwyt_db,"Zapytanie"); Całość może wyglądać np. tak: $db = sqlite_open('/sciezka_do_bazy_danych/books.db'); sqlite_query($db,"CREATE TABLE books(autor VARCHAR(100), tytul VARCHAR(100)) "); sqlite_close($db); Wstawianie danych odbywa się za pomocą SQL'owego INSERT'a sqlite_query($uchwyt_db,"INSERT INTO books VALUES('Sienkiewicz','Krzyzacy') "); Całość dotychczasowego skryptu mogłaby wyglądać tak: $db = sqlite_open('/sciezka_do_bazy_danych/books.db'); $autor = sqlite_escape_string ($autor); $tytul = sqlite_escape_string($tytul); sqlite_query($uchwyt_db,"INSERT INTO books VALUES('$autor','$tytul') "); sqlite_close($db); Aby odczytać dane z SQLite należy wywołać funkcje sqlite_query() z instrukcją SELECT, a następnie przejść kolejno przez zwrócone przez nią wyniki. Obrazuje to poniższy przykład: $query = sqlite_query($uchwyt_db,"SELECT * FROM books"); while ($row = sqlite_fetch_array($query) { // Operacje na $row } ?> W sytuacjach gdy dużą role będzie odgrywać szybkość działania lepiej będzie użyć funkcji sqlite_array_query(), która w tym samym kroku odczyta dane i umieści je w tablicy. $table = sqlite_array_query($uchwyt_db,"SELECT * FROM books"); foreach ($table as $value) { // Operacje na $value } Standardowo funkcja sqlite_fetch_array() zwraca tablice zawierającą zarówno klucze liczbowe jak i asocjacyjne. Standardowo takie "zachowanie" tej funkcji jest na rękę programiście który zarówno może odwoływać się do danych w tablicy za pomocą kluczy liczbowych jak i asocjacyjnych. Problem jednak może powstać w przypadku zagnieżdżenia w pętli while(), pętli foreach() podczas odczytu danych jak to widać na przykładzie: $query = sqlite_query($uchwyt_db,"SELECT * FROM books"); while($row = sqlite_fetch_array($query) { foreach($row as $value) { echo $value.'<br>'; } } ?>
Jak wiadomo stosowanie indeksów jest chyba najprostszą drogą do zwiększenia wydajności skryptu, pod kątem wyszukiwania i sortowania danych pochądzących z bazy danych. Większość osób mająca styczność z inną relacyjną bazą danych np. MySQL'em zapewne wie co to są indeksy.Więc następne pare linijek może spokojnie ominąć. Podczas przeszukiwania tabeli nie zawierającej żadnych indeksów SQLite musi przeszukiwać tabele wiersz po wierszu porównując wartości. W sytuacji gdy "polom wyszukiwania" nadamy indeksy, SQLite odwoła się do właśnie takiego specjalnie stworzonego pola, dzięki któremu odnalezienie lokalizacji interesujących nas danych będzie znacznie szybsze. W przypadkach, gdy dane przechowywane w polach nie mogą się powtarzać(np. PESEL, ID), możemy oznaczyć je jako unikatowe. SQLite, oprócz tego, że będzie "pilnował", aby zawartość pól się niepowtarzała, sprawi także, że pole oznaczone typem UNIQUE, będzie automatycznie indeksowane. sqlite_query($uchwyt_db,"CREATE TABLE books(autor VARCHAR(100) UNIQUE, tytul VARCHAR(100)) "); sqlite_query($uchwyt_db,"CREATE INDEX books_autor_index ON books(autor)" ); Kolejnym szybkim sposobem na zwiększenie wydajności skryptu jest zastosowanie kluczy głównych. Ponownie osoby mające styczność z tym zagadnieniem mogą opuścić kilka poniższych linii. Klucz główny jest unikatowym identyfiaktorem wiersza. Pole pełniące role klucza głównego musi zawierać wartości całkowito-liczbowe . Nie musimy jednak sami nadawać wartości tym polom, ponieważ zrobi to za nas silnik SQL, np. pierwszemu wierszowi SQLite przyporządkuje wartość 1, drugiemu 2 itd .. Przejdźmy zatem do praktyki. Aby stworzyć owe identyfikatory pól musimy utworzyć kolumne typu INTEGER PRIMARY KEY. sqlite_query($uchwyt_db,"CREATE TABLE books(bookid INTEGER PRIMARY KEY , autor VARCHAR(100) , tytul VARCHAR(100) ") );
W której to wszystkie pola kolumny bookid będą spełniać role kluczy głównych. Aby SQLite wypełnił automatycznie pole oznaczone jako klucz główny podczas wstawiania danych trzeba jako wartość podać NULL. Na przykład: sqlite_query( $uchwyt_db,"INSERT INTO books VALUES(NULL,'Sienkiewicz','Krzyzacy') "); Przydatna przy okazji kluczy głównych może okazać się funkcja sqlite_insert_rowid() zwracająca wartość klucza głównego ostatnio wstawianego wiersza. Transakcje Na szczególną uwagę w SQLite zasługują transakcje, które pozwalają zwiększyć wydajność skryptu. Za każdym razem gdy wywołamy funkcje sqlite_query(), sqlite_connect() etc .. SQLite musi wykonać pare zadań(blokowanie dostępu do pliku , odczyt pliku , etc ... ) . Zamiast więc za każdym razem wywoływać funkcje, można zgrupować zapytania w jedną transakcje. Funkcja zostanie wywołana tylko raz, a co za tym idzie ograniczymy robote SQLite'owi Użycie transakcji: $sql = 'BEGIN;'; for((int)$i = 0; $i <= 100; $i++) { $sql .= "INSERT INTO books VALUES('Sienkiewicz','Krzyzacy')"; } $sql .= 'COMMIT;'; sqlite_query($uchwyt_db , $sql); sqlite_exec ($uchwyt_db, "BEGIN; CREATE TABLE books(bookid INTEGER PRIMARY KEY , autor VARCHAR(100) , tytul VARCHAR(100); INSERT INTO books VALUES(NULL,'Sienkiewicz','Krzyzacy'); INSERT INTO books VALUES(NULL,'Kaminski','Kamienie na szaniec'); INSERT INTO books VALUES(NULL,'Prus','Lalka') ; COMMIT; " ); Przechowywanie tabeli w pamięci operacyjnej SQLite posiada także przydatny mechanizm przechowywania tabeli w pamięci RAM .Z pierwszych lekcji informatyki w szkole zapewne wiecie, że pamięć RAM nie jest pamięcią stałą. Dlatego też nie można odwołać się do zapytania wykonanego np. przy poprzednim odświerzeniu strony. Takie działanie jest nieocenione w aplikacjach, które na początku ładują znaczne ilosći danych, a potem wykonują wiele zapytań. Włączenie tego mechanizmu ogranicza się jedynie do przekazania argumentu :memory: funkcji sqlite_open() czyli np. sqlite_open(':memory:'); Przykład: sqlite_open(':memory:'); sqlite_query("CREATE TABLE books(autor VARCHAR(100) , tytul VARCHAR(100))" ); Kolejnym przydatnym mechanizmem w SQLite jest możliwość tworzenia własnych funkcji rozszerzających możliwości bazy danych . Oto przykład: function add_a ( $string ) { $string .= 'a'; return $string ; } $db = sqlite_open('/sciezka_do_bazy_danych/books.db'); sqlite_create_function($db, 'add', 'add_a'); $sql = sqlite_query($db,"SELECT add(autor) AS wynik FROM books "); $rows = sqlite_fetch_array($sql,SQLITE_ASSOC); echo $rows["wynik"]; sqlite_close($db); Obsługa błędów Tak jak w przypadku innych baz danych, także SQLite posiada swój własny "system" obsługi błędów. W omawianym przeze mnie programowaniu strukturalnym, musimy sprawdzać wartości zwracane przez funkcje, a następnie w zależności od tych wartości logicznych generować błąd. Nie musimy się jednak głowić definiowaniem informacjami o tych błędów, zrobi to za nas SQLite. W przypadku niepowodzenia podczas wykonania jakiejś czynności SQLite przypisze numer błędu funkcji sqlite_last_error(), która to zwraca numer ostatnio wygenerowanego przez SQLite błędu.Oczywiście sam numer błędu nam, zwykłym śmiertelnikom nic nie będzie mówił.Zatem musimy go przekształcić na coś bardziej zrozumiałego. Do tego celu służy funkcja sqlite_error_string(), przekształcająca ową niezrozumiałą liczbe na w miare wyczerpującą informacje o błędzie. Przykład: if( sqlite_query($_uchwyt_db, $sql) ) { // dalsze operacje } else die( sqlite_error_string( sqlite_last_error($uchwyt_db) ) ); sqlite_create_function($uchwyt_db, 'add', 'add_a') or die( sqlite_error_string( sqlite_last_error($uchwyt_db) ) ); Np. sqlite_open('/sciezka_do_bazy_danych/books.db',0666,$sqlite_error) or die($sqlite_error); Tytułem zakończeniaPodsumowując SQLite pomimo swojej nazwy, która może sugerować pewną jej "ułomność", obsługuje prawie wszystkie aspekty języka SQL, a także rozszerza go o możliwość definiowania własnych funkcji. Jest to baza danych, która świetnie będzie się spisywać na naszym np. domowym blogu bądź niedużym forum.Jeżeli jednak po przeczytaniu tego artykułu macie wątpliwości co do wydajności SQLite, a także jak wypada na tle innych baz danych w kwesti wydajności, radze zapoznać się z : http://www.maciaszek.pl/phpcon/download/sqlite.pdf Skorowidz nazw * Licencja public domain - ogół tekstów, zdjęć, muzyki, dzieł sztuki, oprogramowania itp., które na skutek decyzji twórcy, braku spadkobierców lub upływu odpowiedniego czasu stały się dostępne do dowolnych zastosowań bez ograniczeń wynikających z przepisów prawa autorskiego. ** Drzewa Binarne - jeden z rodzajów drzewa (struktury danych), w którym liczba synów każdego wierzchołka wynosi nie więcej niż dwa. Wyróżnia się wtedy lewego syna i prawego syna danego wierzchołka. *** Php.ini - Plik konfiguracyjny języka PHP. Artykuł napisany na podstawie : http://www.sqlite.org/ http://pl.php.net/manual/pl/ref.sqlite.php http://pl.wikipedia.org/wiki/ http://www.filipdewaard.com/21_SQLite_inmemory_databases.html http://developer.mimer.com/documentation/html_82/Mimer_SQL_Reference_Manual/Intro_SQL_Stds3.html http://www.maciaszek.pl/phpcon/download/sqlite.pdf Artykuł opublikowany na licencji : http://creativecommons.org/licenses/by-sa/2.5/
| ||||||||||||||||||||||||
|