2006.09_Programowanie i bazy danych_[Programowanie].pdf

(874 KB) Pobierz
439114436 UNPDF
dla programistów
bazy danych
Programowanie
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.
chowywać dane. Mogą to być maile, pliki, re-
kordy i wszelkiego rodzaju dane, które nadają
się do przetwarzania. Ogólnie, na małą skalę,
aplikacje wykorzystują system plików za pośrednictwem
funkcji fopen() / fread() / fwrite() (albo analogiczne, w zależ-
ności od użytego języka).
Zastosowanie systemu plików do przechowywania da-
nych jest proste, szybkie i praktyczne dla prostych zadań
lub aplikacji, które nie wymagają mechanizmów baz da-
nych (o których to mechanizmach wkrótce).
Wyobraźmy sobie, na przykład, że napisaliśmy pro-
gram do obsługi naszej książki adresowej. Nasz prog-
ram zawiera formularz do wpisywania nowych kontak-
tów, inny formularz do modyikowania/usuwania ist-
niejących wpisów oraz jeszcze jeden do wypisywania
wszystkich rekordów. Na pierwszy rzut oka widzimy,
że najbardziej praktycznym sposobem na napisanie tego
programu jest zapisywanie danych do plików i wchodze-
nie do nich później w celu dokonania zmian. W ten spo-
sób otrzymujemy książkę, która przechowuje dane w pli-
kach.
Innym przykładem aplikacji używających systemu
plików jako sposobu przechowywania informacji są usłu-
gi linuksowe, takie jak serwer internetowy Apache, któ-
ry przechowuje swoją konigurację w pliku httpd.conf , czy
też serwer X.org (plik xorg.conf ) i wiele innych programów
przechowujących swoje koniguracje w plikach znajdują-
cych się w katalogu /etc .
W takich przypadkach równie pożytecznym pomy-
słem jest użycie plików tekstowych, biorąc pod uwagę,
że plik może być zmieniany przez użytkowników sys-
temu tak za pomocą aplikacji, której jest własnością, jak
i poprzez edytor tekstu. Szczegółem wartym wzmian-
ki jest tu fakt, że takie pliki są zazwyczaj małe, nie za-
wierają wielu danych i nie są poddawane mnóstwu
zmian.
Zauważyliśmy właśnie pewną niezwykle ważną rzecz,
która po części określa użycie plików do przechowywa-
nia danych. Chodzi o to, że aplikacje używające takiego
mechanizmu przechowywania nie potrzebują utrzymy-
wać ciągłego dostępu do wspomnianych plików, nie gro-
madzą także niezmiernych ilości danych, a przede wszyst-
kim - zebrane dane nie zmieniają się zbyt często.
62
wrzesień 2006
i bazy danych
Z naczna większość aplikacji potrzebuje prze-
439114436.035.png 439114436.036.png 439114436.037.png
 
