2006 09 Programowanie i bazy danych [Programowanie]


dla programistów
bazy danych
Programowanie
i bazy danych
Matías Barletta
Tym, którzy zawsze patrzyli z pewnym dystansem na programowanie z użyciem baz danych,
przedstawiamy dzisiaj prosty i praktyczny przepis na to, by zakosztować mocy baz danych w Wolnym
Oprogramowaniu. Piszemy małą aplikację wykorzystującą PHP/MySQL. Pokazujemy też, jak i kiedy
użyć bazy danych.
naczna większość aplikacji potrzebuje prze- Innym przykładem aplikacji używających systemu
chowywać dane. Mogą to być maile, pliki, re- plików jako sposobu przechowywania informacji są usłu-
kordy i wszelkiego rodzaju dane, które nadają gi linuksowe, takie jak serwer internetowy Apache, któ-
Zsię do przetwarzania. Ogólnie, na małą skalę, ry przechowuje swoją konfigurację w pliku httpd.conf, czy
aplikacje wykorzystują system plików za pośrednictwem też serwer X.org (plik xorg.conf) i wiele innych programów
funkcji fopen()/fread()/fwrite() (albo analogiczne, w zależ- przechowujących swoje konfiguracje w plikach znajdują-
ności od użytego języka). cych się w katalogu /etc.
Zastosowanie systemu plików do przechowywania da- W takich przypadkach równie pożytecznym pomy-
nych jest proste, szybkie i praktyczne dla prostych zadań słem jest użycie plików tekstowych, biorąc pod uwagę,
lub aplikacji, które nie wymagają mechanizmów baz da- że plik może być zmieniany przez użytkowników sys-
nych (o których to mechanizmach wkrótce). temu tak za pomocą aplikacji, której jest własnością, jak
Wyobrazmy sobie, na przykład, że napisaliśmy pro- i poprzez edytor tekstu. Szczegółem wartym wzmian-
gram do obsługi naszej książki adresowej. Nasz prog- ki jest tu fakt, że takie pliki są zazwyczaj małe, nie za-
ram zawiera formularz do wpisywania nowych kontak- wierają wielu danych i nie są poddawane mnóstwu
tów, inny formularz do modyfikowania/usuwania ist- zmian.
niejących wpisów oraz jeszcze jeden do wypisywania Zauważyliśmy właśnie pewną niezwykle ważną rzecz,
wszystkich rekordów. Na pierwszy rzut oka widzimy, która po części określa użycie plików do przechowywa-
że najbardziej praktycznym sposobem na napisanie tego nia danych. Chodzi o to, że aplikacje używające takiego
programu jest zapisywanie danych do plików i wchodze- mechanizmu przechowywania nie potrzebują utrzymy-
nie do nich pózniej w celu dokonania zmian. W ten spo- wać ciągłego dostępu do wspomnianych plików, nie gro-
sób otrzymujemy książkę, która przechowuje dane w pli- madzą także niezmiernych ilości danych, a przede wszyst-
kach. kim - zebrane dane nie zmieniają się zbyt często.
62 wrzesień 2006
autorzy@lpmagazine.org
dla programistów
bazy danych
W części, do której zaraz przejdziemy wi- numerów telefonów naszych kontaktów Tabela1: Kontakty
dzimy część pliku używanego przez środo- te, które zaczynają się od cyfry 9, będzie-
ID ImiÄ™ Nazwiskoi
wisko graficzne KDE, do przechowywania my zmuszeni do przeczytania całego pli-
1000 Natalie Bonita
części swojej konfiguracji. Plik ma strukturę ku i przeanalizowania go część za częścią,
1001 Angelina Hot
łatwą do odczytu, po to, by można było go wiedząc jednak, że jest mnóstwo informa-
bezpośrednio edytować. cji do przeczytania i że nie są to nawet nu-
Tabela 2: Telefony
Analizując strukturę tego pliku zauwa- mery telefonów!;
ID CONTACT_ID Numer
żamy, że posiada ustalony sposób organizacji " Dostępność i bezpieczeństwo. Jeśli chcemy,
101 1000 541-9123
i format, zdefiniowany i używany przez apli- żeby inne aplikacje miały dostęp do na-
102 1001 981-1230
kację. Oznacza to, że kiedy ów sposób orga- szych danych i jednocześnie zależy nam
103 1002 800-123123
nizacji lub format zostaną zmienione, aplika- na zachowaniu ich integralności, powin-
104 1002 231-0932
cja nie rozpozna pliku. Z drugiej strony, jeśli niśmy stworzyć system bezpieczeństwa.
chcielibyśmy żeby inny program zmodyfiko- Czyli napisać jeszcze więcej kodu;
105 1001 859-7665
wał zawartość tego pliku, będzie on musiał " Redundancja danych. Sprawdzenie, czy da-
bardzo dobrze obsługiwać jego format i jego ne, które zachowujemy, nie zostały zapi- " za pomocą pól kluczowych dostarcza na-
sposób organizacji, ponieważ w przeciwnym sane już wcześniej staje się skomplikowa- rzędzia pozwalające uniknąć podwajania
razie zepsuje ten plik. ne; rekordów;
" Skalowalność. Jeśli nasza mała książka ad- " zapewnia integralność odniesień: w ten
[$Version] resowa zamienia się w aplikację do zarzą- sposób, usuwając dany rekord, usuwa się
update_info=kfmclient_3_2.upd: dzania kontaktami, będzie nam potrzebna także rekordy zależne z nim powiązane;
kfmclient_3_2 duża zmiana w kodzie, po to, by rozłożyć " sprzyja normalizacji ponieważ jest najbar-
obciążenie spowodowane przez zapis da- dziej zrozumiały i łatwy w zastosowaniu.
[DistributionListViewColumns] nych pomiędzy różne serwery;
ColumnOrder=0,1,2 " Backup. Nie powinniśmy zapominać, że Jeden obraz mówi więcej niż tysiąc słów, dla-
ColumnWidths=50,48,336 obecnie potrzebujemy regularnych back- tego też Rysunek 1 obrazuje strukturę, jaką
SortAscending=true upów i odzyskiwania informacji bez za- przybrałaby nasza książka telefoniczna.
SortColumn=0 kłócania normalnej pracy systemu. Na tym rysunku widać dwie tabele, z któ-
rych każda przedstawia inną informację rela-
[HTML Settings] Gdy pojawiajÄ… siÄ™ tego rodzaju przypadki, cyjnÄ…. W pierwszej mamy jednostkÄ™ KONTAK-
AutomaticDetectionLanguage=0 zdajemy sobie sprawÄ™ z potrzeby posiadania TY a w drugiej TELEFONY.
DefaultEncoding=ANSI_X3.4-1968 systemu, który umożliwiłby przechowywa- Patrząc na ten rysunek możemy wyjaśnić
nie danych w formie jakiejÅ› struktury, pozwa- termin relacyjne. Odnosi siÄ™ on do relacji po-
[History] lałby na łatwe przeszukiwanie i modyfiko- między wierszami jednej tabeli. W relacyjnych
Directories=file:///,media:/sdc3,media: wałby się bez problemów. Przede wszystkim, bazach danych wiersze lub rekordy tej samej
/sdc34,media:/sdc1/discoF,media: nie chcemy, by wszystkie te zadania przypa- tabeli są powiązane jakościowo. Innymi słowy,
/sdc1/,file://$HOME,file:///usr,file: dły naszej aplikacji. w tabeli KONTAKTY będziemy przechowy-
///lib,file:///home,file:///etc,file: Wówczas właśnie napotykamy relacyjne wać tylko dane kontaktowe, nie mieszając ich
///var,file:///mnt bazy danych, które są ni mniej, ni więcej, jak z telefonami, ponieważ od tego mamy inną ta-
aplikacjami przeznaczonymi wyłącznie do belę, która przechowuje numery telefonów.
Patterns=*,*XP przechowywania danych w formie struktu- Każdy wiersz w tabeli przedstawia rekord
ry. Umożliwiają optymalne ich przeszukiwa- a każdy rekord zawiera rozmaite wartości.
Aby lepiej poznać granice użycia plików do nie oraz rozłożenie obciążenia pracą pomię- W tabeli KONTAKTY mamy całkowitą liczbę
przechowywania i przetwarzania danych, dzy różne rodzaje sprzętu. Zapewniają zdal- 2 rekordów (wygląda na to, że nie mamy wie-
przypuśćmy, że umieszczamy naszą małą ap- ny dostęp, bezpieczeństwo oraz wiele innych lu znajomych), gdzie każdy z tych rekordów
likację na SourceForge (książka adresowa) i na- funkcjonalności, w zależności od wybranego zawiera 3 wartości: imię, nazwisko i wartość
szemu programowi wciąż przybywa użyt- silnika bazy danych. zwaną ID. Jest ona niepowtarzalnym nume-
kowników, a ci proszą o nowe funkcjonalno- rem identyfikacyjnym rekordu i używa się jej,
ści i zaczynamy borykać się z następującymi Bliższe poznanie baz danych aby się do niego jednoznacznie odwołać. Ana-
przeszkodami: Teraz, gdy już wiemy, po co nam baza da- logicznie moglibyśmy powiedzieć, że jest jak
nych i jakie są jej funkcjonalności, wchodzi- adres IP, który identyfikuje konkretny kompu-
" Wydajność. Im większy plik, tym wolniej my w świat relacyjnych baz danych. ter w sieci.
przebiega proces odczytu/zapisu, w mia- Relacyjne bazy danych traktują bazę ja- Skoro każdy z naszych kontaktów jest nie-
rę jak wzrasta liczba użytkowników ma- ko zbiór relacji, w którym każda relacja re- powtarzalny, tabela KONTAKTY będzie za-
jących jednoczesny dostęp do aplikacji, ta prezentowana jest przez tabelę, gdzie w każ- wierała po jednym rekordzie dla każdego zna-
coraz bardziej się zatyka, podczas wyszu- dym wierszu przedstawiany jest z kolei zbiór jomego/znajomej. Za to każdy kontakt może
kiwania, które zależy jednocześnie od wie- wartości określających element rzeczywisto- mieć więcej niż jeden telefon (komórka, pra-
lu pól, programowanie zaczyna robić się ści. Każdy wiersz nazywany jest rekordem, ca, dom, itp.), i dlatego też w drugiej tabeli,
skomplikowane, nie mówiąc już o tym, że a każda kolumna, polem. Model ten zapew- TELEFONY mamy po jednym rekordzie na
wolne. Jeśli chcielibyśmy wyszukać wśród nia następujące korzyści: każdy numer telefonu.
www.lpmagazine.org 63
dla programistów
bazy danych
Gdy przyjrzymy się tej tabeli, zauważymy maszynie działa MySQL, powinniśmy Baza danych dobrze opracowana koncep-
pola ID, KONTAKT_ID i numer. Pole ID speł- uzupełnić pola localhost i Server Hostname, cyjnie lecz zle zaimplementowana technicznie
nia tę samą funkcję, co pierwsza tabela, czyli a następnie wpisać nazwę użytkownika sprawi nam oczywiste trudności, lecz te znaj-
służy do jednoznacznej identyfikacji danego i hasło MySQL. Tym, którzy nie wiedzą, dą rozwiązanie, jeśli ma się trochę doświad-
numeru telefonu. Pole KONTAKT_ID jest tym, że baza danych ma użytkownika i hasło, czenia i Google na wyciągnięcie ręki. Z drugiej
którego użyjemy w celu powiązania danego przypominam, że domyślnym użytkowni- strony, baza zle zaprojektowana koncepcyjnie,
rekordu z jego odpowiednikiem z tabeli KON- kiem jest root, a hasło nie jest ustawione; choć dobrze wykonana technicznie, zwiąże nam
TAKTY. " gdy dotrzemy już do głównego okna Qu- ręce, jako że aplikacja będzie powielała jej po-
W ten sposób możemy zobaczyć, jak nasza ery Browser, stworzymy nową bazę danych rażki.
baza danych będzie przechowywała informa- klikając prawym przyciskiem w zakładkę W miarę jak będzie rosnąć nasze doświad-
cje w formie struktury, zachowując powiązania z napisem Schemata. W roli nazwy użyjemy czenie w rozwijaniu aplikacji wykorzystują-
między nimi. ksiazka_telefoniczna. Jeśli utworzyła się po- cych bazy danych, zdamy sobie sprawę z og-
prawnie, sprawdzamy, czy jej nazwa po- romnej ilości struktur, jakie można nadać bazie
Rozmowa z bazą danych jawia się we wspomnianej zakładce sche- danych. Jedne z nich są bardziej wydajne niż
w języku SQL mata; inne. Napotkamy też aplikacje napisane przez
Wszelka praca z silnikiem bazy danych odby- " naszym następnym krokiem będzie stwo- innych programistów i wiele nauczymy się pa-
wa się za pomocą języka znanego jako SQL; rzenie tabel wewnątrz naszej bazy. Po klik- trząc, jak to zrobili.
czy chodzi o przechowywanie danych, wyszu- nięciu prawym przyciskiem w zakładce W ten sam sposób dostrzeżemy bazy da-
kiwanie ich, modyfikację czy usunięcie, język Schemata naszej bazy wybieramy Create nych niepotrzebnie skomplikowane, zle za-
SQL (Structured Query Lenguage, Strukturalny Table. W nowym oknie uzupełniamy na- projektowane i nieskuteczne, lecz nauczymy
Język Zapytań) jest zawsze w użyciu. zwę pierwszej tabeli KONTAKTY, a w za- się na nich także, jak NIE należy pisać baz.
Strukturalny Język Zapytań (SQL) to stan- kładce poniżej wpisujemy na próbę treść W naszym konkretnym przypadku nie bę-
dardowy język bazodanowy, używany przez następnego rysunku, uważając na to, że dziemy mieli większych problemów z zapro-
różne silniki baz danych (SQLServer, MySQL, gdy wybierzemy typ CHAR powinniśmy jektowaniem bazy danych, biorąc pod uwagę,
Oracle, PostgreSQL, itd.) do wykonywania dodać mu w nawiasie liczbę znaków, ja- że informacje, które chcemy przechować w na-
określonych operacji, przede wszystkim na da- ką powinien przechowywać. W naszym szej bazie nie są skomplikowane, lecz składa-
nych, ale też na ich strukturze. przypadku możemy użyć CHAR(20) dla ją się tylko z nazw i numerów telefonów. Mo-
SQL jest zarazem językiem łatwym do na- pól imię - nazwisko oraz CHAR(30) dla żemy jednak wyobrazić sobie, jak skompliko-
uczenia się i złożonym narzędziem do zarzą- pola telefon. Jeśli nie określimy w nawia- wane może być napisanie aplikacji księgowej,
dzania danymi. Zapytania do bazy danych wy- sie liczby znaków, MySQL przypisze mu administracyjnej czy finansowej, która prze-
rażane są w formie instrukcji, które powinny przestrzeń jednego znaku. chowywałaby informacje z różnych dziedzin,
być napisane zgodnie z zasadami składni oraz powiązane kompletnie na krzyż. Co dopie-
z zachowaniem reguł semantycznych tego ję- Po zakończeniu edycji wciskamy Apply, po ro mówić o aplikacjach dla naukowców, któ-
zyka. czym możemy ujrzeć podsumowanie wyko- re muszą zapamiętać dane klimatyczne. Tam
Zaletą posługiwania się tym językiem nanych operacji. Na ekranie ukazuje się nam złe projektowanie odbije się nieskuteczną pra-
jest możliwość dostępu do wszystkich baz w języku SQL całe zadanie wykonane wcześ- cą aplikacji.
danych obsługujących standard SQL5. niej graficznie. W miarę jak będziemy lepiej po- Z tego powodu krok koncepcyjny jest za-
Użytkownicy Linuksa powinni mieć zain- znawać SQL, będziemy mogli tworzyć tabele zwyczaj krytyczny, choć wielu programistów
stalowanego i działającego Apache'a i MySQL. i definiować pola bez pośrednictwa interfejsu zwraca na niego najmniej uwagi (ucz się, ucz!).
Użytkownicy Windows mogą ściągnąć graficznego, stosując sam tylko SQL. To nie zna- Zazwyczaj, w miarę jak aplikacje rosną, zaczy-
z Internetu maszynę wirtualną zawierającą mi- czy, że MySQL Query Browser nie będzie nam namy zauważać, że były zaprojektowane zle
nimalną wersję Linuksa z zainstalowanym już potrzebny. Przekonamy się, że im więcej do- lub bez wyobrazni.
Apachem i MySQL i odpalić ją za pomocą VM- wiemy się o SQL, tym lepiej będziemy wyko- Nie zniechęcajcie się! Popełnianie błędów
Ware Player. Można ją znalezć na http://www. rzystywać tę aplikację. to część nauki, niemniej jednak cechą charak-
rpath.org/rbuilder/project/lamp/. Wszystko dobrze, jak dotąd napisaliśmy terystyczną dobrych deweloperów i aplika-
MySQL Query Browser jest aplikacją służą- bazę w sposób zadowalający. Teraz czas na cji, które odniosły sukces, jest jasna koncepcja
cą do pisania i wykonywania zapytań SQL za lepsze zrozumienie, co właściwie zrobiliśmy. funkcji spełnianych przez bazę danych.
pomocÄ… interfejsu graficznego. ÅšciÄ…gniemy jÄ…
z http://www.mysql.com/products/tools/query- Projektowanie bazy Rozwój techniczny projektu:
browser/ a następnie zainstalujemy. Najważniejszy krok w zaprojektowaniu bazy Wspomnieliśmy o tym, że gdy tworzy się ta-
Dla uproszczenia sprawy stworzymy ba- danych jest natury koncepcyjnej, a nie tech- belę, powinno się zdefiniować typ danych prze-
zę danych w MySQL według następujących nicznej. chowywanych w każdym z pól. Silnik bazy
kroków: Projektowanie koncepcyjne oznacza okre- danych potrzebuje wiedzieć, jakie dane za-
ślenie, jakie elementy świata rzeczywistego wiera każde pole, po to, by móc zoptymali-
" upewniamy się, że działa u nas usługa My- zostaną przedstawione i powiązane w relacje. zować wyszukiwanie i przechowywanie da-
SQL; Projektowanie fizyczne bazy danych wy- nych.
" uruchamiamy MySQL Query Browser znacza tabele, które się na nią złożą, pola, jakie Każde pole w tabeli będzie mogło pomie-
i uzupełniamy dane połączenia. Na przyk- będzie zawierać każda z tabel, a także typ da- ścić dane tylko jednego typu. Do najpowszech-
ład, jeśli jesteśmy w Linuksie a na naszej nych zawartych w każdym polu. niejszych typów należą:
64 wrzesień 2006
dla programistów
bazy danych
byłoby przykładem złego projektowania. " NOT NULL (Niepuste) Pola opatrzone tą
Listing 1. Formularz
Kto z nas nie ma znajomych o takim sa- opcją nie będą nigdy mogły zawierać tyl-
mym imieniu, a nawet nazwisku. Dlatego ko zera ani być puste. Jeśli chcemy zapisać
zazwyczaj dopisujemy opcję PK do pola, rekord i nie przypiszemy wartości dla po-
"dodaj_znajomego.php"> rzało. Jeśli przypadnie nam w udziale na- nych wyrzuci błąd. Na przykład, jeśli defi-
Imie : "Text" name="imie">
szpitala, możemy wybrać jako PK pole od- silnik bazy nie pozwoli na tworzenie re-
Nazwisko: "Text" name="nazwisko">
wodu osobistego, ponieważ i tak wiemy, nych wartości w polu Nazwisko. W ten
Telefon1 : "Text" name="telefon1">
kraju. Dodatkowo też zapewnilibyśmy nie- ju bazy wymuszamy stałą obecność pew-
Telefon2 : "Text" name="telefon2">
suje ponownie osobę, która jest już w sys- " AutoIncrement (Automatyczna numeracja).
"Zapisz" value="Zapisz"> du do bazy danych otrzyma komunikat uzupełnione automatycznie przez bazę da-
o błędzie silnika i program przypomni, że nych w chwili utworzenia rekordu. W na-
taka osoba nie istnieje. Aatwe, prawda? Wy- szym projekcie bazy wybieramy pola ID
obrazcie sobie, że zaprogramowaliście sa- jako AutoIncrement. Gdy dodamy pierw-
mi cały algorytm wyszukiwania, żeby za- szy rekord, baza wpisze numer w pole te-
" CHAR do przechowywania znaków alfa- gwarantować niepodwajanie się rekor- go rekordu.
numerycznych; dów. Można zrobić to za pomocą bazy da-
" INT przechowuje liczby całkowite; nych, pytając po prostu czy istnieje taki SQL i jeszcze raz SQL
" DATE przechowuje daty/godziny. numer; Czas już przekonać się, jak łatwy do nauki
" UNSIGNED (Niepodpisane). Stosowanie jest SQL, przez co osiÄ…gniemy lepszÄ… interak-
Istnieje wiele typów danych, są też silniki baz tej opcji jest poprawne tylko wobec pól cję z naszymi danymi.
danych, które obsługują ich więcej niż inne. liczbowych i odbywa się w celu zdefinio- Jeśli spojrzymy ponownie na Rysunek 1,
Aby dowiedzieć się, co udostępnia MySQL, wania użycia w danym polu tylko liczb ujrzymy rekordy każdej z tabel wraz z ich
możemy zobaczyć listę typów wybierając Da- dodatnich. Na przykład, pole zdefiniowa- wartościami. Ten widok tabeli ze wszystkimi
ta Type w menu kontekstowym. ne jako typu INT mogłoby pomieścić nu- jej rekordami możemy uzyskać pózniej także
Znając już dostępne typy danych powin- mery od -2147483648 do 2147483647. Je- z poziomu aplikacji MySQL.
niśmy wybrać typ odpowiedni dla każdego śli zdefiniujemy to pole jako UNSIGNED, Jeśli chcielibyśmy teraz poprosić bazę da-
pola, na przykład, w naszych tabelach użyje- wartości, które można by w nim zapisać nych o poszukanie w naszej książce kontak-
my dwóch typów danych. Pierwszym będzie pochodziłyby z przedziału od 0 do 429 tów, które mają na nazwisko Hot użylibyśmy
CHAR, który zastosujemy do przechowania 4967295. Jeśli chcemy zapisywać wyższe następującego pseudokodu:
wartości Imię i Nazwisko. Drugim będzie INT, wartości, musimy użyć innych opcji. Przy-
który przyda nam się do zapisania numeru ID pomina to typy danych używane w pro- szukaj w tabeli KONTAKTY rekordów
danego rekordu. gramowaniu; z Nazwisko= Hot .
Jeśli zastanawiacie się, czemu nie użyć
typu INT dla numerów telefonu, odpowiedz
brzmi: nie powinny być przechowywane jako
numery, ponieważ zawierają spacje albo myśl-
niki.
Istnieje więcej opcji dostępnych podczas
definiowania pola. Wiele z nich odkryjemy je-
dynie gdy wzrosną nasze możliwości projek-
towania baz danych. Zaprezentujemy jednak
najważniejsze i najbardziej użyteczne z nich
wszystkich.
" Primary Key. Gdy wybierzemy tÄ™ opcjÄ™
dla jakiegoÅ› pola, wskazujemy silnikowi
naszej bazy, że chcemy, żeby zawierało
ono niepowtarzalną wartość. Na przyk-
ład, jeśli polu Imię nadamy opcję Prima-
ry Key (PK lub klucz główny) baza da
nych upewni się, żeby podczas tworzenia
rekordów z naszymi kontaktami nie było
osób o takim samym imieniu. Coś takiego Rysunek 1. Edytor tabel
www.lpmagazine.org 65
dla programistów
bazy danych
Tabela 3: Kontakty
W języku SQL: określony w tym słowie. Na przykład, SELECT,
INSERT, DELETE mówią same za siebie, służą
ID Nazwisko ImiÄ™
select * from TELEFONY where do wybierania (wyszukiwania) danych, doda-
1 Z Jones
kontakt_id= 1001 . wania nowych lub ich usuwania. W SQL waż-
Tabela 4: Telefony
ne jest, by jasno wiedzieć, co chce się osiągnąć,
ID CONTACT_ID Numer Możemy tu zobaczyć, że z Angeliną Hot a dokładną składnię można wydobyć używa-
(KONTAKT_ID=1001) jest powiązanych wie- jąc podręcznika i gromadząc doświadczenie.
1 1 800-333-1112
le rekordów. W tym przypadku dodamy rekordy do na-
2 1 615-123-1234
szych tabel. Użyjemy w tym celu następują-
Ten pseudokod jest krokiem pośrednim Zapisywanie danych przez SQL cego polecenia:
w stronę prawdziwej składni SQL. Wiemy już, jak stworzyć bazę, a także jak wy-
szukiwać w niej dane i wydobywać wyniki insert into KONTAKTY set imie= Z ,
select * from KONTAKTY where za pomocÄ… SQL. Brakuje nam tylko wiedzy o nazwisko= jones
nazwisko= Hot przechowywaniu danych.
Język SQL jest bogaty i zawiera wiele in- Aby sprawdzić, czy to polecenie działa, wy-
Poprzednie zdanie to typowe zapytanie SQL strukcji, lecz i tak te, które najbardziej nam się pisujemy instrukcję w górnej zakładce MySQL
rozpoczynające się od {select *} to znaczy  Wy- przydadzą związane będą z przechowywa- Query Browser.
bierz wszystkie kolumny , za którym idzie niem i wyszukiwaniem informacji. Po wpisaniu instrukcji, klikamy w przy-
{from KONTAKTY}, co tłumaczy się jako  z ta- Pozytywną cechą aplikacji MySQL jest cisk EXECUTE. Ta czynność wyśle polecenie
beli Kontakty a zamyka je klauzula {WHERE jej podręcznik, zawierający składnię każde- do bazy danych i jeśli wszystko pójdzie do-
apellido= Hot } zapewniając, że pole  nazwi- go polecenia, jak również przykłady jego brze, w lewym dolnym rogu pojawi się tekst
sko jest równe tekstowi  Hot . użycia. Większość instrukcji SQL rozpoczyna- Query executed in 0:00:XX, czyli  instrukcję
Klauzula WHERE ma duże znaczenie jako ją się jednym słowem i zazwyczaj rozwijają cel wykonano w ciągu XX sekund .
część instrukcji wyszukiwania, ponieważ zaj-
muje się filtrowaniem wyniku. Jeśli nie napi- Listing 2. Dodanie znajomego
szemy WHERE, instrukcja SELECT idzie do
tabeli KONTAKTY, wybiera kolumny, jakie
chcieliśmy (w naszym przypadku wpisaliśmy
gwiazdkę (*), żeby uwzględniła wszystkie ko- lumny) i przyniesie nam w wyniku wszystkie //Otwórz połączenie z bazą danych
rekordy, jakie zawiera ta tabela. Wariantem po- $polaczenie = mysql_connect("localhost", "root");
przedniego wyszukiwania mogłoby być: //Wybierz bazę
mysql_select_db("ksiazka_adresowa",$polaczenie);
select nazwisko,id from KONTAKTY //Wpisz zapytanie SQL
where nazwisko= Hot $sql_wstaw="insert into KONTAKTY set imie='" . $_POST ["imie"] . "',
nazwisko='" . $_POST["nazwisko"] . "'";
Tym razem wynik był inny, kolumny musiały //Wstaw dane
odpowiedzieć na dyspozycję, jaką wydaliśmy $result=mysql_query($sql_wstaw);
dla ich pól (select nazwisko, id), dlatego też naj- //Sprawdzamy w bazie, czy automatyczny ID spotkał już wcześniej wstawiony
pierw przyszło nazwisko i dopiero potem id //rekord.
a skoro nie wpisaliśmy pola imię, ta kolumna $id_nowy_kontakt=mysql_insert_id();
nie pojawiła się w żadnym z rekordów zwró- //Tworzymy następne zapytanie SQL, aby zapisać numery telefonów
conych przez instrukcjÄ™ SELECT. //pod nowym ID.
Spójrzmy na inny przykład. Jeśli chcieli- $sql2_wstaw="insert into TELEFONY set TELEFON='". $_POST['telefon1'].
byśmy uzyskać wszystkie numery telefonów "',KONTAKT_ID='". $id_nowy_kontakt . "'" ;
Angeliny Hot z tabeli TELEFONY, jako pseu- //Zapisujemy pierwszy numer telefonu.
dokod mielibyśmy: $result2=mysql_query($sql2_wstaw);
//Zwracamy uwagę, czy telefon2 był już wstawiony do bazy, jeśli nie,
szukaj w tabeli TELEFONY rekordów //wpisujemy ten numer.
z kontakt_id=1001 . if (!$_POST["telefon2"] == "") {
$sql3_wstaw="insert into TELEFONY set TELEFON='".
Jeśli zadaliście sobie pytanie, dlaczego użyli- $_POST['telefon2']. "',KOTAKT_ID='". $id_nowy_kontakt . "'" ;
śmy pola KONTAKT_ID jako filtra, przypomi- $result3=mysql_query($sql3_wstaw);
nam wam, że jest to pole, które wybraliśmy, }
aby powiązać pola KONTAKTY i TELEFONY.
Dlatego też powinniśmy poznać jedyny i nie- echo "Dane zachowane!";
powtarzalny numer Angeliny Hot, a następnie echo "
Zobacz listę kontaktów ";
na podstawie tego numeru przefiltrować od- ?>
powiadające mu numery telefonów.
66 wrzesień 2006
dla programistów
bazy danych
działa znakomicie. Rozszerzenia MySQL dla
PHP. Niektóre dystrybucje Linuksa nie obsłu-
gują MySQL w PHP, albo też trzeba tę obsłu-
gę doinstalować osobno. Pozbędziemy się wąt-
pliwości wykonując tę samą procedurę, co
we wcześniejszym punkcie i sprawdzamy, czy
jest wzmianka o MySQL na stronie wyniko-
wej. Jeśli PHP obsługuje bazy danych, pojawi
się cała seria konfiguracji tego rozszerzenia.
Znajomość koncepcji HTTP POST/GET.
Nie musicie wiedzieć, jak działa, bit po bicie,
ale wystarczy pamiętać, że jest mechanizmem
protokołu HTTP służącym do wysyłania infor-
macji z klienta na serwer.
Pobierzmy dane za pomocÄ… bardzo pros-
tego formularza: tak, drodzy Czytelnicy, to
właśnie mało estetyczny i bardzo funkcjonalny
formularz, zawierajÄ…cy tylko to, co potrzebne,
aby dodać kontakt. Wierzę, że użyjecie swo-
ich zdolności artystycznych dodając mu kształ-
tu i koloru.
Jak widzimy, formularz wysyła dane z pól
Rysunek 2. Komenda SQL
za pomocÄ… HTTP POST do drugiego pliku ap-
Jeśli chcemy dowiedzieć się, czy udało nam Wymagania: likacji, dodaj_znajomego.php, którego zadaniem
się dodać nowy rekord, możemy wykonać któ- Współpracujący z PHP serwer HTTPD Apa- jest dodanie naszego nowego kontaktu do ba-
rąś w wcześniejszych instrukcji wyszukiwa- che. Aby dowiedzieć się, czy PHP działa po- zy danych. Powyższy plik zawiera polecenia
nia: prawnie, możecie utworzyć plik w katalogu PHP związane z obsługą MySQL, które zaraz
głównym, gdzie Apache przechowuje strony wyjaśnimy.
select * from KONTAKTY (/srv/www/htdocs w SuSE, /var/www/html w Red-
Hat), który będzie się nazywał test.php i któ- $polaczenie = mysql_connect( SERWER ,
Możemy tu zauważyć, że nie użyliśmy klau- rego treścią będzie jedynie .  UŻYTKOWNIK ,  HASAO )
zuli WHERE, co sprawia, że instrukcja SE- Pózniej skierujcie swoją przeglądarkę na trop
LECT działa bez filtra, przez co pokażą nam tego pliku, http://localhost/test.php, i jeśli zwró- To polecenie tworzy połączenie z serwerem
się wszystkie kolumny (select *) wszystkich ci wam stronę z informacją o PHP, wszystko MySQL, który identyfikuje się jako SERWER
rekordów (brak klauzuli WHERE) tabeli CON-
TACTS.
Zapiszemy teraz numery telefonów na-
szego nowego kontaktu Z Jones. Ponieważ
nasza przyjaciółka Z Jones jest bardzo zainte-
resowana rozmową z nami, podała nam dwa
numery telefonu  numer na komórkę i nu-
mer domowy.
Zanim będziemy mogli dodać dane powin-
niśmy sprawdzić, jaki ID przypada kontaktowi
zwanemu Z Jones. Możemy wyczytać to z wy-
niku wcześniejszej instrukcji.
insert into TELEFONY set
kontakt_id=1, numer= 800-333-1112
insert into TELEFONY set
kontakt_id=1, numer= 615-123-1234
Mamy teraz rekord w KONTAKTACH, do któ-
rego należą dwa rekordy z TELEFONÓW.
Gratulacje! Udało nam się przejść przez
najbardziej męczącą część, teraz musimy tylko
uzbroić naszą małą aplikację w PHP, co jest
bardzo proste, biorąc pod uwagę, że użyjemy
Rysunek 3. MySQL Query Browser
wszystkich domyślnych narzędzi PHP.
www.lpmagazine.org 67
dla programistów
bazy danych
używając nazwy użytkownika i hasła, które który zwraca, jest macierz z wierszami wyni- tuje wiersze dopóki nie spotka już żadnych
przyznaje się pózniej. Jeśli nie dodamy zmien- kowymi tego zapytania. więcej.
nej HASAO, połączenie zostanie nawiązane Wykonując to polecenie możemy zobaczyć
z nazwą użytkownika, ale bez hasła: $id=mysql_insert_id() wartość każdej kolumny tego rekordu w nastę-
pujący sposób:
mysql_select_db ( NAZWA_BD , To polecenie zwraca nam wartość przypisaną
 POLACZENIE ) przez MySQL polu autoincrement. W ten spo- $wiersz[nazwa_kolumna]
