You are on page 1of 47

PHP6 i MySQL 5.

Dynammiczne strony www.


Szybki start
Autor: Larry Ullman
Tumaczenie: Jaromir Senczyk
ISBN: 978-83-246-1723-4
Tytu oryginau: PHP 6 and MySQL 5
for Dynamic Web Sites: Visual QuickPro Guide
Format: 170x230, stron: 640
Poznaj moliwoci PHP6 oraz MySQL 5 i twrz dynamiczne strony WWW
Jak utworzy podstawowy skrypt PHP?
Jak korzysta z wielowymiarowych tablic?
Jak budowa bazy danych?

Kada funkcjonalna i atrakcyjna dla uytkownikw strona internetowa musi by


na bieco aktualizowana, a umieszczone na niej interesujce informacje powinny by
atwo dostpne. Najpopularniejsze narzdzia typu open source, suce do tworzenia
dynamicznych witryn, to jzyk PHP i system zarzdzania relacyjnymi bazami danych
MySQL. Oba te narzdzia oferuj wysok wydajno, przenono i niezawodno.
Wrd wielu ogromnych moliwoci oraz zalet PHP i MySQL maj take tak, e
sprawne posugiwanie si nimi nie jest zbyt skomplikowane nawet dla pocztkujcych.
Ksika PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start zawiera precyzyjny
opis czynnoci oraz bogato ilustrowane zrzutami ekranu niezbdne wskazwki
i wyjanienia, uatwiajce samodzielne zbudowanie dynamicznej strony internetowej.
Dziki temu podrcznikowi nauczysz si wyszukiwa i usuwa bdy w skryptach PHP,
tworzy formularze w jzyku HTML oraz zapobiega atakom na Twoje witryny. Poznasz
take podstawowe i zaawansowane techniki tworzenia rnych aplikacji (na przykad
stron wielojzycznych lub obsugujcych fora dyskusyjne).
PHP i MySQL
Tworzenie formularza w jzyku HTML
Tablice i acuchy
Tworzenie i wywoywanie wasnych funkcji
Wypenianie baz danych
Zabezpieczenia
Stosowanie modyfikatorw
Szyfrowanie danych
Tworzenie uniwersalnych witryn
Budowanie strony domowej
Wielojzyczna strona WWW
Tworzenie kont uytkownikw i nadawanie uprawnie

Szybko i atwo naucz si tworzy funkcjonalne


oraz bezpieczne witryny internetowe

Spis treci
Wprowadzenie

Czym s dynamiczne strony WWW? ................................................................... 10


Co bdzie Ci potrzebne? ....................................................................................... 16
O tej ksice ........................................................................................................... 17

Rozdzia 1.

Wprowadzenie do PHP

19

Rozdzia 2.

Programowanie w PHP

Spis treci

Podstawy skadni.................................................................................................... 20
Przesyanie danych do przegldarki internetowej ............................................... 24
Wstawianie komentarzy......................................................................................... 28
Co to s zmienne? .................................................................................................. 32
acuchy ................................................................................................................ 36
czenie acuchw............................................................................................... 39
Liczby ..................................................................................................................... 41
Stae ........................................................................................................................ 45
Apostrof kontra cudzysw .................................................................................... 48

51

Tworzenie formularza w jzyku HTML ............................................................... 52


Obsuga formularza HTML................................................................................... 56
Wyraenia warunkowe i operatory ....................................................................... 60
Weryfikacja danych pochodzcych z formularza ................................................. 64
Co to s tablice? ..................................................................................................... 70
Ptle for i while ...................................................................................................... 88

Rozdzia 3.

Tworzenie dynamicznych stron WWW

91

Wykorzystywanie plikw zewntrznych .............................................................. 92


Wywietlanie i obsuga formularza przez jeden skrypt ....................................... 102
Tworzenie formularzy z pamici ....................................................................... 107
Tworzenie i wywoywanie wasnych funkcji ...................................................... 110

Rozdzia 4.

Wprowadzenie do MySQL

125

Elementy bazy danych i ich nazwy..................................................................... 126


Wybr typu kolumny ........................................................................................... 128
Wybr innych waciwoci kolumn .................................................................... 132
Korzystanie z serwera MySQL-a ........................................................................ 134

Spis treci
Rozdzia 5.

Wprowadzenie do SQL

141

Tworzenie baz danych i tabel.............................................................................. 142


Wprowadzanie rekordw..................................................................................... 145
Wybieranie danych .............................................................................................. 149
Wyraenia warunkowe ........................................................................................ 151
Stosowanie LIKE i NOT LIKE .......................................................................... 154
Sortowanie wynikw zapytania ........................................................................... 156
Ograniczanie wynikw zapytania........................................................................ 158
Uaktualnianie danych .......................................................................................... 160
Usuwanie danych ................................................................................................. 162
Funkcje ................................................................................................................. 164

Spis treci

Rozdzia 6.

Zaawansowany SQL i MySQL

175

Projekt bazy danych............................................................................................. 176


Zczenia............................................................................................................... 191
Grupowanie wynikw zapytania ......................................................................... 196
Indeksy ................................................................................................................. 198
Stosowanie rnych typw tabeli........................................................................ 203
Wyszukiwanie FULLTEXT ................................................................................ 206
Wykonywanie transakcji...................................................................................... 212

Rozdzia 7.

Obsuga i usuwanie bdw

217

Oglne typy bdw i ich usuwanie.................................................................... 218


Wywietlanie bdw PHP.................................................................................. 224
Sterowanie raportowaniem bdw PHP ........................................................... 226
Tworzenie wasnych funkcji obsugi bdw ..................................................... 229
Techniki usuwania bdw z PHP ...................................................................... 234
Techniki usuwania bdw SQL i MySQL ........................................................ 238

Rozdzia 8.

PHP i MySQL

241

Modyfikacja szablonu .......................................................................................... 242


czenie si z MySQL-em i wybieranie bazy.................................................... 244
Wykonywanie prostych zapyta.......................................................................... 248
Odczytywanie wynikw zapytania ...................................................................... 257
Bezpieczestwo zapyta...................................................................................... 261
Zliczanie zwrconych rekordw ......................................................................... 267
Uaktualnianie rekordw w PHP ......................................................................... 269

Rozdzia 9.

Tworzenie aplikacji internetowych

277

Przekazywanie wartoci do skryptu..................................................................... 278


Stosowanie ukrytych pl formularza................................................................... 282
Edycja istniejcych rekordw ............................................................................. 288

Spis treci
Stronicowanie wynikw zapyta......................................................................... 295
Wywietlanie tabel z moliwoci sortowania.................................................... 303

Rozdzia 10. Tworzenie aplikacji internetowych

309

Wysyanie poczty elektronicznej ........................................................................ 310


Funkcje daty i czasu............................................................................................. 316
Obsuga przesyania plikw................................................................................. 320
Skrypty PHP i JavaScript .................................................................................... 333
Nagwki HTTP ................................................................................................... 340

Rozdzia 11. Sesje i ciasteczka

345

Strona logowania .................................................................................................. 346


Funkcje logowania ............................................................................................... 349
Posugiwanie si ciasteczkami............................................................................. 354
Sesje ...................................................................................................................... 367
Zwikszanie bezpieczestwa sesji ...................................................................... 376

Rozdzia 12. Zabezpieczenia

379

Rozdzia 13. Wyraenie regularne Perl

Spis treci

Zapobieganie spamowi ........................................................................................ 380


Walidacja danych wedug typu ........................................................................... 387
Zapobieganie atakom XSS ................................................................................... 392
Zapobieganie wstrzykiwaniu polece SQL........................................................ 395
Szyfrowanie i bazy danych .................................................................................. 401

407

Skrypt testujcy.................................................................................................... 408


Definiowanie prostych wzorcw......................................................................... 412
Stosowanie kwantyfikatorw ............................................................................... 415
Klasy znakw ........................................................................................................ 418
Wyszukiwanie wszystkich dopasowa................................................................ 421
Stosowanie modyfikatorw.................................................................................. 425
Dopasowywanie i zastpowanie wzorcw.......................................................... 427

Rozdzia 14. Tworzenie uniwersalnych witryn

431

Zbiory znakw i kodowanie................................................................................. 432


Tworzenie wielojzycznych stron WWW .......................................................... 434
Unicode w PHP ................................................................................................... 438
Uporzdkowanie zbioru znakw w PHP ............................................................ 442
Transliteracja w PHP........................................................................................... 445
Jzyki i MySQL.................................................................................................... 448
Strefy czasowe i MySQL ..................................................................................... 452
Lokalizatory .......................................................................................................... 455

Spis treci
Rozdzia 15. Forum dyskusyjne przykad

459

Baza danych.......................................................................................................... 460


Szablony................................................................................................................ 469
Strona domowa..................................................................................................... 478
Strona forum......................................................................................................... 479
Strona wtku......................................................................................................... 484
Wstawianie wiadomoci....................................................................................... 489

Rozdzia 16. Rejestracja uytkownikw przykad

501

Tworzenie szablonu ............................................................................................. 502


Skrypty konfiguracyjne........................................................................................ 508
Tworzenie strony domowej ................................................................................. 516
Rejestracja ............................................................................................................ 518
Aktywacja konta ................................................................................................... 527
Logowanie i wylogowywanie si......................................................................... 531
Zarzdzanie hasami............................................................................................. 537

Rozdzia 17. Sklep internetowy przykad

547

Spis treci

Tworzenie bazy danych ....................................................................................... 548


Cz administracyjna aplikacji .......................................................................... 554
Tworzenie szablonu czci publicznej aplikacji................................................. 571
Katalog produktw............................................................................................... 575
Koszyk................................................................................................................... 587
Rejestrowanie zamwie ..................................................................................... 597

Dodatek A

Instalacja

605

Instalacja w systemie Windows .......................................................................... 606


Definiowanie uprawnie MySQL....................................................................... 609
Testowanie instalacji............................................................................................ 613
Konfigurowanie PHP........................................................................................... 616

Skorowidz

619

Zaawansowany SQL i MySQL

Rozdzia 6. Zaawansowany SQL i MySQL

Rozdzia ten zaczyna si w miejscu, w ktrym ostatni si koczy. Omwi w nim bardziej
zaawansowane zagadnienia dotyczce SQL-a i MySQL-a. Poznae ju podstawy obu tych
technologii i z pewnoci wystarcz Ci one do realizacji wielu projektw, ale dopiero ich
bardziej wyszukane moliwoci wynios Twe aplikacje internetowe na wyszy poziom.
Zaczn od szczegowego omwienia procesu projektowania bazy danych, opierajc si
na przykadzie systemu zarzdzania forum. Doprowadzi nas to oczywicie do tematu
zcze, bdcych integraln czci kadej relacyjnej bazy danych. Nastpnie bd
opisywa kolejn kategori funkcji wbudowanych MySQL-a uywanych do grupowania
wynikw zapyta.

175

Zaawansowany SQL i MySQL

Na zakoczenie przejd do bardziej zaawansowanych zagadnie. Powiem o indeksach,


naucz Ci zmienia struktur istniejcych tabel oraz omwi typy tabel dostpne
w MySQL-u. Rozdzia zakocz omwieniem dwch dodatkowych moliwoci MySQL-a:
przeszukiwania tekstw i transakcji.

Rozdzia 6.
W moim przykadowym systemie bd chcia
stworzy forum, na ktrym uytkownicy mog
Pierwsze, co musisz zrobi, gdy pracujesz z systemem zamieszcza swoje opinie i odpowiada innym
zarzdzania relacyjnymi bazami danych, takim jak internautom. Aby korzysta z forum, uytkownik
MySQL, to utworzy struktur bazy (zwan rwnie bdzie musia si zarejestrowa, a nastpnie
schematem bazy danych). Projektowanie bazy danych uwierzytelni za pomoc kombinacji nazwy i hasa.
lub inaczej modelowanie danych to niezbdny etap Przewiduj rwnie moliwo istnienia wielu
gwarantujcy dugotrwae i bezproblemowe zarzdzanie forw powiconych rnym tematom. W tabeli
Twoimi informacjami. W procesie zwanym normalizacj 6.1 pokazaem, jak wyglda przykadowy rekord.
Baza danych bdzie nosi nazw forum.
eliminuje si niepotrzebne powtrzenia informacji
i inne problemy, ktre zagraaj spjnoci danych.

Projekt bazy danych

Projekt bazy danych

Dziki technikom, ktre poznasz w tym rozdziale,


Twoje bazy bd wydajne i niezawodne. Jeden
z przykadw, ktre zaprezentuj forum, na ktrym
uytkownicy mog wymienia si opiniami bdzie
intensywnie wykorzystywany dopiero w rozdziale 15.,
Forum dyskusyjne przykad. Jednak omwione
przeze mnie zasady normalizacji odnosz si
do wszystkich aplikacji bazodanowych, jakie moesz
utworzy. (Przykad bazy sitename uywany
w poprzednich dwch rozdziaach zosta poprawnie
zaprojektowany rwnie z punktu widzenia normalizacji,
ale zagadnienie to nie zostao jeszcze omwione.)

Normalizacja

Wskazwki

Istnieje bardzo dobra metoda na okrelenie,

jakiego rodzaju informacje powinny si


znale w bazie danych. Wystarczy,
e zastanowisz si, jakiego rodzaju pytania
o dane bd zadawane przez uytkownikw
i jakie dane bd musiay si znale
w odpowiedziach.
Nauka normalizacji moe sprawi Ci trudnoci,

jeli niepotrzebnie skoncentrujesz si na