dla programistów
bazy danych
W części, do której zaraz przejdziemy wi-
dzimy część pliku używanego przez środo-
wisko graiczne KDE, do przechowywania
części swojej koniguracji. Plik ma strukturę
łatwą do odczytu, po to, by można było go
bezpośrednio edytować.
Analizując strukturę tego pliku zauwa-
żamy, że posiada ustalony sposób organizacji
i format, zdeiniowany i używany przez apli-
kację. Oznacza to, że kiedy ów sposób orga-
nizacji lub format zostaną zmienione, aplika-
cja nie rozpozna pliku. Z drugiej strony, jeśli
chcielibyśmy żeby inny program zmodyiko-
wał zawartość tego pliku, będzie on musiał
bardzo dobrze obsługiwać jego format i jego
sposób organizacji, ponieważ w przeciwnym
razie zepsuje ten plik.
numerów telefonów naszych kontaktów
te, które zaczynają się od cyfry 9, będzie-
my zmuszeni do przeczytania całego pli-
ku i przeanalizowania go część za częścią,
wiedząc jednak, że jest mnóstwo informa-
cji do przeczytania i że nie są to nawet nu-
mery telefonów!;
Dostępność i bezpieczeństwo . Jeśli chcemy,
żeby inne aplikacje miały dostęp do na-
szych danych i jednocześnie zależy nam
na zachowaniu ich integralności, powin-
niśmy stworzyć system bezpieczeństwa.
Czyli napisać jeszcze więcej kodu;
Redundancja danych . Sprawdzenie, czy da-
ne, które zachowujemy, nie zostały zapi-
sane już wcześniej staje się skomplikowa-
ne;
Skalowalność . Jeśli nasza mała książka ad-
resowa zamienia się w aplikację do zarzą-
dzania kontaktami, będzie nam potrzebna
duża zmiana w kodzie, po to, by rozłożyć
obciążenie spowodowane przez zapis da-
nych pomiędzy różne serwery;
Backup . Nie powinniśmy zapominać, że
obecnie potrzebujemy regularnych back-
upów i odzyskiwania informacji bez za-
kłócania normalnej pracy systemu.
Tabela1: Kontakty
ID Imię Nazwiskoi
1000 Natalie Bonita
1001 Angelina Hot
Tabela 2: Telefony
ID CONTACT_ID Numer
101 1000 541-9123
102 1001 981-1230
103 1002 800-123123
104 1002 231-0932
105 1001 859-7665
• za pomocą pól kluczowych dostarcza na-
rzędzia pozwalające uniknąć podwajania
rekordów;
• zapewnia integralność odniesień: w ten
sposób, usuwając dany rekord, usuwa się
także rekordy zależne z nim powiązane;
• sprzyja normalizacji ponieważ jest najbar-
dziej zrozumiały i łatwy w zastosowaniu.
[$Version]
update_info=kfmclient_3_2.upd:
kfmclient_3_2
[DistributionListViewColumns]
ColumnOrder=0,1,2
ColumnWidths=50,48,336
SortAscending=true
SortColumn=0
Jeden obraz mówi więcej niż tysiąc słów, dla-
tego też Rysunek 1 obrazuje strukturę, jaką
przybrałaby nasza książka telefoniczna.
Na tym rysunku widać dwie tabele, z któ-
rych każda przedstawia inną informację rela-
cyjną. W pierwszej mamy jednostkę KONTAK-
TY a w drugiej TELEFONY .
Patrząc na ten rysunek możemy wyjaśnić
termin relacyjne. Odnosi się on do relacji po-
między wierszami jednej tabeli. W relacyjnych
bazach danych wiersze lub rekordy tej samej
tabeli są powiązane jakościowo. Innymi słowy,
w tabeli KONTAKTY będziemy przechowy-
wać tylko dane kontaktowe, nie mieszając ich
z telefonami, ponieważ od tego mamy inną ta-
belę, która przechowuje numery telefonów.
Każdy wiersz w tabeli przedstawia rekord
a każdy rekord zawiera rozmaite wartości.
W tabeli KONTAKTY mamy całkowitą liczbę
2 rekordów (wygląda na to, że nie mamy wie-
lu znajomych), gdzie każdy z tych rekordów
zawiera 3 wartości: imię , nazwisko i wartość
zwaną ID . Jest ona niepowtarzalnym nume-
rem identyikacyjnym rekordu i używa się jej,
aby się do niego jednoznacznie odwołać. Ana-
logicznie moglibyśmy powiedzieć, że jest jak
adres IP , który identyikuje konkretny kompu-
ter w sieci.
Skoro każdy z naszych kontaktów jest nie-
powtarzalny, tabela KONTAKTY będzie za-
wierała po jednym rekordzie dla każdego zna-
jomego/znajomej. Za to każdy kontakt może
mieć więcej niż jeden telefon (komórka, pra-
ca, dom, itp.), i dlatego też w drugiej tabeli,
TELEFONY mamy po jednym rekordzie na
każdy numer telefonu.
[HTML Settings]
AutomaticDetectionLanguage=0
DefaultEncoding=ANSI_X3.4-1968
Gdy pojawiają się tego rodzaju przypadki,
zdajemy sobie sprawę z potrzeby posiadania
systemu, który umożliwiłby przechowywa-
nie danych w formie jakiejś struktury, pozwa-
lałby na łatwe przeszukiwanie i modyiko-
wałby się bez problemów. Przede wszystkim,
nie chcemy, by wszystkie te zadania przypa-
dły naszej aplikacji.
Wówczas właśnie napotykamy relacyjne
bazy danych, które są ni mniej, ni więcej, jak
aplikacjami przeznaczonymi wyłącznie do
przechowywania danych w formie struktu-
ry. Umożliwiają optymalne ich przeszukiwa-
nie oraz rozłożenie obciążenia pracą pomię-
dzy różne rodzaje sprzętu. Zapewniają zdal-
ny dostęp, bezpieczeństwo oraz wiele innych
funkcjonalności, w zależności od wybranego
silnika bazy danych.
[History]
Directories=ile:///,media:/sdc3,media:
/sdc34,media:/sdc1/discoF,media:
/sdc1/,ile://$HOME,ile:///usr,ile:
///lib,ile:///home,ile:///etc,ile:
///var,ile:///mnt
Patterns=*,*XP
Aby lepiej poznać granice użycia plików do
przechowywania i przetwarzania danych,
przypuśćmy, że umieszczamy naszą małą ap-
likację na SourceForge (książka adresowa) i na-
szemu programowi wciąż przybywa użyt-
kowników, a ci proszą o nowe funkcjonalno-
ści i zaczynamy borykać się z następującymi
przeszkodami:
Bliższe poznanie baz danych
Teraz, gdy już wiemy, po co nam baza da-
nych i jakie są jej funkcjonalności, wchodzi-
my w świat relacyjnych baz danych.
Relacyjne bazy danych traktują bazę ja-
ko zbiór relacji, w którym każda relacja re-
prezentowana jest przez tabelę, gdzie w każ-
dym wierszu przedstawiany jest z kolei zbiór
wartości określających element rzeczywisto-
ści. Każdy wiersz nazywany jest rekordem,
a każda kolumna, polem. Model ten zapew-
nia następujące korzyści:
Wydajność . Im większy plik, tym wolniej
przebiega proces odczytu/zapisu, w mia-
rę jak wzrasta liczba użytkowników ma-
jących jednoczesny dostęp do aplikacji, ta
coraz bardziej się zatyka, podczas wyszu-
kiwania, które zależy jednocześnie od wie-
lu pól, programowanie zaczyna robić się
skomplikowane, nie mówiąc już o tym, że
wolne. Jeśli chcielibyśmy wyszukać wśród
www.lpmagazine.org
63
439114436.001.png 439114436.002.png 439114436.003.png 439114436.004.png 439114436.005.png 439114436.006.png 439114436.007.png 439114436.008.png 439114436.009.png 439114436.010.png 439114436.011.png 439114436.012.png 439114436.013.png
 