sób możemy użyć jego numeru ID aby powią-
Powinniśmy wskazać silnikowi bazy danych, zać je z innymi tabelami. W naszym przypadku możemy dotrzeć do
z jakimi bazami chcemy pracować (np.ksiaz- Ten ostatni plik dostarcza nam listę wszyst- wartości pola telefon wpisując:
ka_telefoniczna). To polecenie wymaga nie tyl- kich rekordów z bazy. Użyliśmy w nim jeszcze
ko nazwy bazy, lecz także odwołania do połą- jednego nowego polecenia: $wiersz[telefon].
czenia (jest obiektem zwracanym przy nawiÄ…-
zaniu połączenia, w naszym przypadku chodzi $wiersz=mysql_fetch_assoc($result) Dalsze informacje!
o zmiennÄ… $polaczenie). Programy wykorzystujÄ…ce bazy danych zaj-
Zapytania zwracają macierz, którą możemy po- mują bardzo szeroki obszar. Bylibyśmy zach-
$result=mysql_query dzielić na wiersze, czy rekordy, za pomocą te- wyceni mogąc wyliczać rozmaite dostępne na-
( INSTRUKCJA SQL ) go polecenia. Odczytuje ono jeden z wierszy rzędzia, jak też i różne sposoby pracy z nimi,
i wstawia go do zmiennej $wiersz, a potem lecz zostawiam was samych z tym zadaniem,
To polecenie jest odpowiedzialne za wyko- przechodzi do następnego (jeśli istnieje). My podając w tym celu kilka bardzo ciekawych
nanie zapytania do bazy danych, a obiektem, użyliśmy tego polecenia w pętli, która odczy- linków:
Listing 3. Numer ID w tabelach
Na temat SQL
SQL to bardzo duży i ciekawy świat. Oto link