szczegach. Kada z postaci normalnych jest
zdefiniowana w do skomplikowany sposb,
a prba przeoenia tych definicji na jzyk
niefachowy moe by mylca. Dlatego radz
Ci, aby podczas lektury omwienia postaci
normalnych skoncentrowa si na oglnym
obrazie zmian zachodzcych w schemacie
bazy danych. Po zakoczeniu normalizacji
i otrzymaniu kocowej postaci bazy danych
cay proces powinien sta si dla Ciebie
wystarczajco zrozumiay.

Proces normalizacji zosta wymylony na pocztku lat


siedemdziesitych przez E.F. Codda, naukowca z firmy
IBM, ktry wymyli te relacyjne bazy danych. Tego
rodzaju bazy to nic innego jak tylko zbir danych
uoonych w pewien okrelony sposb. Istnieje szereg
tak zwanych postaci normalnych (NF, z ang. Normal
Form), ktre uatwiaj definiowanie struktury danych.
W tym rozdziale omwi pierwsze trzy z nich,
Tabela 6.1. Przykadowy rekord pokazujcy, jakiego
poniewa w wikszoci przypadkw s one w peni rodzaju informacje chc przechowywa w mojej
wystarczajce.
bazie danych
Zanim zaczniesz normalizowa swoj baz danych,
musisz okreli, jakie funkcje bdzie penia Twoja
aplikacja. By moe bdziesz musia w tym celu
porozmawia z klientem lub samodzielnie zastanowi
si nad tym zagadnieniem. W kadym razie struktura
bazy danych zaley od sposobu, w jaki aplikacja bdzie
odwoywaa si do zgromadzonych w niej informacji.
Na tym etapie bdziesz wic potrzebowa raczej kartki
i owka ni MySQL-a. Oczywicie, w ten sposb
projektuje si wszystkie relacyjne bazy danych,
nie tylko te dziaajce w systemie MySQL.

176

Przykadowe dane forum


Element

Przykad

username

janek

password

haslo

actual name

Jan Kowalski

user email

jank@example.com

forum

MySQL

message subject Pytanie na temat normalizacji


message body

Nie rozumiem jednej rzeczy. Dla drugiej


postaci normalnej (2NF) podano...

message date

2 lutego 2008 12:20

Zaawansowany SQL i MySQL


Klucze

Baza danych forum skada si w zasadzie tylko z jednej


prostej tabeli (tabela 6.1), ale zanim rozpoczn proces
W rozdziale 4., Wprowadzenie do MySQL-a, normalizacji, chc utworzy w niej przynajmniej jeden
wspominaem ju, e klucze s integraln czci klucz gwny (klucze obce pojawi si w nastpnych
znormalizowanych baz danych. Spotkasz si
krokach).
z dwoma rodzajami kluczy, gwnymi i obcymi.
Klucz gwny to unikatowy identyfikator, ktry Aby przypisa klucz gwny:
podlega pewnym cile okrelonym reguom.
1. Poszukaj pl, ktre speniaj wszystkie trzy warunki
Musi on:
okrelone dla kluczy gwnych.
X Zawsze mie jak warto (inn ni NULL).
W naszym przykadzie (tabela 6.1) adna z kolumn
X Mie sta warto (tak, ktra nigdy nie ulega
nie spenia kryteriw klucza gwnego. Nazwa
zmianie).
uytkownika i adres e-mail s unikalne dla kadego
uytkownika forum, ale nie dla kadego rekordu
X Mie inn warto dla kadego rekordu
bazy danych (ten sam uytkownik moe umieszcza
w tabeli.
wiele wiadomoci na forum). Rwnie ten sam
Najlepszym, z ycia wzitym przykadem klucza
temat wiadomoci moe wystpowa wiele razy.
gwnego jest numer ubezpieczenia spoecznego
Tekst wiadomoci bdzie prawdopodobnie zawsze
przydzielany obywatelom USA. Kady ma tam
unikalny, ale moe si zmienia na skutek
wasny, niezmienny, unikatowy numer polisy.
pniejszych poprawek, tym samym naruszajc
Uatwia to identyfikowanie osb. Wkrtce
jedno z kryteriw wyboru klucza gwnego.
przekonasz si, e wielokrotnie sam bdziesz
2. Jeeli nie istnieje aden logiczny kandydat na klucz
tworzy we wszystkich tabelach klucze gwne.
gwny wprowad go! (tabela 6.2).
Jest to po prostu dobra praktyka projektowa.
Sytuacja, w ktrej musisz sam utworzy klucz
gwny, poniewa adne z istniejcych pl nie
nadaje si do penienia tej roli, wystpuje do
czsto. W tym konkretnym przykadzie utworz
pole message ID.

Wskazwki
Stosuj si do reguy, w myl ktrej w nazwach

Tabela 6.2. Dodaem do tabeli klucz gwny, dziki czemu


bd mg atwo odwoywa si do rekordw
Baza danych forum
Element

Przykad

message ID

username

janek

password

haslo

actual name

Jan Kowalski

user email

jank@example.com

forum

MySQL

message subject Pytanie na temat normalizacji


message body

Nie rozumiem jednej rzeczy. Dla drugiej


postaci normalnej (2NF) podano...

message date

2 lutego 2008 12:20

kluczy gwnych powinna wystpi przynajmniej


cz nazwy tabeli (np. message) i przyrostek id.
Niektrzy projektanci dodaj rwnie skrt pk
(ang. primary key klucz gwny).
MySQL zezwala na stosowanie w kadej tabeli

tylko jednego klucza gwnego, cho moesz oprze


go na kilku kolumnach (oznacza to, e kombinacja
tych kolumn musi by unikatowa).
Najlepiej byoby, gdyby Twj klucz gwny

by zawsze liczb cakowit, poniewa pozwala


to MySQL-owi osign najwysz moliw
wydajno.

177

Projekt bazy danych

Drugi rodzaj kluczy stanowi klucze obce.


Reprezentuj one w tabeli B klucze gwne
tabeli A. Jeeli masz na przykad baz danych
filmy, w ktrej wystpuj tabele film i reyser,
to klucz gwny tabeli reyser bdzie peni
rol klucza obcego w tabeli film. Ju niedugo
zobaczysz, jak to wszystko dziaa w praktyce.

Rozdzia 6.
Zalenoci
Mwic o zalenociach w bazach danych mam
na myli to, w jaki sposb dane z jednej tabeli s
powizane z danymi wystpujcymi w drugiej.
Zalenoci midzy dwiema tabelami mog
przybiera posta jeden do jednego, jeden do wielu
lub wiele do wielu. (Dwie tabele tej samej bazy
danych mog by rwnie wcale niepowizane).

Projekt bazy danych

O zalenoci jeden do jednego mwimy wtedy,


gdy jeden i tylko jeden element tabeli A odnosi si
do jednego i tylko jednego elementu tabeli B
(np. kady mieszkaniec USA ma tylko jeden numer
ubezpieczenia spoecznego, a kady numer polisy
jest przyporzdkowany tylko do jednego obywatela.
Nikt nie moe mie dwch polis, podobnie jak
aden numer ubezpieczenia nie moe odnosi si
do dwch osb).
Zaleno jeden do wielu wystpuje wtedy,
gdy jaki element tabeli A moe odnosi si do kilku
rnych elementw tabeli B. Na przykad,
okrelenia mczyzna i kobieta mog by uywane
w odniesieniu do wielu osb, ale kady czowiek
moe mie tylko jedn pe. Jest to najczciej
wystpujca zaleno midzy tabelami
w znormalizowanych bazach danych.
Istnieje te zaleno wiele do wielu, w ktrej
kilka elementw tabeli A moe odnosi si do kilku
elementw tabeli B. Na przykad rekord pyta
moe zawiera piosenki wykonywane przez rnych
artystw, a kady artysta moe mie na swoim
koncie kilka pyt. W swoich projektach powiniene
unika tego typu zalenoci, poniewa prowadz one
do problemw ze spjnoci danych i sprzyjaj ich
powielaniu. Zamiast zalenoci wiele do wielu
stworzysz tabel poredni, dziki ktrej zaleno
wiele do wielu zostanie rozbita na dwie zalenoci
jeden do wielu.
Temat zalenoci jest w pewien sposb zwizany
z zagadnieniem kluczy, poniewa klucze
zdefiniowane w jednej tabeli odwouj si zazwyczaj
do pl wystpujcych w innych tabelach.

178

Wskazwki
Modelowanie baz danych rzdzi si

pewnymi reguami. Istnieje okrelona


konwencja reprezentowania struktury
bazy (zostanie ona tutaj zachowana).
Na rysunku 6.1 pokazaem symbole trzech
rodzajw zalenoci.
Proces projektowania bazy danych prowadzi

do powstania diagramu zalenoci midzy


encjami (ERD), na ktrym wystpuj
prostokty reprezentujce tabele oraz
symbole z rysunku 6.1.
Istnieje wiele programw sucych

do tworzenia schematw baz danych.


Jednym z nich jest MySQL Workbench
(www.mysql.com).
Termin relacyjny w okreleniu system

zarzdzania relacyjnymi bazami danych


odnosi si do tabel, ktre nazywa si
relacjami.

Rysunek 6.1. Pokazane tu symbole czsto spotyka


si na diagramach strukturalnych. Opisuj one
zalenoci wystpujce midzy tabelami

Zaawansowany SQL i MySQL


Na przykad tabela zawierajca pole, w ktrym
mona umieci kilka numerw telefonw (domowy,
Jak ju powiedziaem wczeniej, normalizacja komrkowy, numer faksu itd.) nie jest zgodna
bazy danych jest procesem dostosowywania z pierwsz postaci normaln, poniewa w jednej
struktury bazy danych do kilku postaci.
kolumnie moe si znale wicej ni jedna warto.
Dostosowywanie to musi by precyzyjne
Jeli chodzi o drugi warunek, to tabela film
i odbywa si w okrelonej kolejnoci.
zawierajca kolumny aktor1, aktor2, aktor3 i tak
Mwimy, e baza danych jest pierwszej postaci dalej, nie bdzie w pierwszej postaci normalnej,
poniewa powtarzajce si kolumny zawieraj
normalnej (1NF), jeeli:
ten sam rodzaj informacji.
X Kada kolumna zawiera tylko jedn warto
Proces normalizacji rozpoczn od sprawdzenia,
(czyli jest atomowa lub niepodzielna).
czy aktualna struktura bazy (tabela 6.2) jest zgodna
X adna tabela nie ma powtarzajcych si
z 1NF. Kolumny, ktre nie s atomowe, zostan
kolumn dla danych pozostajcych w pewnej rozbite na wiele kolumn. Jeli tabela posiada
zalenoci.
powtarzajce si, podobne kolumny, to zostan
one przeksztacone w osobn tabel.

Pierwsza posta normalna

Aby uczyni baz zgodn z 1NF:


1. Zidentyfikuj pole, ktre moe zawiera kilka

informacji naraz.

Tabela 6.3. Tabela z atomowymi kolumnami


Baza danych forum
Element

Przykad

message ID

username

janek

password

haslo

first name

Jan

last name

Kowalski

user email

jank@example.com

forum

MySQL

message subject

Pytanie na temat normalizacji

message body

Nie rozumiem jednej rzeczy.


Dla drugiej postaci normalnej
(2NF) podano...

message date

2 lutego 2008 12:20

Pole message date (data dodania do bazy)


przechowuje, co prawda, dzie, miesic i rok,
ale raczej nie bdzie nas interesowa taki
poziom szczegowoci i potraktujemy
przechowywan przez nie warto jako
niepodzieln. Zreszt pod koniec poprzedniego
rozdziau pokazaem, e MySQL potrafi
doskonale obsugiwa dane reprezentujce
daty i czas za pomoc typu DATETIME.
Gdyby tabela zawieraa na przykad jedn,
wspln kolumn dla imienia i nazwiska zamiast
dwch osobnych albo przechowywaa wiele
numerw telefonw (stacjonarny, komrkowy,
domowy, subowy) w jednej kolumnie,
to kolumny te rwnie naleaoby rozbi.
2. Rozbij wszystkie pola odszukane w kroku 1.

na kilka mniejszych, niepodzielnych pl


(tabela 6.3).

179

Projekt bazy danych

Gdy spojrzysz jeszcze raz na tabel 6.2,


zobaczysz, e jedno z pl nie jest zgodne
z 1NF: actual name. Zawiera ono zarwno
imi jak i nazwisko uytkownika.

Rozdzia 6.
Aby poradzi sobie z tym problemem, utwrz
osobne pola first name i last name, ktre bd
zawiera tylko jedn warto.

Wskazwki
Dostosowanie tabeli do 1NF wymaga

analizy tabeli w poziomie. Wszystkie


kolumny jednego rekordu przegldamy
pod ktem wystpowania w nich danych,
ktre nie s atomowe oraz wystpowania
powtarzajcych si, podobnych danych.

3. Przekszta kad grup powtarzajcych si

Projekt bazy danych

kolumn w osobn tabel.


Problem ten nie wystpuje w bazie danych
forum. Zademonstruj go zatem na przykadzie
przedstawionym w tabeli 6.4. Powtarzajce si
kolumny zawierajce informacje o aktorach
powoduj dwa problemy. Po pierwsze,
dla kadego filmu mona poda tylko
ograniczon liczb aktorw. Nawet jeli
wprowadzimy kolumny aktor 1 a do aktor 100,
to ograniczeniem bdzie stu aktorw. Po drugie,
kady rekord, ktry nie zawiera maksymalnej
liczby aktorw, bdzie mie wartoci NULL
w nadmiarowych kolumnach. W schemacie
bazy danych powinnimy unika kolumn
zawierajcych wartoci NULL. Dodatkowym
problemem jest rwnie to, e kolumny
zawierajce informacje o reyserze i aktorach
nie s atomowe.
Aby rozwiza problemy wystpujce w tabeli
film, utworz dodatkow tabel (tabela 6.5).
Kady jej rekord zawiera informacje o jednym
autorze, co rozwizuje problemy opisane
powyej. Take nazwiska i imiona aktorw s
teraz przechowywane jako wartoci atomowe.
Zwr rwnie uwag, e do nowej tabeli
dodaem kolumn indeksu gwnego. Zasada,
e kada tabela posiada klucz gwny, wynika
wprost z pierwszej postaci normalnej.
4. Upewnij si, e wszystkie nowe pola utworzone