dla programistów
bazy danych
Gdy przyjrzymy się tej tabeli, zauważymy
pola ID , KONTAKT_ID i numer. Pole ID speł-
nia tę samą funkcję, co pierwsza tabela, czyli
służy do jednoznacznej identyikacji danego
numeru telefonu. Pole KONTAKT_ID jest tym,
którego użyjemy w celu powiązania danego
rekordu z jego odpowiednikiem z tabeli KON-
TAKTY.
W ten sposób możemy zobaczyć, jak nasza
baza danych będzie przechowywała informa-
cje w formie struktury, zachowując powiązania
między nimi.
maszynie działa MySQL, powinniśmy
uzupełnić pola localhost i Server Hostname ,
a następnie wpisać nazwę użytkownika
i hasło MySQL. Tym, którzy nie wiedzą,
że baza danych ma użytkownika i hasło,
przypominam, że domyślnym użytkowni-
kiem jest root , a hasło nie jest ustawione;
• gdy dotrzemy już do głównego okna Qu-
ery Browser , stworzymy nową bazę danych
klikając prawym przyciskiem w zakładkę
z napisem Schemata . W roli nazwy użyjemy
ksiazka_telefoniczna . Jeśli utworzyła się po-
prawnie, sprawdzamy, czy jej nazwa po-
jawia się we wspomnianej zakładce sche-
mata ;
• naszym następnym krokiem będzie stwo-
rzenie tabel wewnątrz naszej bazy. Po klik-
nięciu prawym przyciskiem w zakładce
Schemata naszej bazy wybieramy Create
Table . W nowym oknie uzupełniamy na-
zwę pierwszej tabeli KONTAKTY, a w za-
kładce poniżej wpisujemy na próbę treść
następnego rysunku, uważając na to, że
gdy wybierzemy typ CHAR powinniśmy
dodać mu w nawiasie liczbę znaków, ja-
ką powinien przechowywać. W naszym
przypadku możemy użyć CHAR(20) dla
pól imię - nazwisko oraz CHAR(30) dla
pola telefon. Jeśli nie określimy w nawia-
sie liczby znaków, MySQL przypisze mu
przestrzeń jednego znaku.
Baza danych dobrze opracowana koncep-
cyjnie lecz źle zaimplementowana technicznie
sprawi nam oczywiste trudności, lecz te znaj-
dą rozwiązanie, jeśli ma się trochę doświad-
czenia i Google na wyciągnięcie ręki. Z drugiej
strony, baza źle zaprojektowana koncepcyjnie,
choć dobrze wykonana technicznie, zwiąże nam
ręce, jako że aplikacja będzie powielała jej po-
rażki.
W miarę jak będzie rosnąć nasze doświad-
czenie w rozwijaniu aplikacji wykorzystują-
cych bazy danych, zdamy sobie sprawę z og-
romnej ilości struktur, jakie można nadać bazie
danych. Jedne z nich są bardziej wydajne niż
inne. Napotkamy też aplikacje napisane przez
innych programistów i wiele nauczymy się pa-
trząc, jak to zrobili.
W ten sam sposób dostrzeżemy bazy da-
nych niepotrzebnie skomplikowane, źle za-
projektowane i nieskuteczne, lecz nauczymy
się na nich także, jak NIE należy pisać baz.
W naszym konkretnym przypadku nie bę-
dziemy mieli większych problemów z zapro-
jektowaniem bazy danych, biorąc pod uwagę,
że informacje, które chcemy przechować w na-
szej bazie nie są skomplikowane, lecz składa-
ją się tylko z nazw i numerów telefonów. Mo-
żemy jednak wyobrazić sobie, jak skompliko-
wane może być napisanie aplikacji księgowej,
administracyjnej czy inansowej, która prze-
chowywałaby informacje z różnych dziedzin,
powiązane kompletnie na krzyż. Co dopie-
ro mówić o aplikacjach dla naukowców, któ-
re muszą zapamiętać dane klimatyczne. Tam
złe projektowanie odbije się nieskuteczną pra-
cą aplikacji.
Z tego powodu krok koncepcyjny jest za-
zwyczaj krytyczny, choć wielu programistów
zwraca na niego najmniej uwagi (ucz się, ucz!).
Zazwyczaj, w miarę jak aplikacje rosną, zaczy-
namy zauważać, że były zaprojektowane źle
lub bez wyobraźni.
Nie zniechęcajcie się! Popełnianie błędów
to część nauki, niemniej jednak cechą charak-
terystyczną dobrych deweloperów i aplika-
cji, które odniosły sukces, jest jasna koncepcja
funkcji spełnianych przez bazę danych.
Rozmowa z bazą danych
w języku SQL
Wszelka praca z silnikiem bazy danych odby-
wa się za pomocą języka znanego jako SQL ;
czy chodzi o przechowywanie danych, wyszu-
kiwanie ich, modyikację czy usunięcie, język
SQL ( Structured Query Lenguage , Strukturalny
Język Zapytań) jest zawsze w użyciu.
Strukturalny Język Zapytań (SQL) to stan-
dardowy język bazodanowy, używany przez
różne silniki baz danych (SQLServer, MySQL,
Oracle, PostgreSQL, itd.) do wykonywania
określonych operacji, przede wszystkim na da-
nych, ale też na ich strukturze.
SQL jest zarazem językiem łatwym do na-
uczenia się i złożonym narzędziem do zarzą-
dzania danymi. Zapytania do bazy danych wy-
rażane są w formie instrukcji, które powinny
być napisane zgodnie z zasadami składni oraz
z zachowaniem reguł semantycznych tego ję-
zyka.
Zaletą posługiwania się tym językiem
jest możliwość dostępu do wszystkich baz
danych obsługujących standard SQL5 .
Użytkownicy Linuksa powinni mieć zain-
stalowanego i działającego Apache'a i MySQL.
Użytkownicy Windows mogą ściągnąć
z Internetu maszynę wirtualną zawierającą mi-
nimalną wersję Linuksa z zainstalowanym
Apachem i MySQL i odpalić ją za pomocą VM-
Ware Player . Można ją znaleźć na http://www.
rpath.org/rbuilder/project/lamp/ .
MySQL Query Browser jest aplikacją służą-
cą do pisania i wykonywania zapytań SQL za
pomocą interfejsu graicznego. Ściągniemy ją
z http://www.mysql.com/products/tools/query-
browser/ a następnie zainstalujemy.
Dla uproszczenia sprawy stworzymy ba-
zę danych w MySQL według następujących
kroków:
Po zakończeniu edycji wciskamy Apply, po
czym możemy ujrzeć podsumowanie wyko-
nanych operacji. Na ekranie ukazuje się nam
w języku SQL całe zadanie wykonane wcześ-
niej graicznie. W miarę jak będziemy lepiej po-
znawać SQL, będziemy mogli tworzyć tabele
i deiniować pola bez pośrednictwa interfejsu
graicznego, stosując sam tylko SQL. To nie zna-
czy, że MySQL Query Browser nie będzie nam
już potrzebny. Przekonamy się, że im więcej do-
wiemy się o SQL, tym lepiej będziemy wyko-
rzystywać tę aplikację.
Wszystko dobrze, jak dotąd napisaliśmy
bazę w sposób zadowalający. Teraz czas na
lepsze zrozumienie, co właściwie zrobiliśmy.
Projektowanie bazy
Najważniejszy krok w zaprojektowaniu bazy
danych jest natury koncepcyjnej, a nie tech-
nicznej.
Projektowanie koncepcyjne oznacza okre-
ślenie, jakie elementy świata rzeczywistego
zostaną przedstawione i powiązane w relacje.
Projektowanie izyczne bazy danych wy-
znacza tabele, które się na nią złożą, pola, jakie
będzie zawierać każda z tabel, a także typ da-
nych zawartych w każdym polu.
Rozwój techniczny projektu:
Wspomnieliśmy o tym, że gdy tworzy się ta-
belę, powinno się zdeiniować typ danych prze-
chowywanych w każdym z pól. Silnik bazy
danych potrzebuje wiedzieć, jakie dane za-
wiera każde pole, po to, by móc zoptymali-
zować wyszukiwanie i przechowywanie da-
nych.
Każde pole w tabeli będzie mogło pomie-
ścić dane tylko jednego typu. Do najpowszech-
niejszych typów należą:
• upewniamy się, że działa u nas usługa My-
SQL;
• uruchamiamy MySQL Query Browser
i uzupełniamy dane połączenia. Na przyk-
ład, jeśli jesteśmy w Linuksie a na naszej
64
wrzesień 2006
439114436.014.png 439114436.015.png 439114436.016.png
 
