Płaskie struktury danych |
|
Baza danych to rodzaj tabeli podzielonej na poziome wiersze (rekordy) oraz pionowe kolumny (pola). Rekord jest pojedyńczym wpisem do bazy danych. Natomiast pola zawierające dane składają się na pojedyńczy rekord. Definicja ta jest wielkim uproszczeniem, ale na początek zupełnie wystarczy.
Jako przykład weźmy zbiór sześciu liczb, będących wynikiem losowania Dużego Lotka.
Lp |
Liczby |
1 |
4, 7, 23, 27, 42, 49 |
Tabela 1
Możemy powiedzieć, że jest to jeden rekord o sześciu polach numerycznych ...
Lp |
Liczby |
1 |
4 |
2 |
7 |
3 |
23 |
4 |
27 |
5 |
42 |
6 |
49 |
Tabela 2
... lub sześć rekordów o jednym polu numerycznym.
Na początek zajmiemy się drugim przypadkiem, gdzie mamy do czynienia z sześcioma rekordami. Spróbujmy napisać skrypt PHP, który otwierałby plik lotto.txt z zapisanym liczbami i przedstawiałby wyniki losowania w postaci powyższej tabeli.
1 4, 7, 23, 27, 42, 49 |
Plik lotto.txt |
1 <table> 2 <tr> 3 <td>Lp</td> 4 <td>Liczby</td> 5 </tr> 6 <? 7 $plik= file( "lotto.txt"); 8 $baza= explode( ",", $plik[0]); 9 // wypisz wiersze (rekordy) 10 while( list( $lp, $liczba) = each( $baza)){ 11 print("<tr align='center'>". 12 "<td>".($lp+1)."</td>". 13 "<td>".$liczba."</td>". 14 "</tr>"); 15 } 16 ?> 17 </table> |
Plik tabela2.php |
Wiersze 1-5 to typowy początek definicji tabeli wraz z pierszym wierszem będącym jednocześnie nagłówkiem. Następnie funkcja file() otwiera oraz wczytuje zawartość pliku lotto.txt do zmiennej $plik. W zasadzie zmienna $plik staje się tablicą, gdyż funkcja file() umieszcza każdy wiersz czytanego pliku w osobnym elemencie tablicy. Funkcja explode() rozdziela liczby oddzielone "," z pierwszego wiersza tablicy ($plik[0]). W pętli zawartej w wierszach 10-15 następuje wypełnienie tabeli treścią. Wiersz 17 stanowi zakończenie definicji tabeli.
Na uwagę zasługuje konstrukcja z wiersza dzisiątego.
list( $lp, $liczba) = each( $baza)
W działaniu funkcji each() nie ma nic dziwnego. O ile nie dojdzie do końca tablicy $baza, o tyle zwracany jest kolejne jej element. Natomiast znacznie ciekawsza jest funkcja list(), a w zasadzie lewostronny operator. Do zmiennych $lp i $liczba przypisuje wartosci zwracane przez funkcję each(). Warto się chwilę zastanowić nad tą konstrukcją, gdyż jest ona specyficzna dla języka PHP.
Gdybyśmy jednak chcieli pokazać więcej wyników losowań niż tylko jedno, to okaże się, że układ z Tabeli 1 byłby znacznie lepszy. Spróbujmy zatem napisać skrypt, który otworzy plik lotto2.txt i przedstawi wyniki z czterech kolejnych losowań.
3748, 2001-03-24, 4, 7, 23, 27, 42, 49 3747, 2001-03-21, 2, 14, 22, 24, 26, 34 3746, 2001-03-17, 8, 11, 14, 24, 25, 45 3745, 2001-03-14, 2, 9, 11, 25, 40, 49 |
Plik lotto2.txt |
1 <table> 2 <tr> 3 <td>Lp</td> 4 <td>Data</td> 5 <td>L1</td> 6 <td>L2</td> 7 <td>L3</td> 8 <td>L4</td> 9 <td>L5</td> 10 <td>L6</td> 11 </tr> 12 <? 13 $plik= file( "lotto2.txt"); 14 15 // wypisz kolejne wiersze (rekordy) 16 while( list( $lp, $wiersz) = each( $plik)){ 17 print( "<tr align='center'>"); 18 // wypisz pola rekordu 19 $pola= explode( ",", $wiersz); 20 while( list( $lp, $dane) = each( $pola)){ 21 print( "<td>".$dane."</td>"); 22 } 23 print("</tr>"); 24 } 25?> 26</table> |
Plik tabela3.php |
Lp |
Data |
L1 |
L2 |
L3 |
L4 |
L5 |
L6 |
3748 |
2001-03-24 |
4 |
7 |
23 |
27 |
42 |
49 |
3747 |
2001-03-21 |
2 |
14 |
22 |
24 |
26 |
34 |
3746 |
2001-03-17 |
8 |
11 |
14 |
24 |
25 |
45 |
3745 |
2001-03-14 |
2 |
9 |
11 |
25 |
40 |
49 |
Tabela 3
Tym razem niewielkie zmiany w poprzednim skrypcie dały nam oczekiwany rezultat. Pierwsza pętla (linia 16) czyta kolejne wiersze, natomiast druga pętla (wiersz 20) pola zawarte w wierszu.
|
Przecież dane można zdefiniować wprost w skrypcie w postaci tablic. Jednak za umieszczeniem danych w osobnym pliku (bazie danych) przemawiają trzy rzeczy:
Najważniejszą sprawą jest oddzielenie danych od kodu skryptu co zazwyczaj skutkuje zwiększeniem czytelności samego kodu;
Modyfikowanie danych nie wymaga zmieniania treści skryptu. Zapobiega to przypadkowym uszkodzeniom kodu skryptu nawet przez twórcę strony;
Plik z danymi może przygotowywać osoba nie znająca zasad programowania skryptów. Wystarczy, że przygotuje dane w ustalonym wcześniej formacie, który może być zdecydowanie prostszy od kodu skryptu.
W następnej części przedstawię sposoby zapisywania danych do pliku na przykładzie licznika odwiedzin. W dalszych częściach wytoczymy działo o większym kalibrze jakim jest baza MySQL.
Bazy danych - podstawy cz.1 |
W dostępnych na stronie artykułach poświeciłem już trochę miejsca tematowi przechowywania danych. Do chwili obecnej naszym podstawowym elementem ich gromadzenia były pliki tekstowe, które mogą taką funkcje spełniać, ale niewątpliwie nie są najbardziej efektywnym sposobem. Takim sposobem są natomiast bazy danych, a dokładniej mówiąc - serwery baz danych, z których najpopularniejszym w serwisach WWW jest serwer bazy MySQL.
|
Jeżeli miałeś już Szanowny Czytelniku do czynienia z bazami danych, to ten fragment artykułu możesz pominąć. Jeżeli jednak tematyka baz danych tylko obiła Ci się o uszy warto przeczytać go uważnie.
Na początek postaram się, korzystając z analogii pokazać różnicę między przechowywaniem danych w plikach tekstowych, a wykorzystaniem do tego celu serwera bazy danych. Wyobraź sobie, że jesteś szefem firmy zatrudniającej kilkudziesięciu pracowników. Wcześniej czy później przyjdzie Ci z jakichkolwiek powodów zrobić listę tych pracowników, którzy ukończyli np. 40 lat. Kartoteki Twoich pracowników zalegają szufladę Twojego biurka, więc wyciągasz je i rozpoczynasz sortowanie luźnych kart pracowniczych (analogicznie jak w plikach tekstowych). Twoje czynności sprowadzają się do wzięcia do ręki każdej karty (czytasz jeden wiersz z pliku tekstowego), sprawdzenia daty urodzenia i obliczenia (obróbka każdego wiesza), czy pracownik ukończył 40 lat. Jeżeli ukończył - odkładasz kartę na bok (wyświetlasz informację zawartą w czytanym wierszu). Jeżeli pracownik jest młodszy - odkładasz kartę na swoje miejsce i czytasz następną (pomijasz informację z aktualnego wiersza i rozpoczynasz czytanie następnego). Tak z grubsza można przedstawić sposób korzystania z plików tekstowych.
Dlaczego jednak nie miałbyś ułatwić sobie pracy i nie zafundować sobie serwera bazy danych? Co musisz zrobić? Kupujesz szufladę-segregator, wpinasz karty swoich pracowników do wspomnianego segregatora i zamykasz to na klucz. W dalszej kolejności zatrudniasz panią Krysię, która będzie Twoją kadrową. Karty pracowników i szuflada wraz z zatrudnioną panią Krysią stały się Twoim serwerem bazy danych. Gdy ponownie będziesz potrzebował informacji o niektórych pracownikach, skorzystasz z dobrodziejstw serwera bazy danych. Zawołasz panią Krysię i powiesz: proszę dostarczyć mi listę pracowników, którzy skończyli 40 lat. Takim to sposobem zadałeś pytanie, które w języku SQL rozumianym przez serwer mogłoby brzmieć: "SELECT * FROM pracownicy WHERE wiek='40'".
Jeżeli czytałeś artykuły, w których posługiwałem się plikami tekstowymi, to zapewne już zauważyłes różnicę w sposobie wybierania potrzebnych Ci danych. Jeżeli widzisz więc korzyści ze stosowania bazy, przeczytaj dalszą część i zobacz jak z taką bazą sobie poradzić.
|
W przytoczonych w dalszej części przykładach, spróbujemy poznać jedną z najpopularniejszych w Internecie baz danych jaką jest baza MySQL. Do jej wykorzystania użyjemy języka PHP, który w chwili obecnej, wraz z bazą MySQL stanowi chyba najczęściej wykorzystywany tandem.
Serwer bazy danych to program pracujący na jakiejś maszynie i oczekujący na skierowane do niego polecenia. Tym samym ma swój adres internetowy, z którym podobnie jak w przypadku serwera WWW musimy się połączyć. Każdy serwer może obsługiwać wiele baz danych, z których każda może zawierać wiele tabel. Taka konstrukcja oznacza, że próbując wydawać polecenia serwerowi musimy się najpierw z nim połączyć. Nie każdy ma prawo korzystać z bazy danych - system uprawnień przechowywany w kilku tabelach pozwala zweryfikować, czy połączenie z serwerem dokonuje uprawniony użytkownik. Weryfikacja uprawnień odbywa się za pomocą nazwy użytkownika i jego hasła.
Na podstawie powyższego wstępu powinniśmy już rozumieć, że wydanie jakichkolwiek poleceń SQL musi zostać poprzedzone połączeniem z serwerem, do czego niezbędne są: adres serwera (host), nazwa użytkownika (username) oraz hasło użytkownika (password). Podane w nawiasach określenia nie oznaczają, że tak właśnie te terminy musza brzmieć, ale często z takimi (lub podobnymi określeniami się spotkamy).
Zarządzanie serwerem lub swoją bazą na serwerze może się odbywać z tzw. linii poleceń, do czego wykorzystujemy połączenie telnetowe (lub alternatywne np. SSH). Po zalogowaniu możemy napisać (pogrubiona czcionka):
firesoft@tester ~ > mysql -u root -p
Enter password:
ERROR 1045: Access denied for user: 'root@localhost' (Using password: NO)
firesoft@tester ~ >
W powyższym przykładzie, po połączeniu ze swoim kontem na serwerze prowidera, próbowałem się dostać do bazy danych używając nazwy uzytkonika root. Ponieważ nie mam uprawnień root'a (nie znam jego hasła), serwer zwrócił mi komunkat: Access denied for user: 'root@localhost' (Using password: NO) (co w wolnym tłumaczeniu oznacza: Dostęp do hosta localhost zabroniony dla użytkownika root ). W kolejnym przykładzie wykorzystam własną nazwę (tester) i znane mi hasło (nie jest widoczne po wprowadzeniu):
firesoft@tester ~ > mysql -u tester -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1844836 to server version: 3.23.48
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
Tym razem przywitał mnie tekstowy minitor serwera, za pomocą którego mogę tworzyć bazy i tabele, wstawiać i usuwać rekordy oraz wiele innych. Przydatność tego sposobu dla webmasterów jest jednak dyskusyjna, dlatego tych samych operacji dokonamy za pomocą innego interfejsu. Będzie nim język PHP.
|
Jezyk PHP wspiera współpracę z bazą MySQL (i nie tylko z nią). W manualu można znaleźć wiele poleceń i funkcji języka, z których wykorzystamy za chwilę te, które niezbędne są do połączenia. Połączenia możemy dokonać w dwóch krokach:
mysql_connect("host", "username","password");
mysql_select_db("database");
W pierwszej linii połączyliśmy się z serwerem, a w drugiej wybraliśmy bazę danych, bo jak może pamiętamy, jeden serwer może obsługiwać więcej niż jedną bazę. W praktyce kod PHP jest bardziej rozbudowany - spróbujmy najpierw zobaczyć stosowny przykład.
<?php
$host = "baza.nazwadomeny.pl:23345";
$username = "tester";
$password = "haslotestera";
$database = "mojabaza";
$polaczenie = mysql_connect($host, $username, $password);
mysql_select_db($database, $polaczenie);
....
....
... rożne polecenia pobierania danych...
....
....
mysql_close($polaczenie);
?>
W pierwszych czterech wierszach, niezbędne do pracy z bazą dane umieściłem w zmiennych. Taki zabieg ma sens wtedy, gdy w skrypcie (lub kilku skryptach) wielokrotnie będziemy zestawiać połączenia. Zmiana serwera, bazy lub hasła będzie łatwiejsza, jeżeli umieścimy to w jednym miejscu, a później posługiwać się będziemy tylko zmiennymi. Zwracam uwagę na zmienną $host - najczęściej, gdy serwer WWW jest na tej samej maszynie co serwer bazy, nazwą hosta jest "localhost". Jeżeli jednak serwer bazy znajduje się w innym miejscu, a na dodatek pracuje na innym porcie, niż typowy, zmuszeni jesteśmy podać nazwę hosta, składającą się z nazwy (baza.nazwadomeny.pl) oraz numeru portu (23345).
W następnej linii skryptu wykonujemy połączenie, przypisując je do zmiennej. Pozwala nam to identyfikować dokładnie to połączenie. Polecenie wyboru bazy danych zostało uzupełnione o nazwę połączenia z którego należy skorzystać. W kolejnych liniach wykonujemy różne operacje bazodanowe, generujemy HTML, wyświetlamy wyniki, itp. Na koniec skryptu zamykamy połączenie z bazą wykorzystując funkcję języka PHP o nazwie mysql_close().
Tym sposobem uzyskaliśmy połączenie z bazą danych. Korzystając z konta u dostawcy usług internetowych, najczęściej otrzymujemy założoną bazę danych, więc opis ich tworzenia pozwolę sobie pominąć. Jednakże umiejętność tworzenia tabel w bazie będzie nam zdecydowanie niezbędna i właśnie o tym traktować będzie nastepna część niniejszego cyklu.
Zapraszam wkrótce
Bazy danych - podstawy cz.2 |
W poprzedniej części uzyskaliśmy połączenie z bazą danych. Wspomniałem przy tym, że korzystając z konta u dostawcy usług internetowych, najczęściej otrzymujemy założoną bazę danych, więc opis tworzenia samej bazy pozwolę sobie pominąć. Teraz zajmmiemy się umiejętnością tworzenia tabel w bazie oraz wykonywania podstawowych operacji na utworzonych tabelach.
|
Zanim zabierzemy się za wykorzystanie baz danych warto poznać miejsce, w którym kończy się SQL a zaczyna PHP. Wtedy łatwiej będzie połaczyć te dwa, niezalezne elementy.
SQL to jezyk zapytań do bazy danych. Możemy go stosować bezpośrednio w omówionym w pierwszej części tekstowym monitorze serwera. Tak więc podany w pierwszej części przykład:
"SELECT * FROM pracownicy WHERE wiek='40'".
jest poleceniem jezyka SQL i do jego wykonania niekoniecznie potrzebujemy PHP.
Zapominając na chwilę o PHP i innych językach pozwalających współpracować z bazą danych, skupmy się na samym jezyku SQL. Spróbujmy wykonać kilka poleceń posługując się monitorem serwera MySQL.
Po zalogowaniu do serwera (patrz 1 część) wydajemy polecenie utworzenia tabeli w naszej bazie danych:
mysql> CREATE TABLE pracownicy (
-> id_prc INT(8) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> pracownik VARCHAR(128) NOT NULL,
-> rok_urodzenia MEDIUMINT(4) NOT NULL
-> );
Query OK, 0 rows affected (0.03 sec)
Teraz sprawdzamy, czy utworzona tabela coś zawiera:
mysql> SELECT * FROM pracownicy;
Empty set (0.00 sec)
Komunikat w monitorze informuje nas, ze tabela jest pusta. Dodajmy wobec tego jeden rekord to utworzonej tabeli:
mysql> INSERT INTO pracownicy VALUES(NULL,'Jan Kowalski',1976);
Query OK, 1 row affected (0.00 sec)
Dodawanie zakończyło się sukcesem. Możemy teraz ponownie sprawdzić, co zawiera tabela:
mysql> SELECT * FROM pracownicy;
+--------+--------------+---------------+
| id_prc | pracownik | rok_urodzenia |
+--------+--------------+---------------+
| 1 | Jan Kowalski | 1976 |
+--------+--------------+---------------+
1 row in set (0.00 sec)
Tym razem monitor pokazuje nam jeden, przed chwilą dodany rekord. Ponieważ był to tylko trening posługiwania się SQL-em, skasujemy naszą tabelę.
mysql>DROP TABLE pracownicy
Query OK, 0 rows affected (0.00 sec)
mysql>
Możemy już zakończyć pracę z monitorem i wylogować się z serwera. Przedstawione powyżej operacje miały na celu demonstrację użycia samego SQL-a. W praktyce będziemy chcieli używać tego języka za pośrednictwem języka PHP. Jak wydać podobne polecenia serwerowi bazy danych wykorzystując PHP? O tym już za chwilę.
|
Liczę na to, ze sposób połączenia z serwerem MySQL za pomocą PHP jest nam już znany z części 1. Dla przypomnienia, podaję fragment kodu, który jest za to odpowiedzialny:
<?php
$host = "baza.nazwadomeny.pl:23345";
$username = "tester";
$password = "haslotestera";
$database = "mojabaza";
$polaczenie = mysql_connect($host, $username, $password);
mysql_select_db($database, $polaczenie);
...
...
... rożne polecenia pobierania danych...
...
?>
Efektem powyższego jest uzyskane połączenie z bazą mojabaza. Połączenie to posiada identyfikator połączenia umieszczony w zmiennej $połaczenie. Moglibyśmy pominąć identyfikator, jeżeli założymy, że w naszym skrypcie wykonujemy tylko jedno połączenie. Uproszczony fragment kodu wygladałby tak:
mysql_connect($host, $username, $password);
mysql_select_db($database);
Może się jednak zdarzyć, że skrypt wymaga odwołania się do więcej niż jednnej bazy. Wtedy uproszczenie powyższe może spowodować pewne zamieszanie. Sugeruję więc identyfikować połączenia.
Spróbujmy teraz wykonac za pomocą skryptu te same czynności, które robiliśmy wykorzystując monitor serwera bazy. Przeanalizujmy następujący fragment kodu:
$query = "CREATE TABLE pracownicy (
id_prc INT(8) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
pracownik VARCHAR(128) NOT NULL,
rok_urodzenia MEDIUMINT(4) NOT NULL
)";
$wynik = mysql_query($query);
if($wynik) {
echo "Zapytanie do bazy zakończyło sie sukcesem";
} else {
echo "Nieudane zapytanie do bazy";
}
Powyższy przykład nie jest być może optymalny, ale bardziej czytelny dla początkującego użytkownika. W wierszach od pierwszego do piątego, do zmiennej $query wstawiamy treść polecenia SQL, które jest nam już znane. Może ono być umieszczone w jednej linii - w przykładzie poszczególne pola zostały umieszczone w kolejnych wierszach dla większej przejrzystości.
W szóstym wierszu, korzystając z funkcji PHP mysql_query() wysyłamy przygotowane wcześniej polecenie do aktywnej bazy danych. Gdybyśmy używali aktualnie więcej niż jednej bazy danych, w powyższej funkcji należałoby użyć identyfikatora połączenia, o którym wspominałem wcześniej. Zapisalibyśmy to tak:
$wynik = mysql_query($query, $polaczenie);
Wynikiem wysłania polecenia SQL jest identyfikator zbioru wyników $wynik, który zawiera efekt wykonania polecenia SQL. Jeżeli polecenie nie zostało wykonane poprawnie (z powodu różnego rodzaju błędów), zmienna $wynik zawierać będzie wartość FALSE. Na tym właśnie opierają się kolejne cztery wiersze, które informują nas, że zapytanie zostało wykonane poprawnie lub zakończyło się niepowodzeniem.
Zdobytą do tej pory wiedzę spróbujmy połączyć w jeden, kompletny plik php.
<?php
$host = "baza.nazwadomeny.pl:23345";
$username = "tester";
$password = "haslotestera";
$database = "mojabaza";
$polaczenie = mysql_connect($host, $username, $password);
mysql_select_db($database, $polaczenie);
$query = "CREATE TABLE pracownicy (
id_prc INT(8) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
pracownik VARCHAR(128) NOT NULL,
rok_urodzenia MEDIUMINT(4) NOT NULL
)";
$wynik = mysql_query($query, $polaczenie);
if($wynik) {
echo "Zapytanie do bazy zakończyło sie sukcesem";
} else {
echo "Nieudane zapytanie do bazy";
}
?>
Jeżeli uruchomimy ten skrypt jeden raz powinnismy otrzymac komunikat:
Zapytanie do bazy zakończyło sie sukcesem
Jeżeli jednak wykonamy go ponownie, to otrzymamy inny komunikat:
Nieudane zapytanie do bazy
Dzieje się tak dlatego, że przy pierwszym uruchomieniu utworzylismy tabele pracownicy. przy kolejnym uruchomieniu ponownie usiłowalismy utworzyć tabele, która już istnieje. Przesłane polecenie SQL się nie powiodło i zmienna $wynik przyjeła wartość FALSE.
Właściwie wiemy już wszystko, aby wykonac kolejne polecenia SQL, które wczesniej wykonywaliśmy przy uzyciu monitora serwera bazy danych. Czy potrafisz szanowny czytelniku zrobic to już samodzielnie?
Na wypadek, gdybys miał z tym problemy ponizej zamieszczam fragment kodu:
<?php
...
...
$query1 = "CREATE TABLE pracownicy (
id_prc INT(8) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
pracownik VARCHAR(128) NOT NULL,
rok_urodzenia MEDIUMINT(4) NOT NULL
)";
$query2 = "INSERT INTO pracownicy VALUES(NULL,'Jan Kowalski',1976);";
$query3 = "SELECT * FROM pracownicy";
$wynik1 = mysql_query($query1, $polaczenie);
$wynik2 = mysql_query($query2, $polaczenie);
$wynik3 = mysql_query($query3, $polaczenie);
...
...
?>
Powyższy fragment należy oczywiście uzupełnić o zmienne definiujące nazwę bazy, host bazy, użytkownika i jego hasło. Należy także dokonać połączenia i wybrać bazę danych. Te fragmenty powinny się znaleźć w miejscu, gdzie umieściłem trzy kropki na początku skryptu. Trzy kropki na końcu, to miejsce, gdzie wstawimy fragment kodu odpowiedzialny za wyświetlenie wyników. Tym zagadnieniem jednak zajmiemy się w kolejnej części
Zapraszam wkrótce