w kroku 2. i 3. s zgodne z 1NF.

180

Postacie normalne opisane s w rnych

rdach w rny sposb, czsto z uyciem


bardziej technicznego argonu.
Najwaniejszy jest jednak sens i kocowy
rezultat procesu normalizacji, a nie
sownictwo zastosowane do jego opisu.
Tabela 6.4. Tabela film nie jest zgodna z 1NF
z dwch powodw. Po pierwsze, zawiera
powtarzajce si kolumny podobnych danych
(aktor1 itd.). Po drugie, kolumny aktor i reyser
nie zawieraj wartoci atomowych
Tabela film
Kolumna

Warto

film ID

976

tytu filmu

Casablanca

rok produkcji

1943

reyser

Michael Curtiz

aktor1

Humphrey Bogart

aktor2

Ingrid Bergman

aktor3

Peter Lorre

Tabela 6.5. Aby tabela film (tabela 6.4) bya zgodna


z 1NF, powi aktorw z filmami za pomoc tabeli
film-aktor
Tabela film-aktor
ID

Film

Imi aktora

Nazwisko aktora

Casablanca

Humphrey

Bogart

Casablanca

Ingrid

Bergman

Casablanca

Peter

Lorre

Sok maltaski

Humphrey

Bogart

Sok maltaski

Peter

Lorre

Zaawansowany SQL i MySQL


Druga posta normalna
Kada baza, ktra ma spenia drug posta
normaln (2NF), musi by najpierw zgodna z 1NF
(proces normalizacji trzeba przeprowadza
we waciwej kolejnoci). Nastpnie wszystkie
kolumny, ktre nie zawieraj kluczy (kluczy obcych),
musz by powizane zalenoci z kluczem
gwnym. Kolumny, ktre naruszaj ten warunek,
Rysunek 6.2. Aby baza danych o filmach bya zgodna atwo zidentyfikowa po tym, e zawieraj wartoci
z 2NF, potrzebne s cztery tabele. Reyserzy s
niebdce kluczami i powtarzajce si w rnych
reprezentowani w tabeli film za pomoc klucza
rekordach. Wartoci te musz zosta umieszczone
reyser ID; filmy s reprezentowane w tabeli
w osobnej tabeli i by powizane z tabel wyjciow
film-aktor za pomoc klucza film ID; aktorzy s
za pomoc klucza.
reprezentowani w tabeli film-aktor za pomoc
klucza aktor ID

Patrzc na tabel 6.5, mona dostrzec dwa kolejne


naruszenia drugiej 2NF ani tytuy filmw,
ani nazwiska aktorw nie s powizane z kluczem
gwnym tabeli. Zatem baza danych o filmach
w najprostszej postaci wymaga czterech tabel
(rysunek 6.2). W ten sposb informacje o kadym
filmie, aktorze i reyserze s przechowywane tylko
jeden raz, a kada kolumna niebdca kluczem
jest zalena od klucza gwnego danej tabeli.
W zasadzie proces normalizacji mona by okreli
jako tworzenie coraz wikszej liczby tabel, tak
aby cakowicie wyeliminowa moliwo powielenia
jakichkolwiek danych.

181

Projekt bazy danych

Przykadem moe by fikcyjna tabela film


(tabela 6.4), ktra zawieraaby ponad dwadziecia
razy nazwisko Martina Scorsese jako reysera
rnych filmw. Sytuacja taka jest niezgodna z drug
postaci normaln, poniewa kolumna zawierajca
informacj o reyserze nie jest kluczem i nie jest
powizana zalenoci z kluczem gwnym (film ID).
Rozwizanie polega na utworzeniu osobnej tabeli
reyserzy wyposaonej we wasny klucz gwny,
ktry wystpiby jako klucz obcy w tabeli film,
tworzc w ten sposb powizanie obu tabel.

Rozdzia 6.
Aby uczyni baz zgodn z 2NF:
1. Zidentyfikuj kolumny, ktre nie s kluczami

i ktre nie s powizane z kluczem gwnym.


Przygldajc si tabeli 6.3 zauwaysz, e adne
z pl username, first name, last name, email
i forum nie s kluczami (jedyn kolumn bdc
kluczem jest na razie message ID) i adne z nich
nie jest powizane zalenoci z message ID.
Natomiast message subject, body i date rwnie
nie s kluczami, ale ich wartoci zale od klucza
message ID.

Rysunek 6.3. Aby baza danych forum bya zgodna


z 2NF, potrzebne s trzy tabele

2. Utwrz odpowiednie tabele (patrz rysunek 6.3).

Najlogiczniejsza modyfikacja istniejcej struktury


polega na utworzeniu trzech tabel: users, forums
i messages.

Projekt bazy danych

Na diagramie bazy danych kada tabela zostaa


przeze mnie oznaczona prostoktem. Jej nazwa
peni rol nagwka, pod ktrym wymienione
s wszystkie kolumny (atrybuty) tabeli.
3. Przypisz lub utwrz nowe klucze gwne

(rysunek 6.4).
Posugujc si technikami opisanymi wczeniej
w tym rozdziale, upewnij si, e kada nowa
tabela ma zdefiniowany klucz gwny. W tabeli
users stworzyem klucz user ID, a w tabeli
forums klucz forum ID. Poniewa pole username
w tabeli users oraz pole name w tabeli forums
musz by unikalne dla kadego rekordu i zawsze
mie warto, to mgby uy ich jako kluczy
gwnych. Oznaczaoby to jednak, e wartoci
tych pl nie mog si zmienia (zgodnie
z jednym z kryteriw wyboru klucza gwnego).
Uycie kluczy tekstowych zamiast numerycznych
powodowaoby rwnie nieco wolniejsze
dziaanie bazy danych.

182

Rysunek 6.4. Kada tabela powinna mie wasny


klucz gwny

Zaawansowany SQL i MySQL


4. Utwrz pomocnicze klucze obce, ktre pocz

tabele zalenociami (rysunek 6.5).


Ostatni krok na drodze do zgodnoci z 2NF
polega na dodaniu kluczy obcych, ktre okrel
powizania midzy tabelami. Pamitaj, e to,
co w jednej tabeli jest kluczem gwnym,
w drugiej najprawdopodobniej bdzie kluczem
obcym.

Rysunek 6.5. Aby zdefiniowa zaleno midzy


tymi trzema tabelami, dodaem do tabeli messages
dwa klucze obce, z ktrych kady czy j z jedn
z pozostaych dwch tabel

W naszym przykadzie kolumna user ID z tabeli


users czy si z kolumn user ID z tabeli
messages. Dlatego te tabela users pozostaje
w zalenoci jeden do wielu z tabel messages
(kady uytkownik moe umieci na forum
wiele wiadomoci, ale kada wiadomo moe
mie tylko jednego autora).
Poczone zostay rwnie dwie kolumny
forum ID, tworzc w ten sposb zaleno jeden
do wielu pomidzy tabelami messages i forums
(kada wiadomo moe nalee tylko do jednego
forum, ale dane forum moe zawiera wiele
wiadomoci).

Inny sposb sprawdzenia, czy tabele

speniaj drug posta normaln, polega


na przyjrzeniu si powizaniom tabel.
Idealna sytuacja polega na wystpowaniu
samych zalenoci jeden do wielu.
Tabele podlegajce zalenociom wiele
do wielu mog wymaga restrukturyzacji.
Jeli przyjrzymy si jeszcze raz rysunkowi

6.2, moemy zauway, e tabela film-aktor


spenia funkcj tabeli poredniczcej.
Pozwala ona zamieni zaleno wiele
do wielu zachodzc pomidzy filmami
i aktorami na dwie zalenoci jeden
do wielu. Tabele poredniczce atwo
rozpozna po tym, e wszystkie ich kolumny
s kluczami obcymi. W tym przypadku
kolumna odgrywajca rol klucza gwnego
nie jest potrzebna, poniewa kluczem
gwnym moe by kombinacja obu
kolumn tabeli.

W prawidowo znormalizowanej bazie danych

w jednej tabeli nie maj prawa pojawi si


dwa takie same rekordy (dwa lub wicej
rekordw, w ktrych wartoci wystpujce
w poszczeglnych kolumnach s identyczne).
Aby atwiej przyswoi sobie proces normalizacji,

zapamitaj, e pierwsza posta normalna


wie si z analiz tabeli w poziomie, podczas
gdy druga posta normalna powstaje na skutek
analizy w pionie (poszukiwania wartoci
powtarzajcych si w wielu rekordach).

183

Projekt bazy danych

Wskazwki

Rozdzia 6.
Trzecia posta normalna

Projekt bazy danych

Mwimy, e baza danych spenia trzeci posta


normaln (3NF), jeeli jest ona zgodna z 2NF,
a kada kolumna, ktra nie jest kluczem, jest zalena
od klucza gwnego. Jeeli prawidowo przeszede
przez pierwsze dwa etapy normalizacji,
prawdopodobnie dostosowanie bazy danych do 3NF
nie bdzie ju wymaga adnych zmian. W moim
przykadzie (patrz rysunek 6.5) rwnie nie ma
problemw, ktre naleaoby rozwiza, aby baza
bya zgodna z trzeci postaci normaln. Dlatego
te przedstawi je omawiajc hipotetyczn sytuacj.
Wemy na przykad pojedyncz tabel
przechowujc informacje o zarejestrowanych
klientach: imi, nazwisko, e-mail, numer telefonu,
adres pocztowy itp. Tabela taka nie jest zgodna
z 3NF, poniewa wiele kolumn nie bdzie zalenych
od klucza gwnego. Nazwa ulicy bdzie zalee
od miasta, a miasto od stanu. Rwnie kod pocztowy
nie bdzie zalee od tego, jak osob opisuje
rekord. Aby znormalizowa tak baz danych,
powinno si stworzy osobn tabel reprezentujc
pastwa, osobn reprezentujc miasta (poczon
kluczem obcym z tabel pastw) i jeszcze inn
dla kodw. Wszystkie te tabele byyby poczone
z tabel opisujc klientw.
Jeli takie rozwizanie wydaje Ci si przesad,
to masz racj. Wyszy stopie normalizacji czsto
nie jest konieczny. Chocia powinno si dy
do jak najpeniejszej normalizacji, to czasami warto
j powici na rzecz prostoty. (patrz ramka
Rezygnacja z normalizacji). W praktyce stopie
normalizacji zaley od potrzeb konkretnej aplikacji
i szczegw bazy danych.

Aby uczyni baz zgodn z 3NF:


1. Zidentyfikuj wszystkie pola, ktre nie s

bezporednio powizane z kluczem


gwnym.
Jak ju wspomniaem, na tym etapie
poszukujemy kolumn, ktre powizane s
midzy sob zalenociami (tak jak miasto
i stan) zamiast z kluczem gwnym.

W bazie danych forum nie wystpoway


takie zalenoci. Przyjrzyjmy si tabeli
messages. Kada warto pola subject
jest specyficzna dla danego message ID,
kada warto pola body jest specyficzna
dla wybranego message ID itd.
2. Utwrz odpowiednie tabele.

Jeli w punkcie 1. udao si odnale


problematyczne kolumny, takie jak
na przykad miasto i stan, to tworzymy
dla nich osobne tabele cities i states.
3. Przypisz lub utwrz nowe klucze gwne.

Kada tabela musi mie klucz gwny,


wobec czego do nowych tabel dodaj
kolumny city ID i state ID.
4. Utwrz pomocnicze klucze obce, definiujc

tym samym zalenoci (rysunek 6.6).


Na zakoczenie dodaem do tabeli Cities
klucz obcy State ID oraz klucz obcy City ID
do tabeli Clients. W efekcie uzyskaem
poczenie rekordu klienta nie tylko
z informacj o miecie, w ktrym jest
zameldowany, ale rwnie o stanie.

Jak ju wspomniaem, nasz przykad bazy forum


nie wymaga dalszej normalizacji (jest ju zgodny
z 3NF) i dlatego proces dostosowywania do trzeciej
postaci normalnej przedstawi wanie na przykadzie
omwionej wyej bazy danych o klientach.
Rysunek 6.6. Uproszczona wersja hipotetycznej
bazy clients bdzie zawiera dwie nowe tabele
przechowujce informacje o miastach i stanach

184

Zaawansowany SQL i MySQL


Wskazwka
W praktyce nie normalizowabym tabeli Clients

a do takiego stopnia. Gdybym pozostawi


pola opisujce miasto i stan w tabeli Clients,
to najgorsz rzecz, jaka mogaby si zdarzy,
byaby zmiana nazwy miasta i zwizana z tym
konieczno aktualizacji rekordw wszystkich
klientw bdcych jego mieszkacami.
W rzeczywistoci jednak sytuacja taka zdarza
si bardzo rzadko.
Mimo istnienia zasad normalizacji baz danych

Rezygnacja z normalizacji

Projekt bazy danych

Cho spenienie trzeciej postaci normalnej