dla programistów
bazy danych
Listing 1. Formularz
byłoby przykładem złego projektowania.
Kto z nas nie ma znajomych o takim sa-
mym imieniu, a nawet nazwisku. Dlatego
zazwyczaj dopisujemy opcję PK do pola,
żeby upewnić się, że nie będzie się powta-
rzało. Jeśli przypadnie nam w udziale na-
pisanie bazy danych pacjentów jakiegoś
szpitala, możemy wybrać jako PK pole od-
powiadające numerowi paszportu albo do-
wodu osobistego, ponieważ i tak wiemy,
że taki numer jest wyjątkowy w każdym
kraju. Dodatkowo też zapewnilibyśmy nie-
sprzeczność systemu: jeśli użytkownik wpi-
suje ponownie osobę, która jest już w sys-
temie, w momencie zapisywania rekor-
du do bazy danych otrzyma komunikat
o błędzie silnika i program przypomni, że
taka osoba nie istnieje. Łatwe, prawda? Wy-
obraźcie sobie, że zaprogramowaliście sa-
mi cały algorytm wyszukiwania, żeby za-
gwarantować niepodwajanie się rekor-
dów. Można zrobić to za pomocą bazy da-
nych, pytając po prostu czy istnieje taki
numer;
UNSIGNED (Niepodpisane). Stosowanie
tej opcji jest poprawne tylko wobec pól
liczbowych i odbywa się w celu zdeinio-
wania użycia w danym polu tylko liczb
dodatnich. Na przykład, pole zdeiniowa-
ne jako typu INT mogłoby pomieścić nu-
mery od -2147483648 do 2147483647 . Je-
śli zdeiniujemy to pole jako UNSIGNED,
wartości, które można by w nim zapisać
pochodziłyby z przedziału od 0 do 429
4967295. Jeśli chcemy zapisywać wyższe
wartości, musimy użyć innych opcji. Przy-
pomina to typy danych używane w pro-
gramowaniu;
NOT NULL (Niepuste) Pola opatrzone tą
opcją nie będą nigdy mogły zawierać tyl-
ko zera ani być puste. Jeśli chcemy zapisać
rekord i nie przypiszemy wartości dla po-
la, które posiada tę opcję, silnik bazy da-
nych wyrzuci błąd. Na przykład, jeśli dei-
niujemy pole Nazwisko jako NOT NULL,
silnik bazy nie pozwoli na tworzenie re-
kordów, które nie będą zawierały żad-
nych wartości w polu Nazwisko. W ten
sposób już w fazie projektowania i rozwo-
ju bazy wymuszamy stałą obecność pew-
nych wartości.
AutoIncrement (Automatyczna numeracja).
Pola, w których wybrano tę opcję, zostaną
uzupełnione automatycznie przez bazę da-
nych w chwili utworzenia rekordu. W na-
szym projekcie bazy wybieramy pola ID
jako AutoIncrement. Gdy dodamy pierw-
szy rekord, baza wpisze numer w pole te-
go rekordu.
< html >
< body >
< form method= "post" action=
"dodaj_znajomego.php" >
Imie : < input type=
"Text" name= "imie" >< br >
Nazwisko: < input type=
"Text" name= "nazwisko" >< br >
Telefon1 : < input type=
"Text" name= "telefon1" >< br >
Telefon2 : < input type=
"Text" name= "telefon2" >< br >
< input type= "Submit" name=
"Zapisz" value= "Zapisz" >
< /form >
< /body >
< /html >
CHAR do przechowywania znaków alfa-
numerycznych;
INT przechowuje liczby całkowite;
DATE przechowuje daty/godziny.
SQL i jeszcze raz SQL
Czas już przekonać się, jak łatwy do nauki
jest SQL, przez co osiągniemy lepszą interak-
cję z naszymi danymi.
Jeśli spojrzymy ponownie na Rysunek 1 ,
ujrzymy rekordy każdej z tabel wraz z ich
wartościami. Ten widok tabeli ze wszystkimi
jej rekordami możemy uzyskać później także
z poziomu aplikacji MySQL.
Jeśli chcielibyśmy teraz poprosić bazę da-
nych o poszukanie w naszej książce kontak-
tów, które mają na nazwisko Hot użylibyśmy
następującego pseudokodu:
Istnieje wiele typów danych, są też silniki baz
danych, które obsługują ich więcej niż inne.
Aby dowiedzieć się, co udostępnia MySQL,
możemy zobaczyć listę typów wybierając Da-
ta Type w menu kontekstowym.
Znając już dostępne typy danych powin-
niśmy wybrać typ odpowiedni dla każdego
pola, na przykład, w naszych tabelach użyje-
my dwóch typów danych. Pierwszym będzie
CHAR, który zastosujemy do przechowania
wartości Imię i Nazwisko. Drugim będzie INT,
który przyda nam się do zapisania numeru ID
danego rekordu.
Jeśli zastanawiacie się, czemu nie użyć
typu INT dla numerów telefonu, odpowiedź
brzmi: nie powinny być przechowywane jako
numery, ponieważ zawierają spacje albo myśl-
niki.
Istnieje więcej opcji dostępnych podczas
deiniowania 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.
szukaj w tabeli KONTAKTY rekordów
z Nazwisko=”Hot”.
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
439114436.017.png 439114436.018.png 439114436.019.png 439114436.020.png 439114436.021.png 439114436.022.png 439114436.023.png 439114436.024.png 439114436.025.png 439114436.026.png 439114436.027.png 439114436.028.png 439114436.029.png
 
