|
Baza danych MySQL
U偶ycie bazy danych to dobra alternatywa wobec plik贸w, zw艂aszcza przy budowaniu du偶ych serwis贸w czy z艂o偶onych statystyk. Pobieranie i zapisywania informacji w bazach danych opiera si臋 na wysy艂aniu do serwera bazy zapyta艅 zapisywanych w j臋zyku SQL (Structured Query Language) zawartych w kodzie PHP, na kt贸re serwer odpowiada, pobieraj膮c z bazy odpowiednie dane i wysy艂aj膮c je do nas. Zrozumienie tego na pewno u艂atwi poni偶szy schemat:
1. Klient wysy艂a do serwera zapytanie o stron臋 WWW, 2. Serwer WWW wysy艂a do parsera kod PHP, 3. Parser wysy艂a do serwera baz danych zapytanie o jakie艣 dane, 4. Serwer baz zwraca dane, kt贸re s膮 u偶ywane dalej w skrypcie, 5. Parser wysy艂a gotowy kod HTML do serwera WWW, 6. Serwer WWW wysy艂a kod HTML do przegl膮darki klienta.
Przy pisaniu kodu PHP z u偶yciem baz danych trzeba pami臋ta膰, 偶e je艣li serwer PHP nie znajduje si臋 (fizycznie) na tym samym serwerze (czyli nie ma mo偶liwo艣ci odwo艂ania si臋 do niego poprzez localhost), tylko np. w innej cz臋艣ci Internetu, mo偶e to znacznie zwolni膰 prac臋 skryptu. Podczas naszych standardowych test贸w po uruchomieniu strony z po艂膮czeniem do serwera bazy MySQL na innym ho艣cie czas generowania strony wyni贸s艂 oko艂o 2,5 sekundy, a podczas gdy baza znajdowa艂a si臋 na serwerze lokalnym, nie trwa艂o to nawet 0,01 sekundy.
Struktura bazy
Schemat obrazuje struktur臋 bazy danych. Najwa偶niejszym elementem jest oczywi艣cie sama baza 鈥 zazwyczaj jedna przydzielana jest dla ka偶dego u偶ytkownika, chocia偶 na serwerach komercyjnych dostaje si臋 czasem nawet i dziesi臋膰 baz. Ingerowa膰 w bazy (tworzy膰, usuwa膰) mo偶e zazwyczaj tylko administrator. Kolejnym elementem s膮 tabele 鈥 to s膮 dopiero struktury przechowuj膮ce dane. S膮 one dowolnie modyfikowane przez u偶ytkownika i mo偶e ich by膰 dowolna liczba, bo ograniczenia s膮 zazwyczaj nak艂adane przez firmy hostingowe na wielko艣膰 ca艂ej bazy, a nie na liczb臋 tabel. Aby u艂atwi膰 nauk臋 obs艂ugi bazy MySQL-a i tworzenia w艂asnych przyk艂ad贸w, we wszystkich przyk艂adach tworzona b臋dzie i rozbudowywana baza danych fikcyjnych uczni贸w jakiej艣 klasy oraz skrypty j膮 obs艂uguj膮ce.
Po艂膮czenie z baz膮
Przed wykonywaniem operacji na bazie danych nale偶y si臋 z ni膮 po艂膮czy膰. Trzeba u偶y膰 funkcji mysql_connect(host[:port], nazwa u偶ytkownika, has艂o). Funkcja ta 艂膮czy si臋 z serwerem podanym jako argument host. Opcjonalnie, je艣li MySQL pracuje na innym porcie ni偶 3306, nale偶y te偶 to poda膰. Dla przyk艂adu: <? $sql = mysql_connect(鈥檚erwer_baz.org鈥, 鈥榣ogin鈥, 鈥榤oje_haslo鈥); ?>
Zmienna $sql podana na pocz膮tku to uchwyt (handle) do po艂膮czenia z baz膮. Ponownie potrzebny b臋dzie tylko na ko艅cu wykonywania skryptu, aby roz艂膮czy膰 si臋 z baz膮: <? mysql_close($sql); ?>
Je艣li chcemy utworzy膰 du偶y serwis, korzystaj膮cy z bazy i cz臋sto od艣wie偶any, warto po艂膮czy膰 si臋 z baz膮 funkcj膮 mysql_pconnect (permanent connect 鈥 sta艂e po艂膮czenie), dzi臋ki kt贸remu nie trzeba si臋 za ka偶dym razem 艂膮czy膰 z baz膮. Wszystkie argumenty s膮 te same. Wyst臋puje tutaj tylko jedna r贸偶nica: po艂膮czenia pconnect nie trzeba zamyka膰 na ko艅cu skryptu funkcj膮 mysql_close.
J臋zyk SQL
Z baz膮 鈥瀔ontaktujemy si臋鈥 za pomoc膮 zapyta艅. S膮 to polecenia pisane w j臋zyku SQL (bardzo proste) wysy艂ane dzi臋ki funkcji mysql_query, kt贸ra zwraca zmienn膮 z wynikami zapytania. Najcz臋艣ciej u偶ywane tutaj nazwy zmiennych s膮 widoczne na przyk艂adzie, ale oczywi艣cie mo偶emy ustali膰 swoje w艂asne. Dla przyk艂adu: <? $query=鈥漐APYTANIE鈥; $res = mysql_query($query); ?> Pierwsze operacje, nowa baza
Je艣li mamy dost臋p do serwera, mo偶emy sobie za艂o偶y膰 baz臋. Jedyn膮 spraw膮, o kt贸rej nale偶y pami臋ta膰, jest wywo艂anie funkcji mysql_create_db(nazwa), kt贸ra tworzy baz臋 o nazwie podanej w argumencie. Po utworzeniu i przed rozpocz臋ciem pracy nale偶y pami臋ta膰, aby te偶 wybra膰 baz臋, z kt贸r膮 chcemy pracowa膰. Robimy to za pomoc膮 polecenia mysql_select_db(nazwa). Dla przyk艂adu: <? mysql_create_db(鈥渒lasa鈥); mysql_select_db(鈥渒lasa鈥); ?>
Nowe tabele
Gdy za艂o偶yli艣my ju偶 baz臋 danych, kolejnym krokiem jest utworzenie tabel. W tym celu budujemy zapytanie o nast臋puj膮cej sk艂adni: 鈥淐REATE TABLE nazwa (nazwa1 typ1, nazwa2 typ2, nazwa3 typ3, nazwa4 typ4, PRIMARY KEY(nazwa))鈥
Mo偶emy teraz utworzy膰 tabel臋 wed艂ug podanego powy偶ej zapytania. 鈥淐REATE TABLE uczniowie (id char(2) NOT NULL AUTO_INCREMENT, imie char(20) NOT NULL, nazwisko char(40) NOT NULL, urodzony date, PRIMARY KEY(id) )鈥
Stworzona zostanie tabela o nazwie uczniowie z polami id, imie, nazwisko, urodzony, przy czym id b臋dzie kluczem podstawowym, czyli indeksem, i nie b臋dzie si臋 m贸g艂 powtarza膰. Opr贸cz tego, je艣li dodamy NOT NULL, to klucz nie b臋dzie m贸g艂 by膰 pusty. Opcja AUTO_INCREMENT sprawia natomiast, 偶e je艣li nie podamy warto艣ci id do wpisania, to zostanie ona automatycznie wpisania (warto艣ci膮 stanie si臋 warto艣膰 poprzedniego rekordu id podniesiona o jeden). Dost臋pnych jest wiele rodzaj贸w p贸l 鈥 oto kilka najwa偶niejszych:
* char(x) 鈥 ci膮g znak贸w o maksymalnej d艂ugo艣ci podanej jako parametr x (x<256), * longtext 鈥 ci膮g znak贸w o praktycznie nieograniczonej d艂ugo艣ci, * date 鈥 data w formacie YYYY-MM-DD, * year 鈥 rok; je艣li zostanie podany z艂y, jego warto艣膰 zmieni si臋 na 0000, * time 鈥 przechowuje czas w formacie timestamp, * tinyint, smallint, mediumint, int, bigint 鈥 liczby ca艂kowite, * longblob 鈥 przechowuje dane binarne (np. obrazki) o praktycznie nieograniczonej wielko艣ci, * enum, set 鈥 podobne jak 鈥瀝adio鈥 w formularzach, do wyboru s膮 tylko opcje zadeklarowane uprzednio przy tworzeniu bazy (np. tak/nie).
Wstawianie danych
Aby wstawi膰 jakie艣 dane do tabeli, nale偶y pos艂u偶y膰 si臋 instrukcj膮 INSERT. Jej schemat jest nast臋puj膮cy: 鈥淚NSERT INTO nazwa_tabeli (pole1, pole2, pole3) VALUES (wart_pola1, wart_pola2, wart_pola3)鈥
Jako pole1, pole2 itd. wpisujemy nazwy p贸l, kt贸re chcemy wype艂ni膰, a w wart_pola1 itd. w odpowiedniej kolejno艣ci warto艣ci do dodania. Dla przyk艂adu: 鈥淚NSERT INTO uczniowie (imie, nazwisko, dziennik) VALUES (鈥楰ornel鈥, 鈥楰ornelowicz鈥, 鈥1989-12-12鈥)鈥
W powy偶szym wypadku warto艣膰 pola id zostanie ustalona na 1, poniewa偶 jest to pierwszy rekord w tabeli. Je艣li wstawialiby艣my to samo jeszcze raz, to mia艂by on ca艂y czas warto艣膰 id o jeden wi臋ksz膮 od poprzedniej. Wstawmy do bazy kilka pojedynczych rekord贸w z danymi uczni贸w: <? $res = mysql_query(鈥淚NSET INTO uczniowie (imie, nazwisko, dziennik) VALUES (鈥榃acek鈥, 鈥楰apusta鈥, 鈥2鈥)鈥); $res = mysql_query(鈥淚NSET INTO uczniowie (imie, nazwisko, dziennik) VALUES (鈥楯urek鈥, 鈥極g贸rek鈥, 鈥3鈥)鈥); $res = mysql_query(鈥淚NSET INTO uczniowie (imie, nazwisko, dziennik) VALUES (鈥榃ojtek鈥, 鈥楯arz膮bek鈥, 鈥4鈥)鈥); $res = mysql_query(鈥淚NSET INTO uczniowie (imie, nazwisko, dziennik) VALUES (鈥楽ebastian鈥, 鈥榃arzywo鈥, 鈥5鈥)鈥); ?> Wybieranie konkretnych rekord贸w
Aby wybra膰 z bazy danych jakie艣 dane, nale偶y pos艂u偶y膰 si臋 operatorem SELECT. Jego sk艂adnia to: SELECT pole1, pole2, pole_n FROM nazwa_tabeli WHERE warunek1 AND warunek2 ORDER BY nazwa_klucza rodzaj_sortowania LIMIT klucz_poczatkowy, ilosc_rekord贸w
Jest to do艣膰 zawi艂e, dlatego teraz po kolei wyt艂umaczymy ca艂e zapytanie.
* pole1, pole2, pole_n 鈥 okre艣laj膮 nazwy p贸l, kt贸re serwer baz ma wys艂a膰 w wyniku. Je艣li chce si臋 otrzyma膰 wszystkie, wystarczy wpisa膰 * (gwiazdk臋), * FROM nazwa_tabeli 鈥 to chyba najprostszy fragment; okre艣la nazw臋 tabeli, z kt贸rej maj膮 by膰 wybrane rekordy, * WHERE warunek1 AND warunek2 鈥 to warunek (warunki), wed艂ug kt贸rych serwer ma przeszukiwa膰 baz臋. Mo偶na nie poda膰 ich wcale i wtedy wynik b臋dzie zawiera艂 wszystkie rekordy z tabeli. Warunki mo偶na 艂膮czy膰 operatorami AND oraz OR, a tak偶e bra膰 w nawiasy (tak jak w IF w PHP), * ORDER BY nazwa_klucza rodzaj_sortowania 鈥 okre艣la, wed艂ug jakiego klucza posortowane maj膮 by膰 wyniki i w jakiej kolejno艣ci. Dost臋pne s膮 dwa rodzaje sortowania: ASC (rosn膮ce) i DESC (malej膮ce), * LIMIT klucz_poczatkowy, ilosc_rekord贸w 鈥 okre艣la, ile wynik贸w ma by膰 zwr贸conych. Warto pami臋ta膰, 偶e ilosc_rekordow pokazuje, ile ma by膰 zwr贸conych rekord贸w od klucz_pocz膮tkowy, a nie jest to id klucza ko艅cowego (cz臋sty b艂膮d).
Na schemacie pokazujemy przyk艂ad u偶ycia LIMIT. W wynikach jest 16 rekord贸w, potrzebne s膮 rekordy od 3 do 14. Wa偶ne jest, aby si臋 nie pomyli膰 i w ilosc_rekordow poda膰 ca艂kowit膮 liczb臋 potrzebnych rekord贸w, a nie id ostatniego (tak jak w wi臋kszo艣ci baz danych czy na adresowaniu kom贸rek w Excelu). Dla przyk艂adu: <? $res = mysql_query(鈥淪ELECT * FROM uczniowie ORDER BY dziennik ASC鈥); $res = mysql_query(鈥淪ELECT imie FROM uczniowie WHERE nazwisko = 鈥楰apusta鈥欌); $res = mysql_query(鈥淪ELECT * FROM uczniowie WHERE dziennik > 5鈥); //a oto popularny przyk艂ad na wy艣wietlanie porcji //wynik贸w, np z ksi臋gi go艣ci $res = mysql_query(鈥淪ELECT * FROM ksi臋ga ORDER BY id ASC LIMIT $start, 10鈥); ?>
W warunkach do przeszukiwania mog膮 te偶 wyst膮pi膰 takie operatory, jak IN lub BETWEEN. Dla przyk艂adu: <? $res = mysql_query(鈥淪ELECT * FROM uczniowie WHERE id=5 OR id=7 OR id=10鈥); //te dwa przyk艂ady to to samo $res = mysql_query(鈥淪ELECT imie FROM uczniowie WHERE id IN(5,7,10)鈥); $res = mysql_query(鈥淪ELECT * FROM uczniowie WHERE dziennik > 5 AND dziennik < 20鈥); //i to te偶 to samo 鈥 between okre艣la zakres $res = mysql_query(鈥淪ELECT * FROM uczniowie WHERE dziennik BETWEEN 5 AND 20鈥); ?>
Zast臋pc膮 znanego z instrukcji warunkowych wykrzyknika jest NOT. Mo偶na go u偶y膰 zar贸wno przed pojedyncz膮 instrukcj膮, jak i przed ca艂ym nawiasem. Dla przyk艂adu: <? $res = mysql_query(鈥淪ELECT imie FROM uczniowie WHERE id NOT IN(5,7,10)鈥); //zwraca wszystkich uczni贸w o id r贸偶nym od 5, 7 lub 10 $res = mysql_query(鈥淪ELECT * FROM uczniowie WHERE dziennik NOT BETWEEN 5 AND 20鈥); //zwraca wszystkich uczni贸w o id mniejszym od 5 i wi臋kszym od 20 ?>
Nie zawsze da si臋 dok艂adnie por贸wna膰 dwa ci膮gi znak贸w. Czasem nale偶y pos艂u偶y膰 si臋 operatorem LIKE. Por贸wnuje on konkretn膮 warto艣膰 ze wzorcem. Zaznaczmy przy tym, 偶e % (procent) zast臋puje w wyra偶eniu dowoln膮 liczb臋 znak贸w, a _ (podkre艣lenie) zast臋puje dok艂adnie jeden znak. Dla przyk艂adu: <? $res = mysql_query(鈥淪ELECT * FROM uczniowie WHERE imie LIKE 鈥%ek鈥 AND nazwisko LIKE 鈥榑apusta鈥欌); ?> Modyfikacja rekord贸w
Czasem zachodzi potrzeba poprawienia jakiego艣 rekordu. B艂膮d mo偶e by膰 wynikiem nieuwagi przy wprowadzaniu danych, ale mo偶emy te偶 chcie膰 zmieni膰 adres klienta w bazie danych sklepu internetowego. S艂u偶y do tego polecenie UPDATE. Jego sk艂adnia to: UPDATE nazwa_tabeli SET pole1=鈥檟yz鈥, pole2 = 鈥榓bc鈥, polen = 鈥榖cd鈥 WHERE warunki
Przyjrzyjmy si臋 bli偶ej temu zapytaniu:
* nazwa_tabeli 鈥 to po prostu nazwa tabeli, w kt贸rej ma nast膮pi膰 zamiana rekord贸w, * SET pole1=鈥檟yz鈥, pole2 = 鈥榓bc鈥, polen = 鈥榖cd鈥 鈥 okre艣la pola i warto艣ci, kt贸re maj膮 by膰 do nich przydzielone, * WHERE warunki 鈥 okre艣la, kt贸re rekordy maj膮 by膰 modyfikowane. W wypadku gdy nie podamy warunku w WHERE, modyfikacji ulegaj膮 wszystkie rekordy w tabeli.
Dla przyk艂adu: <? $res = mysql_query(鈥淯PDATE uczniowie SET dziennik = 11 WHERE id = 3鈥); $res = mysql_query(鈥淯PDATE uczniowie SET dziennik = 12 WHERE id = 2鈥); ?> Usuwanie rekord贸w
Do usuwania jednego, kilku okre艣lonych rekord贸w lub zawarto艣ci ca艂ej tabeli s艂u偶y DELETE. Jego sk艂adnia to: DELETE FROM nazwa_tabeli WHERE warunki
Oznaczenia s膮 takie same jak w poprzednich poleceniach i nie trzeba ich jeszcze raz opisywa膰. Warto za艣 zaznaczy膰, 偶e je艣li niepodany zostanie warunek WHERE, to tabela zostanie wyczyszczona. Dla przyk艂adu: <? $res = mysql_query(鈥淒ELETE FROM uczniowie WHERE id = 3鈥); $res = mysql_query(鈥淒ELETE FROM uczniowie WHERE id > 15鈥); ?> Funkcje do obs艂ugi MySQL-a
W PHP istnieje wiele funkcji do kontaktu z baz膮 danych MySQL i obs艂ugi zapyta艅. Podstawowe ju偶 znamy:
* mysql_connect 鈥 艂膮czy z baz膮 danych, * mysql_pconnect 鈥 艂膮czy trwale z baz膮 danych, * mysql_create_db 鈥 tworzy baz臋 danych, * mysql_select_db 鈥 wybiera baz臋 danych, * mysql_close 鈥 ko艅czy po艂膮czenie z baz膮 danych, * mysql_query 鈥 wysy艂a zapytanie do bazy danych.
mysql_num_rows()
Funkcja mysql_num_rows(rezultat) zwraca liczb臋 rekord贸w z wyniku zapytania skierowanego do serwera bazy. Poni偶szy przyk艂ad wy艣wietla licz臋 rekord贸w w tabeli uczniowie: <? $res = mysql_query(鈥淪ELECT * FROM uczniowie鈥); $ile = mysql_num_rows($res); echo $ile; ?> mysql_fetch_array()
Funkcja mysql_fetch_array(rezultat [,typ]) zwraca przy ka偶dym wywo艂aniu kolejny wiersz z wyniku zapytania w postaci tablicy zwyk艂ej lub asocjacyjnej (lub jednej i drugiej). Typ tablicy zale偶y w艂a艣nie od parametru typ. Mo偶e on przybra膰 warto艣膰 MYSQL_ASSOC (zwraca wynik w postaci tablicy asocjacyjnej), MYSQL_NUM (w postaci zwyk艂ej tablicy) albo (domy艣lnie) MYSQL_BOTH (tablicy indeksowanej asocjacyjnie i numerycznie). Dla przyk艂adu: <? $res = mysql_query(鈥淪ELECT * FROM uczniowie鈥); while($row = mysql_fetch_array($res, MYSQL_BOTH)) { echo ?ID to ?.$row[id].? a jego imie to: ?.$row[1]; } ?> mysql_insert_id()
Funkcja mysql_insert_id() zwraca ID wygenerowane dla pola z w艂asno艣ci膮 AUTO_INCREMENT. Uwaga! Funkcja mysql_insert_id() zwr贸ci 0, gdy rekord by艂 dodawany do tabeli bez pola AUTO_INCREMENT. Dla przyk艂adu: <? $res = mysql_query(鈥淚NSERT INTO uczniowie (imie, nazwisko, dziennik) VALUES (鈥楯ustyna鈥, 鈥楰oma鈥, 13)鈥); $id = mysql_insert_id(); echo 鈥淚D ostatnio dodanego rekordu to: 鈥.$id; ?> mysql_result()
mysql_result(rezultat ,wiersz [,kolumna])- Bardzo przydatna funkcja, gdy trzeba si臋 odwo艂a膰 do konkretnego pola w konkretnym rz臋dzie wyniku. Wystarczy poda膰 jako pierwszy argument zmienn膮 z rezultatem zapytania, jako drugi wiersz, a jako trzeci (opcjonalnie)pole w danym wierszu (domy艣lne to 0). <? $res = mysql_query(鈥淪ELECT * FROM uczniowie鈥); echo mysql_result($res, 0, 1); //wy艣wietli imi臋 pierwszego ucznia w tabeli ?> mysql_error()
Funkcja mysql_error() pokazuje tre艣膰 ostatniego b艂臋du wygenerowanego przez serwer MySQL. Warto wywo艂a膰 t臋 funkcj臋 po zapytaniu do bazy, kt贸re powoduje b艂臋dy. Dla przyk艂adu: <? $res = mysql_query(鈥淪ELECT * FROM ucnziowie鈥); echo mysql_error(); ?>
wy艣wietli co艣 w stylu 鈥#1146 鈥 Table 鈥榖aza.ucnziowie鈥 doesn鈥檛 exist鈥. Wy艣wietlanie wyniku zapytania
Cz臋stym b艂臋dem pocz膮tkuj膮cego programisty jest pr贸ba wykonania nast臋puj膮cego kodu: echo $res;
Niestety, $res jest niejako obiektem zawieraj膮cym zgrupowane dane, a wi臋c za pomoc膮 echo nie da si臋 ich bezpo艣rednio wy艣wietli膰. Istniej膮 dwie podstawowe metody przegl膮dania danych z zapytania do MySQL-a. Pierwsza 鈥 wiersz po wierszu 鈥 i druga 鈥 bezpo艣rednio odwo艂uj膮c si臋 do danego wiersza lub kolumny.
1. P臋tla while i mysql_fetch_array Dla przyk艂adu: <? $res = mysql_query(鈥淪ELECT * FROM config鈥); while($row = mysql_fetch_array($res, MYSQL_BOTH)) { echo 鈥渃onfig_name to 鈥.$row[0].鈥 a jego warto艣膰 to: 鈥.$row[config_value]; } ?>
Przy ka偶dej iteracji p臋tli zmienna $row staje si臋 czteroelementow膮 tablic膮. Dzi臋ki ustawionemu MYSQL_BOTH do rekord贸w mamy dost臋p zar贸wno poprzez nazwy indeks贸w (np. config_value), jak i poprzez kolejne cyfry (w danym wypadku config_name to 0, a config_value to 1). Wa偶ne jest to, by wybra膰 wygodniejszy dla siebie spos贸b, pami臋taj膮c o wadach ka偶dego z nich (MYSQL_ASSOC to wi臋cej pisania, przy MYSQL_NUM natomiast podczas zmiany zapytania mo偶e si臋 鈥瀙osypa膰鈥 ca艂y skrypt).
Funkcja mysql_result()
Metoda ta jest dobra przy pobieraniu pojedynczego elementu z du偶ego zapytania do bazy. Jej zalet膮 jest to, 偶e nie trzeba przechodzi膰 przez ca艂膮 baz臋, wad膮 jest natomiast konieczno艣膰 znajomo艣ci dok艂adnej lokalizacji wyniku w zapytaniu (wsp贸艂rz臋dne wiersz i kolumna). Dla przyk艂adu: <? $res = mysql_query(鈥淪ELECT * FROM config鈥); echo mysql_result($res,3,1); //wy艣wietli po prostu 鈥25鈥 ?>
Do administrowania swoj膮 baz膮 danych, a w szczeg贸lno艣ci ca艂ym serwerem i wszystkimi bazami, polecamy u偶ywania darmowego skryptu phpMyAdmin. Pozwala on na bardzo szybki i sprawny nadz贸r nad bazami, tabelami i u偶ytkownikami baz.
|