do Wikipedii, które powie wam o nim więcej:

http://es.wikipedia.org/wiki/SQL. Nie zapominaj-
cie też, że w manualu MySQL Query Browser
//Pokaż funkcję pliku
opisane jest każde pojęcie SQL!
print "Lista Znajomych

";
echo "Nazwisko - Imie - Telefony

";
Programowanie obiektowe baz danych
//Otwórz połączenie z bazą danych
AdoDB dla PHP. To warstwa abstrakcji pozwa-
$polaczenie = mysql_connect("localhost", "root");
lająca na obsługę zapytań i połączeń do bazy
//Wybierz bazÄ™
danych za pomocą typowych obiektów, po-
mysql_select_db("ksiazka_telefoniczna",$polaczenie);
zwalajÄ…ca na wykorzystanie tego samego ko-
//Wstaw zapytanie do zmiennej
du przez różne siniki baz danych.
$sql = "select * from KONTAKTY";
PEAR PHP: To zbiór rozszerzeń i aplika-
//Wykonaj zapytanie i zapisz wynik w zmiennej $result
cji, które można zastosować powtórnie w PHP,
$result=mysql_query($sql);
bardzo godny polecenia. Znajdziecie go na
//Rozpocznij wykonywanie pętli, żeby wypisać każdy wiersz wyniku.
http://pear.php.net. WewnÄ…trz zbioru znajdujÄ… siÄ™
while ($wiersz1=mysql_fetch_assoc($result)) {
rozszerzenia dla baz danych podobne do Ado-
echo $wiersz1[nazwisko];
DB.
echo " , ";
SQLObjects dla Pythona. To bardzo ciekawa
echo $wiersz1[nazwisko];
warstwa abstrakcji, nie używa się w niej ani
echo " , Telefony: ";
jednej instrukcji SQL, a jedynie obsługę obiek-
//Teraz piszemy zapytanie SQL żeby wyszukać informacje o numerach
tów! Obsługuje różne silniki bazodanowe i mo-
//telefonu naszego Kontaktu.
żna ją znalezć na http://www.sqlobject.org.
$sql2="select telefon from TELEFONY where KONTAKT_ID=" . $wiersz1[ID];
//Wykonaj SQL
Inne programy
$result2=mysql_query($sql2);
Przekonaliśmy się w tym artykule, że MySQL
// Druga pętla, która wypisuje wszystkie numery związane z naszym Kontaktem.
Query Browser przydaje siÄ™ bardzo i pozwala
while ($wiersz2=mysql_fetch_assoc($result2)) {
nam ujrzeć graficznie wiele informacji, spraw-
echo $wiersz2[telefon];
dzajÄ…c w tym czasie nasze instrukcje SQL oraz
echo " , ";
szybko i sprawnie oczyszczajÄ…c kod. Poda-
}
jÄ™ wam tutaj link do innej podobnej aplikacji,
echo "
";
która od poprzedniej różni się tym, że pozwala
}
na połączenie z różnymi silnikami (Oracle, Post-
?>
greSQL, MySQL, itd.) oraz przeglÄ…danie danych

z różnych baz i silników jednocześnie: http://

squirrel-sql.sourceforge.net/.
68 wrzesień 2006


Wyszukiwarka

Podobne podstrony:
2004 09 Kexi bazy danych [Bazy Danych]
2007 09 PostgreSQL [Bazy Danych]
Bazy Danych Język Zapytań SQL Programowanie Proceduralne
09 Efektywne przeszukiwanie danych w programie Access
Bazy danych postgreSQL programowanie i implementacja
Instalacja bazy danych Plexiform do programu DIALux
DNAStat wersja 2 1 – program do obsługi bazy danych profili genetycznych oraz do obliczeń biostatyst
09 Programowanie w środowisku języka obiektowegoidy84
2006 02 Program koncepcyjny
09 Programowanie sterownika PLC
BAZY DANYCH Streszczenie z wykładów
2006 09 Wielozadaniowość w systemach operacyjnych [Inzynieria Oprogramowania]

więcej podobnych podstron