dla programistów
bazy danych
Tabela 3: Kontakty
ID Nazwisko Imię
1
W języku SQL:
określony w tym słowie. Na przykład, SELECT ,
INSERT , DELETE mówią same za siebie, służą
do wybierania (wyszukiwania) danych, doda-
wania nowych lub ich usuwania. W SQL waż-
ne jest, by jasno wiedzieć, co chce się osiągnąć,
a dokładną składnię można wydobyć używa-
jąc podręcznika i gromadząc doświadczenie.
W tym przypadku dodamy rekordy do na-
szych tabel. Użyjemy w tym celu następują-
cego polecenia:
Z
Jones
select * from TELEFONY where
kontakt_id=”1001”.
Tabela 4: Telefony
ID CONTACT_ID Numer
1
1
800-333-1112
Możemy tu zobaczyć, że z Angeliną Hot
(KONTAKT_ID=1001) jest powiązanych wie-
le rekordów.
2
1
615-123-1234
Ten pseudokod jest krokiem pośrednim
w stronę prawdziwej składni SQL.
Zapisywanie danych przez SQL
Wiemy już, jak stworzyć bazę, a także jak wy-
szukiwać w niej dane i wydobywać wyniki
za pomocą SQL. Brakuje nam tylko wiedzy o
przechowywaniu danych.
Język SQL jest bogaty i zawiera wiele in-
strukcji, lecz i tak te, które najbardziej nam się
przydadzą związane będą z przechowywa-
niem i wyszukiwaniem informacji.
Pozytywną cechą aplikacji MySQL jest
jej podręcznik, zawierający składnię każde-
go polecenia, jak również przykłady jego
użycia. Większość instrukcji SQL rozpoczyna-
ją się jednym słowem i zazwyczaj rozwijają cel
select * from KONTAKTY where
nazwisko=”Hot”
insert into KONTAKTY set imie=”Z”,
nazwisko=”jones”
Poprzednie zdanie to typowe zapytanie SQL
rozpoczynające się od {select *} to znaczy “Wy-
bierz wszystkie kolumny”, za którym idzie
{from KONTAKTY} , co tłumaczy się jako “z ta-
beli Kontakty” a zamyka je klauzula {WHERE
apellido=”Hot”} zapewniając, że pole “nazwi-
sko” jest równe tekstowi “Hot”.
Klauzula WHERE ma duże znaczenie jako
część instrukcji wyszukiwania, ponieważ zaj-
muje się iltrowaniem wyniku. Jeśli nie napi-
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
rekordy, jakie zawiera ta tabela. Wariantem po-
przedniego wyszukiwania mogłoby być:
Aby sprawdzić, czy to polecenie działa, wy-
pisujemy instrukcję w górnej zakładce MySQL
Query Browser.
Po wpisaniu instrukcji, klikamy w przy-
cisk EXECUTE . Ta czynność wyśle polecenie
do bazy danych i jeśli wszystko pójdzie do-
brze, w lewym dolnym rogu pojawi się tekst
Query executed in 0:00:XX , czyli “instrukcję
wykonano w ciągu XX sekund”.
Listing 2. Dodanie znajomego
< html >
< body >
<?
//Otwórz połączenie z bazą danych
$polaczenie = mysql_connect ( "localhost" , "root" ) ;
//Wybierz bazę
mysql_select_db ( "ksiazka_adresowa" , $polaczenie ) ;
//Wpisz zapytanie SQL
$sql_wstaw ="insert into KONTAKTY set imie= '" . $_POST ["imie"] . "' ,
nazwisko= '" . $_POST ["nazwisko"] . "' ";
//Wstaw dane
$result = mysql_query ( $sql_wstaw ) ;
//Sprawdzamy w bazie, czy automatyczny ID spotkał już wcześniej wstawiony
//rekord.
$id_nowy_kontakt = mysql_insert_id () ;
//Tworzymy następne zapytanie SQL, aby zapisać numery telefonów
//pod nowym ID.
$sql2_wstaw ="insert into TELEFONY set TELEFON= '". $_POST ['telefon1'].
"',KONTAKT_ID='". $id_nowy_kontakt . "' " ;
//Zapisujemy pierwszy numer telefonu.
$result2 = mysql_query ( $sql2_wstaw ) ;
//Zwracamy uwagę, czy telefon2 był już wstawiony do bazy, jeśli nie,
//wpisujemy ten numer.
if ( ! $_POST [ "telefon2" ] == "" ) {
$sql3_wstaw = "insert into TELEFONY set TELEFON='".
$_POST ['telefon2']. "' ,KOTAKT_ID= '". $id_nowy_kontakt . "'" ;
$result3 =mysql_query( $sql3_wstaw );
}
select nazwisko,id from KONTAKTY
where nazwisko=”Hot”
Tym razem wynik był inny, kolumny musiały
odpowiedzieć na dyspozycję, jaką wydaliśmy
dla ich pól (select nazwisko, id), dlatego też naj-
pierw przyszło nazwisko i dopiero potem id
a skoro nie wpisaliśmy pola imię, ta kolumna
nie pojawiła się w żadnym z rekordów zwró-
conych przez instrukcję SELECT.
Spójrzmy na inny przykład. Jeśli chcieli-
byśmy uzyskać wszystkie numery telefonów
Angeliny Hot z tabeli TELEFONY, jako pseu-
dokod mielibyśmy:
szukaj w tabeli TELEFONY rekordów
z kontakt_id=1001”.
Jeśli zadaliście sobie pytanie, dlaczego użyli-
śmy pola KONTAKT_ID jako iltra, przypomi-
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-
powtarzalny numer Angeliny Hot, a następnie
na podstawie tego numeru przeiltrować od-
powiadające mu numery telefonów.
echo "Dane zachowane!";
echo " < br > < a href= 'lista.php' > Zobacz listę kontaktów < /a > " ;
?>
66
wrzesień 2006
439114436.030.png 439114436.031.png 439114436.032.png 439114436.033.png 439114436.034.png
 
Zgłoś jeśli naruszono regulamin