jest korzystne, nie oznacza to jeszcze,
e masz normalizowa kad baz danych,
z ktr pracujesz. Jednoczenie
powiniene uzmysowi sobie, e odejcie
od sprawdzonych metod moe mie
w perspektywie duszego czasu
katastrofalne skutki.

dwch rnych projektantw moe dokona


normalizacji tej samej bazy w nieco inny sposb.
Projektowanie baz danych pozostawia pewien
margines dla indywidualnych preferencji
i interpretacji. Najwaniejsze jest,
by zaprojektowana baza danych nie naruszaa
postaci normalnej, gdy prdzej czy pniej
doprowadzi to do pojawienia si powanych
problemw.

Z normalizacji rezygnuje si zazwyczaj


z dwch powodw ze wzgldu
na wydajno i dla wygody. Duo atwiej
jest ogarn mniejsz liczb tabel, a poza
tym atwiej si nimi zarzdza. Ze wzgldu
na liczb powiza midzy tabelami,
uaktualnianie, odczytywanie i modyfikowanie
danych w znormalizowanych bazach danych
trwa z reguy duej. Krtko mwic,
normalizacja jest powiceniem prostoty
i szybkoci na rzecz spjnoci i skalowalnoci.
Naley jednak pamita, e istnieje znacznie
wicej sposobw na przyspieszenie bazy
danych ni na odzyskanie informacji
utraconych na skutek przechowywania ich
w le zaprojektowanej bazie.
W miar nabywania dowiadczenia bdziesz
potrafi coraz lepiej modelowa bazy danych,
ale mimo wszystko staraj si trzyma
po stronie normalizacji.

185

Rozdzia 6.
Tworzenie bazy danych

2. Utwrz baz danych forum (rysunek 6.7).

Aby zakoczy projekt bazy danych, musimy


wykona trzy ostatnie kroki:
1. Sprawdzi, czy w bazie znajd si wszystkie

potrzebne informacje.
2. Zidentyfikowa typy kolumn.

Projekt bazy danych

3. Nazwa wszystkie elementy bazy danych.

CREATE DATABASE forum;


USE forum;

Moliwe, e Twoja konfiguracja nie pozwala


na tworzenie nowych baz danych. W takiej
sytuacji po prostu wykorzystaj jak ju
istniejc baz i dodawaj do niej kolejne
tabele.

Ostateczny projekt bazy danych zosta


Tabela 6.6. Ostateczny projekt bazy forum
przedstawiony w tabeli 6.6. W porwnaniu
wraz z typami kolumn
do rysunku 6.5 zostaa dodana jeszcze jedna
forum
kolumna. Poniewa wiadomo umieszczana
Nazwa kolumny Tabela
Typ kolumny
na forum moe by odpowiedzi na inn wiadomo,
forum_id
forums
TINYINT
musimy jako reprezentowa t zaleno w bazie.
name
forums
VARCHAR(60)
Rozwizanie polega na dodaniu kolumny parent_id
messages INT
w tabeli messages. Jeli wiadomo jest odpowiedzi, message_id
forum_id
messages
TINYINT
to jej pole parent_id bdzie zawiera warto pola
parent_id
messages
INT
message_id oryginalnej wiadomoci (czyli message_id
user_id
messages
MEDIUMINT
spenia funkcj klucza obcego w tej samej tabeli).
subject
messages VARCHAR(100)
Jeli pole parent_id ma warto rwn 0, oznacza
body
messages LONGTEXT
to, e wiadomo stanowi pocztek nowego wtku,
messages TIMESTAMP
czyli nie jest odpowiedzi na adn inn wiadomo. date_entered
Jeli wprowadzasz jakiekolwiek zmiany w strukturze
tabel, powiniene ponownie sprawdzi, czy speniaj
one wszystkie postacie normalne, aby mie pewno,
e baza danych jest nadal znormalizowana.
Zagadnienie nazw tabel i kolumn oraz wyboru typw
kolumn omwiem ju w rozdziale 4.

user_id

users

MEDIUMINT

username

users

VARCHAR(30)

pass

users

CHAR(40)

first_name

users

VARCHAR(20)

last_name

users

VARCHAR(40)

email

users

VARCHAR(80)

Gdy schemat jest gotowy, moesz utworzy


odpowiadajc mu baz danych MySQL-a
za pomoc polece omwionych w rozdziale 5.,
Wprowadzenie do SQL.
Aby utworzy baz danych:
1. Uyj wybranego klienta do dostpu do serwera

MySQL-a.
Podobnie jak w poprzednim rozdziale,
we wszystkich przykadach bdziemy posugiwali
si monitorem (klientem) mysqla. Oczywicie
moesz te miao korzysta z phpMyAdmina
i innych narzdzi.

186

Rysunek 6.7. Najpierw musisz utworzy


i wybra baz danych

Zaawansowany SQL i MySQL


3. Utwrz tabel forums (rysunek 6.8).
CREATE TABLE forums (
forum_id TINYINT UNSIGNED
NOT NULL AUTO_INCREMENT,
name VARCHAR(60) NOT NULL,
PRIMARY KEY (forum_id)
);

Kolejno, w jakiej tworzysz tabele,


nie ma oczywicie znaczenia. Ja zaczn
od forums. Pamitaj, e zawsze moesz
rozpisa polecenie SQL w kilku wierszach
na ekranie, jeeli tylko bdzie Ci tak
wygodniej.

4. Utwrz tabel messages (rysunek 6.9).


CREATE TABLE messages (
message_id INT UNSIGNED
NOT NULL AUTO_INCREMENT,
forum_id TINYINT UNSIGNED
NOT NULL,
parent_id INT UNSIGNED NOT NULL,
user_id MEDIUMINT UNSIGNED
NOT NULL,
subject VARCHAR(100) NOT NULL,
body LONGTEXT NOT NULL,
date_entered TIMESTAMP NOT NULL,
PRIMARY KEY (message_id)
);

W tym przypadku klucz gwny musi by


zdecydowanie bardziej pojemny, poniewa
spodziewam si, e tabela ta bdzie zawiera
bardzo duo rekordw. Trzy kolumny bdce
kluczami obcymi forum_id, parent_id
i user_id bd mie taki sam rozmiar i typ
jak ich odpowiedniki bdce kluczami
gwnymi w innych tabelach. Pole subject
zostao ograniczone do 100 znakw, a pole
body moe zawiera znaczn ilo tekstu. Pole
date_entered otrzymao typ TIMESTAMP. Bdzie
ono przechowywa dat i czas dodania rekordu.
Jego warto zostanie automatycznie
zaktualizowana (biec dat i czasem)
w momencie wstawienia rekordu (wanie
w ten sposb zachowuje si typ TIMESTAMP).

Rysunek 6.9. Utwrz drug tabel

187

Projekt bazy danych

Rysunek 6.8. Utwrz pierwsz tabel

Tabela ta zawiera tylko dwie kolumny


(sytuacja taka ma czsto miejsce w przypadku
znormalizowanych baz danych). Poniewa nie
spodziewam si, e tabela ta bdzie zawiera
du liczb rekordw, klucz gwny otrzyma
typ TINYINT. Jeli chcesz, by baza zawieraa
rwnie opis kadego forum, moesz doda
do tej tabeli kolumn typu VARCHAR(255).

Rozdzia 6.
5. Utwrz tabel users (rysunek 6.10).
CREATE TABLE users (
user_id MEDIUMINT UNSIGNED
NOT NULL AUTO_INCREMENT,
username VARCHAR(30) NOT NULL,
pass CHAR(40) NOT NULL,
first_name VARCHAR(20) NOT NULL,
last_name VARCHAR(40) NOT NULL,
email VARCHAR(80) NOT NULL,
PRIMARY KEY (user_id)
);

danych ma tak struktur jak powinna


(rysunek 6.11).
SHOW
SHOW
SHOW
SHOW

TABLES;
COLUMNS FROM forums;
COLUMNS FROM messages;
COLUMNS FROM users;

Ten krok jest opcjonalny, poniewa MySQL


i tak wywietla informacje o pomylnym
wykonaniu kadego wprowadzanego
polecenia. Warto jednak przypomnie
sobie struktur bazy danych.
Wskazwka
W przypadku poczenia klucz

gwny-klucz obcy (na przykad forum_id


tabeli forum z forum_id tabeli messages),
obie kolumny musz by tego samego typu
(w naszym przykadzie: TINYINT UNSIGNED
NOT NULL).

Projekt bazy danych

Wikszo kolumn tej tabeli wykorzystuje


definicje znane z tabeli users bazy sitename
uywanej w poprzednich dwch rozdziaach.
Kolumna pass jest typu CHAR(40), poniewa
dla hase bd stosowa funkcj SHA1(), ktra
zwraca zawsze acuch o dugoci 40 znakw
(patrz rozdzia 5.).

6. Jeli chcesz, moesz upewni si, e baza

Rysunek 6.10. Trzecia i ostatnia tabela w bazie Rysunek 6.11. Sprawd struktur bazy za pomoc polecenia
SHOW

188

Zaawansowany SQL i MySQL


Wypenianie bazy danych
W rozdziale 15. napiszemy w PHP interfejs
WWW dla bazy forums. Bdzie on dostarcza
standardowego sposobu wypeniania bazy
danymi (poprzez rejestrowanie si
uytkownikw i umieszczanie wiadomoci
na forum). Zanim jednak dojdziemy do tego
punktu, musisz si jeszcze sporo nauczy.
Dlatego na razie wypenimy baz danymi
za pomoc klienta mysqla. Moesz wykona
po kolei ponisze kroki lub skorzysta
z gotowych polece SQL-a doczonych do
przykadw zamieszczonych na serwerze ftp.

Aby zapeni baz danymi:


1. Dodaj kilka nowych rekordw do tabeli forums

(rysunek 6.12).
INSERT INTO forums (name) VALUES ('MySQL'),
('PHP'), ('Programowanie'), ('HTML'),
('CSS'), ('Bazy danych');

Poniewa tablica messages jest zalena od


wartoci odczytywanych z tabel forums i users,
wypeni najpierw te ostatnie. W przypadku
powyszego polecenia INSERT wystarczy jedynie
poda warto kolumny name (MySQL
automatycznie nada warto kolumnie forum_id).
2. Dodaj nowe rekordy do tabeli users

(rysunek 6.13).

Jeli masz wtpliwoci co do skadni polecenia


INSERT lub zastosowania funkcji SHA1(), skorzystaj
z informacji podanych w rozdziale 5.

Rysunek 6.13. Dodawanie rekordw do tabeli users

189

Projekt bazy danych

Rysunek 6.12. Dodawanie rekordw do tabeli forums

INSERT INTO users (username, pass,


first_name, last_name, email) VALUES
('janek', SHA1('haslo'),
'Jan', 'Kowalski', 'jank@example.com'),
('ak', SHA1('haselko'),
'Arkadiusz', 'Kaczmarek', 'ak@example.com'),
('GosiaM', SHA1('tajne'), 'Magorzata',
'Malinowska', 'mm@example.com');

Rozdzia 6.
3. Wstaw nowe rekordy do tabeli messages

(patrz rysunek 6.14).

Projekt bazy danych

SELECT * FROM forums;


SELECT user_id, username FROM users;
INSERT INTO messages (forum_id,
parent_id, user_id, subject, body)
VALUES
(1, 0, 1, 'Pytanie na temat normalizacji',
'Nie rozumiem jednej rzeczy. Dla drugiej
postaci normalnej (2NF) podano...'),
(1, 0, 2, 'Projekt bazy danych', 'Projektuj
now baz danych i natrafiem na pewien
problem. Ile tabel powinna mie moja
baza?...'),
(1, 2, 1, 'Projekt bazy danych', 'Liczba
tabel w Twojej bazie danych...'),
(1, 3, 2, 'Projekt bazy danych', 'OK,
dzikuj!'),
(2, 0, 3, 'Bdy PHP', 'Prbuj uruchomi
skrypty z rozdziau 3. i pierwszy skrypt
kalkulatora nie dziaa. Gdy akceptuj
formularz...');

Poniewa dwa pola tabeli messages (forum_id


oraz user _id) odwouj si do wartoci
przechowywanych w innych tabelach,
przed wstawieniem nowych rekordw
dokonam wyboru tych wartoci. Na przykad,
gdy uytkownik janek utworzy now wiadomo
na forum MySQL-a, musisz uy forum_id
rwny 1 i user_id rwny 1.

Spraw dodatkowo komplikuje kolumna


parent_id. Musi ona zawiera warto
message_id tej wiadomoci, na ktr

odpowied stanowi nowa wiadomo.


Druga wiadomo umieszczona w bazie
danych bdzie mie message_id rwny
2 i wobec tego kada wiadomo stanowica
odpowied na t wiadomo bdzie musiaa
mie warto parent_id rwn 2.
W tworzonych przez Ciebie skryptach
PHP, wszystko to bdzie wygldao
znacznie prociej. Musz teraz jednak
wyoy Ci ca teori, posugujc si
terminologi jzyka SQL.
Zwr rwnie uwag, e nie wprowadziem
wartoci dla pola date_entered. MySQL
automatycznie umieci w nim biec
dat i czas, poniewa jest to kolumna
typu TIMESTAMP.
4. Powtrz kroki od 1. do 3., aby zapeni

baz danymi.
We wszystkich kolejnych przykadach
w tym rozdziale bd wykorzystywa baz,
ktr wanie zapeniem. Jeli chcesz,
moesz wykona u siebie te same polecenia
INSERT co ja lub utworzy swoje wasne.

Rysunek 6.14. W przypadku znormalizowanych baz danych bardzo czsto spotkasz si z sytuacj,
w ktrej, aby wstawi jaki rekord do tabeli, bdziesz musia zna wartoci przechowywane w innych tabelach

190

Zaawansowany SQL i MySQL

Zczenia
Poniewa relacyjne bazy danych maj zoon
struktur, aby wydoby te informacje, ktre
najbardziej nas interesuj, musimy czasem
wykona jakie niestandardowe zapytanie.
Na przykad, jeli chcesz dowiedzie si, jakie
wiadomoci zawiera forum MySQL-a, musisz
najpierw dowiedzie si, jaka jest warto
forum_id dla tego forum, a nastpnie uy
jej do pobrania wszystkich rekordw tabeli
message, ktre maj tak warto forum_id.
Jak z tego wynika, to proste zadanie wymaga
wykonania dwch zapyta. Jednak stosujc
zczenie, moesz poradzi sobie z nim
w jednym kroku.
Zczenie jest zapytaniem SQL-a uywajcym
dwch lub wicej tabel i tworzcym wirtualn
tabel wynikw. W specyfikacji SQL-a
wystpuj dwa gwne typy zcze:
wewntrzne i zewntrzne (oba maj szereg
podtypw).

Zczenie to wybiera wszystkie kolumny obu tabel,


jeli spenione s dwa warunki. Po pierwsze,
kolumna forums.name musi zawiera warto
MySQL (ktrej odpowiada warto forum_id
rwna 1). Po drugie, warto forum_id w tabeli
forums musi odpowiada wartoci forum_id
w tabeli messages. Ze wzgldu na sprawdzenie
rwnoci dotyczce pl w rnych tabelach
(messages.forum_id = forums.forum_id) zczenie
takie nazywa si rwnociowym.
Zczenia wewntrzne moesz rwnie zapisywa
bez stosowania klauzuli INNER JOIN:
SELECT * FROM messages, forums WHERE
messages.forum_id = forums.forum_id
AND forums.name = 'mySQL'

Jeeli wybierasz dane z wielu tabel i kolumn,


a w kilku tabelach wystpuj kolumny o takiej samej
nazwie, musisz zastosowa notacj z kropk
(tabela.kolumna). W przypadku relacyjnych baz
danych robi si to praktycznie zawsze, poniewa
klucz gwny jednej tabeli ma tak sam nazw
jak obcy klucz drugiej. Jeeli nie wskaesz
jednoznacznie kolumny, do ktrej si odwoujesz,
zobaczysz komunikat o bdzie (rysunek 6.16).

Rysunek 6.15. To zczenie zwraca kolumny obu tabel dla rekordw, dla ktrych wartoci
forum_id s rwne MySQL (1)

Rysunek 6.16. Oglne odwoanie do kolumny


wystpujcej w kilku tabelach spowoduje
wystpienie bdu niejednoznacznoci

191

Zczenia

Zczenie wewntrzne zwraca wszystkie


rekordy podanych tabel, dla ktrych zachodzi
dopasowanie. Na przykad, aby uzyska
wszystkie wiadomoci zamieszczone
na forum MySQL, powiniene uy
nastpujcego zczenia wewntrznego
(rysunek 6.15):

SELECT * FROM messages


INNER JOIN forums
ON messages.forum_id =
forums.forum_id
WHERE forums.name = 'MySQL'

Rozdzia 6.
Zczenia zewntrzne rni si od zcze
wewntrznych tym, e potrafi zwraca rekordy,
ktre nie speniaj wyraenia warunkowego.
Istniej trzy podtypy zcze zewntrznych: left
(lewe), right (prawe) i full (pene). Przykadem
pierwszego podtypu jest nastpujce zczenie:
SELECT * FROM forums
LEFT JOIN messages ON
forums.forum_id = messages.forum_id;

SELECT * FROM messages


INNER JOIN forums
USING (forum_id)
WHERE forums.name = 'mySQL'
SELECT * FROM forums
LEFT JOIN messages
USING (forum_id)

Zanim przejd do przykadw, jeszcze dwie


uwagi. Po pierwsze, poniewa skadnia
wymagana przy tworzeniu zcze jest do
skomplikowana, przy ich pisaniu przydaj si
aliasy omwione w rozdziale 5. Po drugie,
poniewa zczenia czsto zwracaj duo
danych, to najlepiej zawsze okreli, ktre
kolumny nas interesuj, zamiast wybiera
wszystkie.

Zczenia

Najwaniejsze przy tego rodzaju zczeniach


jest to, ktre tabele naley wymieni jako pierwsze.
W powyszym przykadzie w przypadku udanego
dopasowania zwrcone zostan wszystkie rekordy
tabeli forums wraz ze wszystkimi informacjami
z tabeli messages. Jeli dla danego rekordu tabeli
forums nie mona dopasowa informacji w tabeli
messages, to zamiast nich zostan zwrcone
wartoci NULL (rysunek 6.17).

Jeeli w warunku porwnania zczenia


zewntrznego bd wewntrznego wystpuje
kolumna o takiej samej nazwie w obu tabelach,
moesz uproci zapis zapytania, stosujc
klauzul USING:

Rysunek 6.17. To zczenie zewntrzne zwraca wicej rekordw ni zczenie wewntrzne, poniewa zwraca
wszystkie wiersze pierwszej tabeli. Zapytanie to zwraca rwnie nazwy wszystkich forw, nawet jeli nie zawieraj
one jeszcze adnej wiadomoci

192

Zaawansowany SQL i MySQL


Aby wykorzysta zczenia:
1. Pobierz nazw forum i temat wiadomoci
dla kadego rekordu tabeli messages

(patrz rysunek 6.18).


SELECT f.name, m.subject
FROM forums
AS f INNER JOIN messages AS m
USING (forum_id) ORDER BY f.name;

Zapytanie to zawiera zczenie wewntrzne,


ktre spowoduje w efekcie zastpienie
wartoci forum_id z tabeli messages
odpowiadajc jej wartoci name z tabeli
forums dla kadego rekordu tabeli messages.
W wyniku otrzymasz zatem temat kadej
wiadomoci wraz z nazw forum, do ktrego
naley ta wiadomo.
Zwr uwag, e w poczeniach nadal
moesz uywa klauzul ORDER BY.

2. Pobierz temat i dat wprowadzenia kadej

wiadomoci wysanej przez uytkownika janek


(rysunek 6.19).
SELECT m.subject,
DATE_FORMAT(m.date_entered,
'%M %D, %Y') AS Date
FROM users AS u INNER JOIN
messages AS m
USING (user_id)
WHERE u.username = 'janek';

Rwnie to zczenie uywa dwch tabel,


users i messages. Zczenie obu tabel odbywa
si za pomoc kolumny user_id i dlatego
zostaa ona umieszczona wewntrz klauzuli
USING. Wyraenie warunkowe WHERE pozwala
zidentyfikowa interesujcego nas uytkownika,
a funkcja DATE_FORMAT sformatowa warto
pola date_entered.

Zczenia

Rysunek 6.18. Podstawowe zczenie wewntrzne


zwraca w tym przykadzie tylko dwie kolumny

Rysunek 6.19. Nieco bardziej skomplikowana wersja


zczenia wewntrznego tabele users i messages

193

Rozdzia 6.
3. Pobierz identyfikator wiadomoci, temat oraz

4. Dla kadego uytkownika pobierz nazw

nazw forum dla kadej wiadomoci, ktrej


autorem jest uytkownik janek (patrz
rysunek 6.20).

uytkownika, temat wiadomoci i nazw


forum (patrz rysunek 6.21).

SELECT m.message_id, m.subject,


f.name FROM users AS u
INNER JOIN
messages AS m USING (user_id)
INNER JOIN forums AS f
USING (forum_id)
WHERE u.username = 'janek';

Gdyby zastosowa podobne zczenie


wewntrzne, to uytkownicy, ktrzy nie
s jeszcze autorami adnej wiadomoci,
nie zostaliby uwzgldnieni (patrz rysunek
6.22). Zatem jeli interesuj Ci wszyscy
uytkownicy, powiniene uy zczenia
zewntrznego. Zwr uwag, e tabela,
ktra ma by uwzgldniona w caoci
(users w tym przypadku), musi by podana
jako pierwsza tabela zczenia typu left.

Zczenia

Powysze zczenie jest podobne


do zastosowanego w punkcie 2., ale idzie o krok
dalej, doczajc trzeci tabel. Zwr szczegln
uwag na sposb konstrukcji zczenia
wewntrznego trzech tabel oraz zastosowanie
aliasw w celu atwiejszego odwoywania si
do tabel i ich kolumn.

SELECT u.username, m.subject,


f.name FROM users AS u LEFT JOIN
messages AS m USING (user_id)
LEFT JOIN forums AS f
USING (forum_id);

Rysunek 6.20. Zczenie wewntrzne wszystkich trzech


tabel bazy

194

Rysunek 6.21. To zczenie zewntrzne zwraca


dla kadego uytkownika temat kadej wiadomoci
i nazw kadego forum. Jeli uytkownik nie umieci
jeszcze adnej wiadomoci na forum (tak jak tomekj
widoczny na dole rysunku), to temat wiadomoci
i nazwa forum bd mie dla niego wartoci NULL

Zaawansowany SQL i MySQL


Wskazwki
Moesz nawet zczy tabel z ni sam.
Zczenia mona tworzy z wykorzystaniem

wyrae warunkowych odwoujcych si


do dowolnych kolumn. Nie musz one
peni roli kluczy, cho sytuacja taka jest
najczstsza.
Stosujc skadni bazadanych.tabela.

kolumna, moesz wykonywa zczenia


tabeli nalecych do rnych baz danych,
o ile tylko wszystkie znajduj si na tym
samym serwerze. Ta metoda nie zadziaa,
jeeli bazy komunikuj si ze sob
za porednictwem sieci.

Zczenia, ktre nie zawieraj klauzuli WHERE


(np. SELECT * FROM urls, url_associations),

nazywamy zczeniami penymi. Zwracaj one


rekordy z obu tabel. W przypadku duych tabel
ilo zwracanych danych moe stanowi pewien
problem.
Nigdy nie zostanie zwrcona warto NULL

wystpujca w kolumnie, do ktrej odwoujemy


si w zczeniu. To dlatego, e nie jest ona rwna
adnej innej wartoci, w tym take innym
wartociom NULL.

Zczenia

Rysunek 6.22. To zczenie wewntrzne nie zwrci


uytkownika, ktry nie umieci jeszcze adnej
wiadomoci na forum (tak jak tomekj widoczny
na dole rysunku 6.21)

195

Rozdzia 6.

Grupowanie wynikw zapytania


W poprzednim rozdziale przedstawiem dwie
rne klauzule ORDER BY i LIMIT majce wpyw
na wynik zapytania. Pierwsza z nich umoliwia
okrelenie uporzdkowania zwracanych rekordw,
a druga pozwala okreli, ktre z rekordw bdcych
wynikiem zapytania zostan w rzeczywistoci
zwrcone. Kolejna klauzula, GROUP BY, grupuje
zwracane dane w podobne do siebie bloki informacji.
Na przykad, aby pogrupowa wszystkie wiadomoci
wedug forum, wpisz:

Grupowanie wynikw zapytania

SELECT * FROM messages


GROUP BY forum_id;

Zwracane dane nie bd miay postaci pojedynczych


rekordw, tylko grup informacji. Zamiast duej
liczby wiadomoci pochodzcych z danego forum
zobaczysz je wszystkie w postaci jednego rekordu.
Ten przykad nie jest by moe szczeglnie
przydatny, ale wystarczajcy do przedstawienia
samej koncepcji.

Aby zgrupowa dane:


1. Policz zarejestrowanych uytkownikw

(patrz rysunek 6.23).


SELECT COUNT(user_id) FROM users;

COUNT() jest prawdopodobnie

najpopularniejsz z funkcji agregujcych.


Z jej pomoc moesz szybko zliczy
rekordy tak jak w przypadku tabeli users.
Zwr uwag, e nie wszystkie zapytania
stosujce funkcje agregujce uywaj
klauzuli GROUP BY.
2. Policz, ile razy kady uytkownik umieci

na forum swoj wiadomo (patrz


rysunek 6.24).
SELECT username,
COUNT(message_id) AS Number
FROM users LEFT JOIN messages AS m
USING (user_id) GROUP BY (m.user_id);

Z klauzul GROUP BY czsto uywa si jednej z funkcji Tabela 6.7. Funkcje grupujce MySQL-a
agregujcych przedstawionych w tabeli 6.7 (funkcji
Przeznaczenie
tych mona uywa rwnie niezalenie od klauzuli Funkcja
AVG()
Zwraca redni warto z podanej
GROUP BY).
kolumny.

Na wyraenie GROUP BY moesz oczywicie nakada


warunki WHERE, ORDER BY i LIMIT, tworzc zapytania
w rodzaju:
SELECT kolumny FROM tabela WHERE warunek
GROUP BY kolumna ORDER BY kolumna
LIMIT x, y;

MIN()

Zwraca najmniejsz warto


z podanej kolumny.

MAX()

Zwraca najwiksz warto z podanej


kolumny.

SUM()

Zwraca sum wszystkich wartoci


z danej kolumny.

COUNT()

Zwraca liczb rzdw.

GROUP_CONCAT() Zwraca konkatenacj wartoci


kolumny.

Rysunek 6.23. To zapytanie grupujce zwraca


liczb wartoci user_id w tabeli users

196

Zaawansowany SQL i MySQL


Jest to rozszerzona wersja zapytania
wystpujcego w kroku 1., ale zamiast
zlicza samych uytkownikw, podaje
liczb wiadomoci zwizanych z kadym
uytkownikiem. Zastosowanie zczenia
umoliwia dostp do informacji w dwch
tabelach. Aby uwzgldni uytkownikw,
ktrzy nie byli jeszcze aktywni na forum,
zastosowaem zczenie wewntrzne.
3. Znajd dwch najaktywniejszych

uytkownikw forum (rysunek 6.25).


SELECT username,
COUNT(message_id) AS Number
FROM users
LEFT JOIN messages AS m
USING (user_id)
GROUP BY (m.user_id)
ORDER BY Number DESC LIMIT 2;

W zapytaniach z klauzul GROUP BY nadal moesz


sortowa wyniki zapyta. Proces ten moesz
uproci, stosujc alias Number dla wartoci
COUNT(message_id).
Wskazwki
Jak ju miae okazj si przekona, NULL

jest bardzo specyficzn wartoci. Interesujce


jest to, e wyraenie GROUP BY umieszcza
wszystkie wartoci NULL w tej samej grupie,
poniewa wszystkie one wykazuj taki sam
brak wartoci.
Funkcja COUNT() zlicza jedynie wystpienia
wartoci rnych od NULL. Dlatego pamitaj,
aby uy jej dla kadej kolumny (*) lub
dla kolumn, ktre nie zawieraj wartoci NULL

Opanowanie klauzuli GROUP BY i funkcji


Rysunek 6.24. To zapytanie GROUP BY podaje liczb
wiadomoci umieszczonych na forum przez kadego
uytkownika

omwionych w tym podrozdziale zajmie Ci


troch czasu. Za kadym razem, gdy uyjesz
nieprawidowej skadni, zostanie zgoszony
bd. Poeksperymentuj troch z monitorem
mysqla, aby zapamita, jak dokadnie musz
by sformuowane wszystkie zapytania, ktrych
bdziesz chcia uywa w swoich aplikacjach.
Z klauzul GROUP BY zwizana jest klauzula
HAVING, ktra zachowuje si jak klauzula WHERE

zastosowana do grupy rekordw.

Rysunek 6.25. Klauzula ORDER BY pozwala


posortowa autorw na podstawie liczby wiadomoci
umieszczonych na forum. Klauzula LIMIT powoduje,
e podane zostan tylko dwa wyniki

197

Grupowanie wynikw zapytania

(na przykad klucza gwnego). Jeli zapytanie


uyte w punkcie 2. (rysunek 6.24) stosowaoby
funkcj COUNT() dla wszystkich kolumn (*)
zamiast tylko dla message_id, to pokazaoby
bdn warto rwn 1 dla wszystkich
uytkownikw, ktrzy nie napisali jeszcze adnej
wiadomoci. Staoby si tak, poniewa zapytanie
zwrcioby dokadnie jeden rekord dla kadego
z tych uytkownikw.

Rozdzia 6.

Indeksy
Mechanizm indeksw to specjalny system
wykorzystywany w bazach danych do poprawy
ich wydajnoci. Zakadajc na swych tabelach
indeksy, sprawiasz, e MySQL przywizuje wag
do okrelonych kolumn. Aby indeksy mogy by
wykorzystywane w sposb maksymalnie efektywny,
MySQL przechowuje je w osobnych plikach.

Wyposaony w te wiadomoci zmodyfikuj


baz forum, dodajc do niej indeksy.
W tabeli 6.8 podaem indeksy utworzone
dla poszczeglnych kolumn za pomoc
polecenia ALTER omwionego w ramce.

Na kadej tabeli mona zaoy co najmniej 16


indeksw, a kady indeks moe obejmowa do 15
kolumn. Cho rozciganie indeksu na kilka kolumn
moe wydawa si zastanawiajce, przydaje si to
podczas czstego przeszukiwania tego samego
zestawu kolumn (np. imion i nazwisk, miast
i wojewdztw).
Nie powiniene jednak przesadza z indeksowaniem.
Cho przyspiesza ono odczytywanie informacji
z bazy, to jednoczenie spowalnia ich modyfikowanie
(poniewa informacje o zmianach musz trafi
do indeksw). Najlepszym wyjciem jest zakadanie
indeksw na kolumnach, ktre:

Indeksy

X Czsto wymieniane s w zapytaniach


po klauzulach WHERE.
X Czsto wymieniane s w zapytaniach
po klauzulach ORDER BY.
X Czsto wykorzystywane s jako gwny punkt

zczenia.
X Maj wiele rnych wartoci (nie powinno si

indeksowa kolumn zawierajcych wiele


powtarzajcych si wartoci).
W MySQL-u wystpuj cztery rodzaje indeksw:
INDEX (standardowy), UNIQUE (ktry wymaga,
aby w kadym rzdzie wystpoway inne wartoci),
FULLTEXT (do wyszukiwa FULLTEXT) oraz PRIMARY KEY
(klucz gwny, bdcy szczeglnym przypadkiem
indeksu UNIQUE). Pamitaj, e dana kolumna moe
by tylko raz zaindeksowana i wobec tego wybierz
dla niej najodpowiedniejszy rodzaj indeksu.

198

Tabela 6.8. Indeksy uywane przez baz danych


forum. Nie wszystkie kolumny s indeksowane,
a dwa indeksy zostay utworzone dla par kolumn:
user.pass i user.username oraz messages.body
i messages.subject
Indeksy bazy danych forum
Nazwa kolumny

Tabela

Typ indeksu

forum_id

forums

PRIMARY

name

forums

UNIQUE

message_id

messages

PRIMARY

forum_id

messages

INDEX

parent_id

messages

INDEX

user_id

messages

INDEX

body/subject

messages

FULLTEXT

date_entered

messages

INDEX

user_id

users

PRIMARY

username

users

UNIQUE

pass/username

users

INDEX

email

users

UNIQUE

Zaawansowany SQL i MySQL


Aby doda indeks do istniejcej tabeli:
1. Za indeks na kolumnie name w tabeli forums

(patrz rysunek 6.26).


ALTER TABLE forums ADD UNIQUE (name);

Rysunek 6.26. Dla kolumny name dodano nowy


indeks, ktry poprawi efektywno zapyta
i zapobiegnie wprowadzaniu powtarzajcych si
wartoci

Tabela forums ma ju zaoony indeks typu klucz


gwny na kolumnie forum_id. Poniewa name
rwnie jest polem, do ktrego bd czste
odwoania i ktrego warto musi by unikatowa
w kadym rekordzie, zakadam na nim indeks
UNIQUE.

Modyfikowanie tabel

Indeksy

Polecenie ALTER suy przede wszystkim do modyfikowania struktury tabeli w bazie danych.
Najczciej oznacza to dodawanie, usuwanie bd modyfikacj kolumn, ale rwnie dodawanie
indeksw. Polecenia ALTER mona rwnie uy do zmiany nazwy tabeli. Teoretycznie przy dobrym
projekcie bazy jej struktura nie powinna stwarza adnych problemw. Jednak w praktyce czsto
zdarza si wprowadza w niej pewne zmiany. Skadnia polecenia ALTER jest nastpujca:
ALTER TABLE nazwa_tabeli KLAUZULA;

Poniewa klauzul, ktre mona zastosowa, jest bardzo wiele, w tabeli 6.9 wymieniem tylko najczciej
stosowane. Pen list znajdziesz w podrczniku MySQL-a.
Tabela 6.9. Popularne warianty polecenia ALTER (gdzie t reprezentuje nazw tabeli, c nazw kolumny,
a i nazw indeksu. Pen specyfikacj polecenia znajdziesz w dokumentacji MySQL-a
Klauzule, ktre mona stosowa w poleceniach ALTER TABLE
Klauzula

Sposb uycia

Znaczenie

ADD COLUMN

ALTER TABLE t ADD COLUMN c TYP

Dodaje now kolumn na kocu tabeli.

CHANGE COLUMN

ALTER TABLE t CHANGE COLUMN c c TYP

Pozwala zmieni typ danych i waciwoci kolumny.

DROP COLUMN

ALTER TABLE t DROP COLUMN c

Usuwa kolumn z tabeli razem z wszystkimi jej


danymi.

ADD INDEX

ALTER TABLE t ADD INDEX i (c)

Zakada nowy indeks na kolumnie c.

DROP INDEX

ALTER TABLE t DROP INDEX i

Usuwa istniejcy indeks.

RENAME AS

ALTER TABLE t RENAME AS nowa_t

Zmienia nazw tabeli.

199

Rozdzia 6.
2. Za indeksy dla tabeli messages

(patrz rysunek 6.27).


ALTER TABLE messages
ADD INDEX(forum_id),
ADD INDEX(parent_id),
ADD INDEX(user_id),
ADD FULLTEXT(body, subject),
ADD INDEX(date_entered);

Rysunek 6.27. Do tabeli messages dodano kilka


indeksw naraz. MySQL raportuje wykonanie
operacji oraz podaje liczb rekordw, ktrych
dotyczya (powinna to by liczba wszystkich
rekordw tabeli)

Indeksy

Ta tabela bdzie mie najwicej indeksw,


poniewa jest najwaniejsz tabel w bazie
i zawiera trzy klucze obce (forum_id, parent_id
i user_id), dla ktrych naley zaoy osobne
indeksy. Dodatkowo pola body i subject
otrzymuj indeks FULLTEXT uywany podczas
wyszukiwa typu FULLTEXT w dalszej czci
tego rozdziau. Rwnie kolumna date_entered
otrzymuje indeks, poniewa bdzie uywana
przez klauzule ORDER BY (do sortowania
wiadomoci po dacie).

Jesli podczas wykonywania tego zapytania


pojawi si komunikat o bdzie
stwierdzajcy, e typ tabeli nie obsuguje
indeksw FULLTEXT (patrz rysunek 6.28),
na razie opu ten wiersz zapytania
i sprawd w nastpnym podrozdziale,
w jaki sposb zmieni typ tabeli.

Rysunek 6.28. Indeksw FULLTEXT nie mona stosowa dla wszystkich typw
tabel. Jeli napotkasz ten komunikat o bdzie, to rozwizanie znajdziesz
w tym rozdziale w czci Stosowanie rnych typw tabel

200

Zaawansowany SQL i MySQL


3. Dodaj indeksy do tabeli users

(patrz rysunek 6.29).


ALTER TABLE users
ADD UNIQUE (username),
ADD INDEX (pass, username),
ADD UNIQUE (email);

Tabela users bdzie mie dwa indeksy


UNIQUE oraz jeden indeks zaoony na dwch
kolumnach. Indeksy UNIQUE zastosowaem
w tym przypadku, poniewa chc zapobiec
moliwoci zarejestrowania dwch
uytkownikw o tej samej nazwie
lub wielokrotnego zarejestrowania
uytkownika o tym samym adresie e-mail.

Indeks zaoony na kolumnach pass i username


ma za zadanie poprawi efektywno zapyta
wykonywanych podczas uwierzytelniania
uytkownika, gdy kombinacja tych dwch
kolumn bdzie uywana w wyraeniu
warunkowym WHERE.
4. Obejrzyj biec struktur wszystkich tabel

(patrz rysunek 6.30).


DESCRIBE forums;
DESCRIBE messages;
DESCRIBE users;

Polecenie DESCRIBE jzyka SQL zwraca


informacje o nazwach kolumn wystpujcych
w tabeli i w ich typach, a take o kolejnoci,
w jakiej one wystpuj i o pozakadanych
indeksach. Podaje ono take, czy dane pole
moe przyjmowa warto NULL, czy okrelono
dla niego jak warto domyln itd.

Rysunek 6.29. Indeksy zostay rwnie


dodane do trzeciej tabeli

Indeksy

Rysunek 6.30. Aby zobaczy szczegowe informacje na temat struktury tabeli,


uyj polecenia DESCRIBE. Kolumna Key informuje o indeksach

201

Rozdzia 6.
Wskazwki
Prba zaoenia indeksu UNIQUE na kolumnie

zawierajcej duplikaty spowoduje bd, a indeks


nie zostanie utworzony.
Tworzc indeks, moesz nada mu nazw.
ALTER TABLE tabela
ADD INDEX nazwa_indeksu (kolumna);

Jeeli tego nie zrobisz, otrzyma on nazw


kolumny, na ktrej go zakadasz.
Sowo COLUMN w wikszoci polece ALTER

jest opcjonalne.
Zamy, e stworzye indeks dla kilku kolumn:
ALTER TABLE tabela
ADD INDEX (kol1, kol2, kol3)

Indeksy

Powstay indeks umoliwia efektywne


przeszukiwanie kolumny kol1, kombinacji
kolumn kol1 i kol2 oraz kombinacji wszystkich
trzech podanych kolumn. Nie zwiksza
efektywnoci przeszukiwania kolumny kol2
i kol3 lub ich kombinacji.

202

Zaawansowany SQL i MySQL

Stosowanie
rnych typw tabeli
MySQL obsuguje kilka rnych typw tabeli
(typ tabeli nazywany bywa rwnie silnikiem
przechowywania). Kady z tych typw ma inne
waciwoci, odrbne ograniczenia (dotyczce
iloci przechowywanych danych)
i charakteryzuje si inn efektywnoci
dziaania w okrelonych sytuacjach. Jednak
interakcje uytkownika (w sensie wykonywania
zapyta) z rnymi typami tabel s spjne.
Najwaniejszym typem tabeli jest MyISAM. Jest
on domylnym typem tabeli na wszystkich
platformach oprcz Windows. Tabele tego
typu s najodpowiedniejsze dla wikszoci
aplikacji i umoliwiaj szybkie wykonywanie
polece SELECT oraz INSERT. Ich podstawow
wad jest to, e nie obsuguj transakcji.

CREATE TABLE tabela (


kolumna1 TYPKOLUMNY,
kolumna2 TYPKOLUMNY...
) ENGINE = INNODB

Jeli tworzc tabele, nie podamy ich typu, to MySQL


uyje typu domylnego.
Typ istniejcej tabeli moemy zmieni za pomoc
polecenia ALTER:
ALTER TABLE tabela ENGINE = MYISAM

Poniewa nastpny przykad w tym rozdziale bdzie


wymaga tabeli typu MyISAM, to poka najpierw
kroki konieczne do skonfigurowania odpowiedniego
typu tabeli na przykadzie tabeli messages. W kilku
pierwszych krokach dowiesz si, jak sprawdzi
wykorzystywany typ silnika, (poniewa zmiana
typu tabeli moe nie by konieczna).

203

Stosowanie rnych typw tabeli

Kolejnym typem tabeli pod wzgldem


popularnoci zastosowa jest InnoDB, ktry jest
domylnym typem tabeli MySQL-a w systemie
Windows. Tabele InnoDB obsuguj transakcje
i umoliwiaj szybkie wykonywanie polece
UPDATE. Jednak silnik InnoDB jest w oglnym
przypadku wolniejszy ni MyISAM i wymaga
wikszej przestrzeni dyskowej serwera. Tabele
typu InnoDB nie obsuguj rwnie indeksw
typu FULLTEXT (i dlatego moge napotka bd
przedstawiony na rysunku 6.28, jeli uywasz
Windows).

Aby okreli, ktrego silnika chcemy uywa,


na kocu polecenia CREATE dodajemy specjaln
klauzul:

Rozdzia 6.
Aby zmieni typ tabeli:
1. Obejrzyj aktualn informacj o tabeli

ALTER TABLE messages ENGINE=MYISAM;

(patrz rysunek 6.31).


SHOW TABLE STATUS;

Polecenie SHOW TABLE STATUS zwraca wiele


przydatnych informacji o tabelach bazy danych.
Informacje te odczytuje si niewygodnie,
poniewa maj one posta szerokiej tabeli
zajmujcej wiele wierszy. W kadym wierszu
znajduje si najpierw nazwa tabeli, a nastpnie
jej typ. Zwykle jest nim MyISAM lub InnoDB.

Stosowanie rnych typw tabeli

2. Jeli to konieczne, zmie typ tabeli


messages na MyISAM (rysunek 6.32).

Jeli w punkcie 1. okazao si, e typ


tabeli jest inny ni MyISAM, to zmie go
za pomoc powyszego polecenia
(nie musisz zwraca uwagi na mae i due
litery w typie tabeli). Jeli wykonae
domyln instalacj i konfiguracj
MySQL-a, to zmiana typu tabeli nie
bdzie potrzebna w systemie Mac OS X,
ale musisz jej dokona w systemie
Windows.

Rysunek 6.31. Zanim zmienisz typ tabeli, sprawd go za pomoc


polecenia SHOW TABLE STATUS

Rysunek 6.32. Zmieniem typ tabeli (lub silnik


przechowywania) za pomoc polecenia ALTER

204

Zaawansowany SQL i MySQL


3. Moesz sprawdzi zmian typu tabeli, wykonujc
ponownie polecenie SHOW TABLE STATUS.

Wskazwki
Aby uatwi odczytanie wynikw dowolnego

zapytania, moesz doda w kliencie mysqla


parametr \G na kocu zapytania (rysunek 6.33):
SHOW TABLE STATUS \G

Rysunek 6.33. Aby uzyska bardziej czyteln


posta wynikw zapytania, uyem znacznika \G

Znacznik ten informuje, e tabela wynikw


powinna zosta wywietlona pionowo zamiast
poziomo. Zwr uwag, e nie musisz w tym
przypadku uy rednika koczcego polecenie
SQL, poniewa funkcj t spenia znacznik \G.
W tej samej bazie danych mog wystpowa

205

Stosowanie rnych typw tabeli

rne typy tabel. W zalenoci od domylnego


typu tabel w Twojej instalacji MySQL-a,
stwierdzenie to moe ju by prawdziwe dla bazy
danych forum. To samo moesz zaobserwowa
w przypadku bazy danych ecommerce, w ktrej
tabele klientw i produktw s typu MyISAM,
ale tabela zamwie jest typu InnoDB
(aby umoliwi stosowanie transakcji).

Rozdzia 6.

Wyszukiwanie FULLTEXT

Realizacja podstawowego wyszukiwania


FULLTEXT

W rozdziale 5. przedstawiem sowo kluczowe LIKE


Po zaoeniu indeksu FULLTEXT moesz
umoliwiajce proste porwnania acuchw,
wydawa zapytania przy uyciu funkcji MATCH
na przykad:
i AGAINST w wyraeniach warunkowych WHERE:
SELECT * FROM users
WHERE last_name LIKE 'Kowalsk%';

W ten sposb nie wykonamy jednak wyszukiwa


z zastosowaniem wielu sw. Aby stao si to
moliwe, wprowadzono wyszukiwania FULLTEXT.
Wyszukiwania FULLTEXT wymagaj obecnoci
indeksu FULLTEXT, ktry mona zaoy jedynie
na tabelach typu MyISAM. W nastpnych przykadach
bd uywa tabeli messages bazy forum. Jeli
utworzona przez Ciebie tabela messages nie jest typu
MyISAM i (lub) nie ma indeksu FULLTEXT zaoonego
na kolumnach body i subject, wykonaj kroki podane
na kilku poprzednich stronach, aby to zmieni.

Wyszukiwanie FULLTEXT

Wskazwki
Wstawianie rekordw do tabel, na ktrych
zaoono indeks FULLTEXT, moe by znacznie

wolniejsze ze wzgldu na skomplikowan


natur tego indeksu.
Indeks FULLTEXT moemy zakada na wielu

kolumnach, jeli wszystkie maj by


przeszukiwane.
Wyszukiwania FULLTEXT mog suy

do implementacji prostych usug wyszukiwania.


Poniewa jednak indeks FULLTEXT stosuje
si do jednej tabeli, to usugi wyszukiwania
informacji w wielu tabelach wymagaj
zastosowania bardziej zaawansowanych
rozwiza.

206

SELECT * FROM tabela


WHERE MATCH (kolumna)
AGAINST('poszukiwane_sowa')

MySQL zwrci pasujce rekordy poczwszy


od speniajcych warunek wyszukiwania
w najwikszym stopniu. Podczas wyszukiwania
stosowane s nastpujce reguy:
X acuchy rozbijane s na poszczeglne

sowa.
X Sowa krtsze ni 4-znakowe s ignorowane.
X Sowa czsto uywane s ignorowane.
X Jeli ponad poowa rekordw spenia

warunek wyszukiwania, to nie jest zwracany


aden rekord.
Zwaszcza ostatnia regua jest zaskakujca
dla wielu uytkownikw, ktrzy rozpoczynaj
dopiero przygod z wyszukiwaniami FULLTEXT
i dziwi si, dlaczego nie zwracaj one adnych
wynikw. Jeli wypenisz tabel zbyt ma
liczb rekordw, to MySQL nie zwrci
waciwych wynikw.

Zaawansowany SQL i MySQL


Aby wykona wyszukiwanie FULLTEXT:
1. Wypenij tabel messages du iloci
danych zwaszcza w polu body.

Moesz uy w tym celu polece INSERT


cignitych z serwera ftp.
2. Wykonaj proste wyszukiwanie FULLTEXT

dla sowa skrypt (patrz rysunek 6.34).


SELECT subject, body FROM messages
WHERE MATCH (body, subject)
AGAINST ('skrypt');

Ten prosty przykad zwrci wynik pod


warunkiem, e co najmniej jeden rekord i mniej
ni poowa rekordw tabeli messages zawiera
sowo tabela w polu body lub subject. Zwr
uwag, e kolumny, do ktrych odwouje si
MATCH, musz by tymi samymi kolumnami,
jakie podae, tworzc indeks FULLTEXT. W tym
przykadzie moge zatem uy albo body,
subject, albo subject, body, ale nie samych body
lub subject (patrz rysunek 6.35).

Wyszukiwanie FULLTEXT

Rysunek 6.34. Podstawowe wyszukiwanie FULLTEXT

Rysunek 6.35. Zapytanie FULLTEXT moesz wykona jedynie na tej samej


kolumnie lub kombinacji kolumn, dla ktrej utworzye indeks FULLTEXT.
W tym przypadku zapytanie zakoczy si bdem, mimo e kombinacja
kolumn body i subject ma indeks FULLTEXT

207

Rozdzia 6.
3. Wykonaj to samo wyszukiwanie FULLTEXT,

pokazujc dodatkowo stopie spenienia


warunku przez poszczeglne rekordy (patrz
rysunek 6.36).
SELECT subject, body,
MATCH (body, subject)
AGAINST('skrypt') AS R
FROM messages
WHERE MATCH (body, subject)
AGAINST('skrypt');

Jeli uyjesz tego samego wyraenia


MATCH...AGAINST jako wybieranej wartoci,
to pokazany zostanie rwnie stopie spenienia
warunku przez rekordy.
4. Wykonaj wyszukiwanie FULLTEXT stosujc kilka

sw (rysunek 6.37).

Wyszukiwanie FULLTEXT

SELECT subject, body


FROM messages
WHERE MATCH (body, subject)
AGAINST('projekt formularz');

W tym przypadku rekord speni warunek


wyszukiwania, jeli pole subject lub body
bdzie zawiera jedno z podanych sw. Rekord
zawierajcy oba sowa uzyska wyszy stopie
spenienia warunku.

Wskazwki
Pamitaj, e jeli wyszukiwanie FULLTEXT

nie zwrci adnych rekordw, to albo aden


rekord nie spenia warunku wyszukiwania,
albo spenia go ponad poowa rekordw.
Dla uproszczenia wszystkie zapytania

przedstawione w tym podrozdziale


zapisaem jako najprostsze polecenia SELECT.
Wyszukiwania FULLTEXT mona te uywa
w bardziej skomplikowanych zapytaniach
czy zczeniach.
MySQL zawiera w kodzie rdowym

list kilkuset sw pospolitych, ktre s


ignorowane w wyszukiwaniach FULLTEXT.
Minimaln dugo wyszukiwanego sowa

(wynoszc domylnie 4 znaki) mona


konfigurowa.
Domylnie wyszukiwania FULLTEXT

nie rozrniaj maych i wielkich liter.

Rysunek 6.36. Moesz rwnie zobaczy stopie speniania warunku wyszukiwania przez poszczeglne rekordy

Rysunek 6.37. Wyszukiwanie FULLTEXT mona take stosowa dla wielu sw

208

Zaawansowany SQL i MySQL


Znak maski (*) umoliwia wyszukiwanie rnych
wariantw sowa. Na przykad zastosowanie go
w sowie bezpiecz* spowoduje wyszukanie rekordw
Bardziej zaawansowane wyszukiwania FULLTEXT zawierajcych sowa bezpieczny, bezpieczestwo
mona wykonywa, korzystajc z trybu
i tym podobnych. Dwa kolejne operatory
Boolean. W trybie tym uywamy wyraenia
umoliwiaj okrelenie, e dane sowo jest mniej (<)
IN BOOLEAN MODE wewntrz klauzuli AGAINST: lub bardziej (>) wane. Znaki cudzysowu pozwalaj
wyszukiwa cae frazy, a nawiasy tworzy
SELECT * FROM tabela WHERE
MATCH(kolumny)
podwyraenia.

Wyszukiwania FULLTEXT
w trybie Boolean

AGAINST('poszukiwane_sowa'
IN BOOLEAN MODE)

W trybie Boolean moemy stosowa szereg


operatorw (tabela 6.10) okrelajcych sposb
traktowania kadego wyszukiwanego sowa:
SELECT * FROM tabela WHERE
MATCH(kolumny)
AGAINST('+baza -mysql' IN BOOLEAN MODE)

SELECT * FROM tabela WHERE


MATCH (kolumny) AGAINST('>"serwer WWW" +html
~JavaScript' IN BOOLEAN MODE)

W trybie Boolean pojawiaj si nastpujce rnice


w sposobie dziaania wyszukiwania FULLTEXT:
X Jeli sowo nie jest poprzedzone adnym

operatorem, to jest opcjonalne, ale podnosi


warto rekordu, ktry je zawiera.
X Wyniki s zwracane nawet wtedy, gdy ponad

poowa rekordw spenia warunek


wyszukiwania.
X Wyniki nie s automatycznie sortowane

Tabela 6.10. Operatory umoliwiajce


precyzyjniejsze wyszukiwanie FULLTEXT
Operatory dostpne w trybie Boolean
Operator

Znaczenie

Rekord musi zawiera sowo poprzedzone


tym operatorem.

Rekord nie moe zawiera sowa


poprzedzonego tym operatorem.

Sowo poprzedzone tym operatorem obnia


warto rekordu jako wyniku wyszukiwania.

Maska wyszukiwania.

<

Zmniejsza znaczenie sowa.

>

Zwiksza znaczenie sowa.

""

Rekord musi zawiera fraz umieszczon


w znakach cudzysowu.

()

Tworzy podwyraenie.

na podstawie stopnia, w jakim speniaj warunek


wyszukiwania.
Z uwagi na t ostatni waciwo mona
samodzielnie posortowa rekordy wedug
stopnia w jakim speniaj warunek wyszukiwania,
co zaprezentuj w kilku nastpnych krokach.
W przypadku wyszukiwa w trybie Boolean nadal
obowizuje zasada, e sowa krtsze ni 4-znakowe
s ignorowane. Nie zmienia tego uycie operatora
+, na przykad sowo +php zostanie zignorowane.

209

Wyszukiwanie FULLTEXT

W tym przykadzie rekord zostanie wybrany,


jeli zawiera sowo baza i nie zawiera sowa
mysql. Jako sabsz form operatora
reprezentowanego przez znak minus ( -)
moemy stosowa tyld (~). Oznacza ona,
e rekord moe zawiera dane sowo,
ale wtedy w mniejszym stopniu spenia
warunek wyszukiwania.

Ponisze zapytanie wyszuka rekordy zawierajce


fraz serwer WWW oraz sowo html. Obecno
sowa JavaScript obniy warto rekordu jako
wyniku wyszukiwania.

Rozdzia 6.
Aby wykona wyszukiwanie FULLTEXT
w trybie Boolean:
1. Wykonaj proste wyszukiwanie FULLTEXT rnych

przypadkw sowa baza (bazy, bazie itp.)


(patrz rysunek 6.38).
SELECT subject, body FROM
messages WHERE MATCH(body, subject)
AGAINST('baz*' IN BOOLEAN MODE) \G

Sowo baza moe pojawi si w wiadomociach


forum w wielu rnych przypadkach takich
jak bazy lub bazie. Powysze zapytanie wyszuka
rekordy zawierajce te przypadki dziki
zastosowaniu znaku maski (*).

Wyszukiwanie FULLTEXT

Dodatkowo zastosowaem znacznik \G,


aby atwiej przeanalizowa wyniki.

2. Wykonaj zapytanie wyszukujce

wiadomoci dotyczce tabel


ze szczeglnym uwzgldnieniem
zawierajcych termin normalizacja
(patrz rysunek 6.39).
SELECT subject, body FROM messages
WHERE MATCH(body, subject)
AGAINST ('>formularz* +skrypt*'
IN BOOLEAN MODE)\G

Zapytanie to najpierw wyszukuje


wszystkie rekordy zawierajce sowo
skrypt* (skryptu, skrypty, ) i formularz*
(formularz, formularza, formularzy, ).
Obecno terminu skrypt* jest wymagana
(na co wskazuje operator +), natomiast
wyrnione zostaj rekordy zawierajce
termin formularz* (na co wskazuje
operator >).

Rysunek 6.38. Proste wyszukiwanie FULLTEXT w trybie BOOLEAN

Rysunek 6.39. To wyszukiwanie dotyczy wariantw dwch rnych sw, z ktrych jedno ma wyszy priorytet

210

Zaawansowany SQL i MySQL


Wskazwki
W MySQL 5.1.7 wprowadzono jeszcze jeden
tryb wyszukiwa FULLTEXT: tryb jzyka

naturalnego. Jeli nie wybierzesz innego trybu


(np. Boolean), to jest on trybem domylnym.
Modyfikator WITH QUERY EXPANSION pozwala

Optymalizacja bazy danych


Efektywno dziaania bazy danych zaley
gwnie od jej struktury i indeksw. Tworzc
baz, powiniene sprbowa:
Wybra najlepszy silnik przechowywania.
Uywa jak najmniej pojemnego typu

danych dla kadej kolumny.


Definiowa kolumny jako NOT NULL tam,

zwikszy liczb zwracanych wynikw.


Zapytania z tym modyfikatorem wykonuj
w rzeczywistoci dwa wyszukiwania, ale zwracaj
jeden zbir wynikw. Drugie wyszukiwanie
bazuje na terminach wyszukanych dodatkowo
w najlepszych wynikach pierwszego
wyszukiwania. Pozwala to znale dodatkowe
rekordy, ale nie zawsze odpowiadaj one
pocztkowym kryteriom wyszukiwania.

gdzie to moliwe.
Uywa wartoci cakowitych jako kluczy

gwnych.
Uwanie definiowa indeksy, wybierajc

Wyszukiwanie FULLTEXT

odpowiedni typ oraz stosujc je


dla waciwych kolumn.
Ogranicza indeksy do pewnej liczby

znakw, jeli to moliwe.


Oprcz tych wskazwek warto zastosowa
dwie proste techniki optymalizacji baz
danych. Jednym ze sposobw poprawy
efektywnoci dziaania MySQL-a jest
wykonanie polecenia OPTIMIZE dla tabel.
Polecenie to usuwa wolne przestrzenie
i przywraca wysok efektywno dziaania
tabel.
OPTIMIZE TABLE tabela;

Wykonanie tego polecenia jest szczeglnie


zalecane po modyfikacji tabeli za pomoc
polecenia ALTER.
Aby zwikszy wydajno wykonywanego
zapytania, warto zrozumie, w jaki sposb
serwer MySQL-a je przetwarza. W tym celu
naley posuy si sowem kluczowym
jzyka SQL o nazwie EXPLAIN. Informacje
na temat dziaania zapyta znajdziesz
w podrczniku MySQL-a.

211

Rozdzia 6.

Wykonywanie transakcji

Wykonywanie transakcji

Po zatwierdzeniu lub wycofaniu zapyta


transakcja jest uznawana za zakoczon
Transakcja bazodanowa to seria zapyta
i MySQL wraca do trybu automatycznego
wykonywanych podczas jednej sesji. Przypumy, zatwierdzania (ang. autocommit). Oznacza to,
e wstawiamy rekord do jednej tabeli, inny rekord e wszystkie zapytania s natychmiast
do drugiej tabeli, a potem wykonujemy aktualizacj. realizowane. Aby rozpocz nastpn
Bez transakcji kada operacja jest realizowana
transakcj, wystarczy ponownie wpisa START
natychmiast i nie mona jej cofn. Jeli uyjemy TRANSACTION.
transakcji, bdziemy mogli ustawi punkt
pocztkowy i kocowy, a nastpnie zatwierdzi Trzeba wiedzie, e niektrych typw transakcji
lub wycofa wszystkie zapytania (jeli, na przykad, nie da si wycofa; dotyczy to w szczeglnoci
zawiedzie jedno zapytanie, bdzie mona wycofa zapyta, ktre tworz, modyfikuj, oprniaj
lub usuwaj tabele albo tworz lub usuwaj
wszystkie).
bazy danych. Co wicej, wykonanie takiego
Transakcje s czsto potrzebne w interakcjach
zapytania skutkuje zatwierdzeniem
finansowych, nawet tak podstawowych jak przelew i zakoczeniem biecej transakcji.
100 zotych z jednego konta na drugie. Proces ten
wydaje si prosty, ale w rzeczywistoci skada si Powiniene te pamita, e transakcje s
specyficzne dla kadego poczenia. Zatem
z kilku etapw:
jeden uytkownik klienta mysql dokonuje
X Potwierdzenia, e na pierwszym koncie znajduje innej transakcji ni uytkownik drugiego
si przynajmniej 100 zotych.
klienta, a obie te transakcje s niezalene
od realizowanych przez skrypt PHP.
X Zmniejszenia stanu pierwszego konta
o 100 zotych.
To powiedziawszy, zaprezentuj bardzo prosty
X Zwikszenia stanu drugiego konta o 100 zotych.
X Sprawdzenia, czy udao si zwikszy stan

drugiego konta.
Jeli ktrakolwiek z tych operacji si nie powiedzie,
naley cofn je wszystkie. Jeli na przykad nie uda
si umieci pienidzy na drugim koncie, powinny
one wrci na pierwsze. Odbywa si to do momentu,
w ktrym uda si przeprowadzi ca transakcj.
Aby korzysta z transakcji w MySQL-u, trzeba
posugiwa si tabelami InnoDB (lub silnikiem
tego typu). W celu rozpoczcia nowej transakcji
w kliencie mysql naley wpisa:
START TRANSACTION;

Na zakoczenie transakcji naley wyda instrukcj


COMMIT, aby zatwierdzi wszystkie zapytania,
albo ROLLBACK, aby je wycofa.

212

przykad uycia transakcji w kliencie mysql.


W rozdziale 17. poka, jak realizowa
transakcje z wykorzystaniem skryptw PHP.

Zaawansowany SQL i MySQL


Aby wykona transakcj,
naley wykona ponisze czynnoci:
1. Uruchomi klienta mysql i wybra baz

danych test.
Poniewa jest to tylko przykad,
wykorzystam hipotetyczn baz danych test.
2. Utworzy now tabel accounts

(patrz rysunek 6.40).


CREATE TABLE accounts (
id INT UNSIGNED NOT NULL
AUTO_INCREMENT,
name VARCHAR(40) NOT NULL,
balance DECIMAL(10,2) NOT NULL
DEFAULT 0.0,
PRIMARY KEY (id))
ENGINE=InnoDB;

Oczywicie trudno uzna to za kompletny


projekt tabeli czy bazy danych. Zasady
normalizacji nakazywayby rozdzieli imi
i nazwisko uytkownika na dwie kolumny,
a nawet umieci je w innej tabeli. Jednake
tabela ta w zupenoci wystarczy do naszych
celw.
Najwaniejszym aspektem definicji tabeli jest
okrelenie mechanizmu InnoDB, ktry obsuguje
transakcje.
3. Wypeni tabel danymi.
INSERT INTO accounts (name, balance)
VALUES ('Beata Piechota', 5460.30),
('Dawid Wjcik', 909325.24),
('Ilona Machnik', 892.00);

Mona uy dowolnie wybranych nazwisk


i wartoci. Naley zauway, e MySQL
automatycznie zatwierdzi to zapytanie,
poniewa nie zostaa jeszcze rozpoczta
adna transakcja.

Wykonywanie transakcji

Rysunek 6.40. Nowa tabela utworzona w bazie danych test posuy


do zademonstrowania transakcji

213

Rozdzia 6.
4. Rozpocz transakcj i pobra biec zawarto

tabeli (patrz rysunek 6.41).


START TRANSACTION;
SELECT * FROM accounts;

5. Podj 100 zotych z konta Dawida Wjcika

(albo dowolnego innego uytkownika).


UPDATE accounts
SET balance=(balance-100)
WHERE id=2;

Rysunek 6.41. Rozpoczto transakcj i wywietlono


wszystkie rekordy znajdujce si w tabeli

Instrukcja UPDATE, odrobina matematyki


i klauzula WHERE pozwalaj zmniejszy stan
konta o 100 zotych. Cho MySQL informuje,
e zmodyfikowany zosta jeden wiersz, efekt
nie bdzie trway, dopki transakcja nie zostanie
zatwierdzona.
6. Wpaci 100 zotych na konto Beaty Piechoty:

Wykonywanie transakcji

UPDATE accounts
SET balance=(balance+100)
WHERE id=1;

Jest to przeciwiestwo operacji wykonanej


w etapie 5., co odzwierciedla przelewanie
100 zotych z jednego konta na drugie.
7. Sprawdzi wyniki (patrz rysunek 6.42).
SELECT * FROM accounts;

Jak wida na rysunku, na jednym koncie


jest teraz o 100 zotych wicej, a na drugim
o 100 zotych mniej ni na pocztku
(patrz rysunek 6.41).

214

Rysunek 6.42. Wykonano dwa zapytania


i wywietlono wyniki

Zaawansowany SQL i MySQL


8. Wycofa transakcj.
ROLLBACK;

Aby zademonstrowa wycofywanie transakcji,


uniewaniam wykonane wczeniej zapytania.
Instrukcja ROLLBACK przywraca baz danych
do stanu sprzed rozpoczcia transakcji. Instrukcja
ta koczy jednoczenie transakcj, przeczajc
MySQL-a z powrotem do trybu automatycznego
zatwierdzania.
Rysunek 6.43. Poniewa uyto instrukcji
ROLLBACK, wykonane wczeniej zapytania
zostay wycofane

9. Sprawdzi wyniki (patrz rysunek 6.43).


SELECT * FROM accounts;

Zapytanie powinno zwrci zawarto tabeli


sprzed rozpoczcia transakcji.
10. Powtrzy etapy 4. 6.

11. Zatwierdzi transakcj i sprawdzi wyniki

(patrz rysunek 6.44).


Rysunek 6.44. Instrukcja COMMIT
utrwala rezultaty transakcji

COMMIT;
SELECT * FROM accounts;

Po wydaniu instrukcji COMMIT transakcja zostanie


zatwierdzona, co oznacza, e wszystkie zmiany
stan si trwae. Instrukcja ta jednoczenie
koczy transakcj, przeczajc MySQL-a
z powrotem do trybu automatycznego
zatwierdzania.

215

Wykonywanie transakcji

Aby sprawdzi, co si stanie w razie


zatwierdzenia transakcji, naley ponownie
wykona dwa zapytania UPDATE. Naley pamita
o rozpoczciu nowej transakcji, poniewa
w przeciwnym razie zapytania zostan
automatycznie zatwierdzone!

Rozdzia 6.
Wskazwki
Jedn z najwikszych zalet transakcji jest to,

e zapewniaj one ochron przed zdarzeniami


losowymi, takimi jak awaria serwera. Transakcja
jest albo w caoci zatwierdzana,
albo ignorowana.
Aby wyczy tryb automatycznego

zatwierdzania w serwerze MySQL-a,


naley wpisa:
SET AUTOCOMMIT=0;

Nie trzeba bdzie wwczas wydawa instrukcji


START TRANSACTION, a wszystkie wykonane
zapytania zostan zrealizowane dopiero
po wpisaniu instrukcji COMMIT (albo uyciu
zapytania CREATE, ALTER itp.).
W transakcjach mona tworzy punkty zapisu:
SAVEPOINT nazwa_punktu_zapisu;

Wykonywanie transakcji

Funkcja ta umoliwia wycofanie transakcji


do okrelonego punktu zapisu:
ROLLBACK TO SAVEPOINT nazwa_punktu_zapisu;

216

You might also like