SlideShare une entreprise Scribd logo
1  sur  47
Télécharger pour lire hors ligne
PHP6 i MySQL 5.
Dynammiczne strony www.
Szybki start
Autor: Larry Ullman
T³umaczenie: Jaromir Senczyk
ISBN: 978-83-246-1723-4
Tytu³ orygina³u: PHP 6 and MySQL 5
for Dynamic Web Sites: Visual QuickPro Guide
Format: 170x230, stron: 640

        Poznaj mo¿liwoœci PHP6 oraz MySQL 5 i twórz dynamiczne strony WWW
    • Jak utworzyæ podstawowy skrypt PHP?
    • Jak korzystaæ z wielowymiarowych tablic?
    • Jak budowaæ bazy danych?
Ka¿da funkcjonalna i atrakcyjna dla u¿ytkowników strona internetowa musi byæ
na bie¿¹co aktualizowana, a umieszczone na niej interesuj¹ce informacje powinny byæ
³atwo dostêpne. Najpopularniejsze narzêdzia typu open source, s³u¿¹ce do tworzenia
dynamicznych witryn, to jêzyk PHP i system zarz¹dzania relacyjnymi bazami danych
MySQL. Oba te narzêdzia oferuj¹ wysok¹ wydajnoœæ, przenoœnoœæ i niezawodnoœæ.
Wœród wielu ogromnych mo¿liwoœci oraz zalet PHP i MySQL maj¹ tak¿e tak¹, ¿e
sprawne pos³ugiwanie siê nimi nie jest zbyt skomplikowane nawet dla pocz¹tkuj¹cych.
Ksi¹¿ka „PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start” zawiera precyzyjny
opis czynnoœci oraz bogato ilustrowane zrzutami ekranu niezbêdne wskazówki
i wyjaœnienia, u³atwiaj¹ce samodzielne zbudowanie dynamicznej strony internetowej.
Dziêki temu podrêcznikowi nauczysz siê wyszukiwaæ i usuwaæ b³êdy w skryptach PHP,
tworzyæ formularze w jêzyku HTML oraz zapobiegaæ atakom na Twoje witryny. Poznasz
tak¿e podstawowe i zaawansowane techniki tworzenia ró¿nych aplikacji (na przyk³ad
stron wielojêzycznych lub obs³uguj¹cych fora dyskusyjne).
    • PHP i MySQL
    • Tworzenie formularza w jêzyku HTML
    • Tablice i ³añcuchy
    • Tworzenie i wywo³ywanie w³asnych funkcji
    • Wype³nianie baz danych
    • Zabezpieczenia
    • Stosowanie modyfikatorów
    • Szyfrowanie danych
    • Tworzenie uniwersalnych witryn
    • Budowanie strony domowej
    • Wielojêzyczna strona WWW
    • Tworzenie kont u¿ytkowników i nadawanie uprawnieñ
                    Szybko i ³atwo naucz siê tworzyæ funkcjonalne
                        oraz bezpieczne witryny internetowe
Spis treści

              Wprowadzenie                                                                                                                  9
              Czym są dynamiczne strony WWW? ................................................................... 10
              Co będzie Ci potrzebne? ....................................................................................... 16
              O tej książce ........................................................................................................... 17

Rozdział 1.   Wprowadzenie do PHP                                                                                                          19
              Podstawy składni.................................................................................................... 20
              Przesyłanie danych do przeglądarki internetowej ............................................... 24
              Wstawianie komentarzy......................................................................................... 28
              Co to są zmienne? .................................................................................................. 32
              Łańcuchy ................................................................................................................ 36
              Łączenie łańcuchów............................................................................................... 39




                                                                                                                                                      Spis treści
              Liczby ..................................................................................................................... 41
              Stałe ........................................................................................................................ 45
              Apostrof kontra cudzysłów .................................................................................... 48

Rozdział 2.   Programowanie w PHP                                                                                                          51
              Tworzenie formularza w języku HTML ............................................................... 52
              Obsługa formularza HTML................................................................................... 56
              Wyrażenia warunkowe i operatory ....................................................................... 60
              Weryfikacja danych pochodzących z formularza ................................................. 64
              Co to są tablice? ..................................................................................................... 70
              Pętle for i while ...................................................................................................... 88

Rozdział 3.   Tworzenie dynamicznych stron WWW                                                                                             91
              Wykorzystywanie plików zewnętrznych .............................................................. 92
              Wyświetlanie i obsługa formularza przez jeden skrypt ....................................... 102
              Tworzenie formularzy z pamięcią ....................................................................... 107
              Tworzenie i wywoływanie własnych funkcji ...................................................... 110

Rozdział 4.   Wprowadzenie do MySQL                                                                                                       125
              Elementy bazy danych i ich nazwy..................................................................... 126
              Wybór typu kolumny ........................................................................................... 128
              Wybór innych właściwości kolumn .................................................................... 132
              Korzystanie z serwera MySQL-a ........................................................................ 134

                                                                                                                                                  5
Spis treści


              Rozdział 5.   Wprowadzenie do SQL                                                                                                     141
                            Tworzenie baz danych i tabel.............................................................................. 142
                            Wprowadzanie rekordów..................................................................................... 145
                            Wybieranie danych .............................................................................................. 149
                            Wyrażenia warunkowe ........................................................................................ 151
                            Stosowanie LIKE i NOT LIKE .......................................................................... 154
                            Sortowanie wyników zapytania ........................................................................... 156
                            Ograniczanie wyników zapytania........................................................................ 158
                            Uaktualnianie danych .......................................................................................... 160
                            Usuwanie danych ................................................................................................. 162
                            Funkcje ................................................................................................................. 164
              Rozdział 6.   Zaawansowany SQL i MySQL                                                                                                175
                            Projekt bazy danych............................................................................................. 176
                            Złączenia............................................................................................................... 191
                            Grupowanie wyników zapytania ......................................................................... 196
                            Indeksy ................................................................................................................. 198
                            Stosowanie różnych typów tabeli........................................................................ 203
                            Wyszukiwanie FULLTEXT ................................................................................ 206
Spis treści




                            Wykonywanie transakcji...................................................................................... 212
              Rozdział 7.   Obsługa i usuwanie błędów                                                                                               217
                            Ogólne typy błędów i ich usuwanie.................................................................... 218
                            Wyświetlanie błędów PHP.................................................................................. 224
                            Sterowanie raportowaniem błędów PHP ........................................................... 226
                            Tworzenie własnych funkcji obsługi błędów ..................................................... 229
                            Techniki usuwania błędów z PHP ...................................................................... 234
                            Techniki usuwania błędów 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 wyników zapytania ...................................................................... 257
                            Bezpieczeństwo zapytań...................................................................................... 261
                            Zliczanie zwróconych rekordów ......................................................................... 267
                            Uaktualnianie rekordów w PHP ......................................................................... 269
              Rozdział 9.   Tworzenie aplikacji internetowych                                                                                      277
                            Przekazywanie wartości do skryptu..................................................................... 278
                            Stosowanie ukrytych pól formularza................................................................... 282
                            Edycja istniejących rekordów ............................................................................. 288

              6
Spis treści

             Stronicowanie wyników zapytań......................................................................... 295
             Wyświetlanie tabel z możliwością sortowania.................................................... 303

Rozdział 10. Tworzenie aplikacji internetowych                                                                                        309
             Wysyłanie poczty elektronicznej ........................................................................ 310
             Funkcje daty i czasu............................................................................................. 316
             Obsługa przesyłania plików................................................................................. 320
             Skrypty PHP i JavaScript .................................................................................... 333
             Nagłówki HTTP ................................................................................................... 340

Rozdział 11. Sesje i „ciasteczka”                                                                                                      345
             Strona logowania .................................................................................................. 346
             Funkcje logowania ............................................................................................... 349
             Posługiwanie się ciasteczkami............................................................................. 354
             Sesje ...................................................................................................................... 367
             Zwiększanie bezpieczeństwa sesji ...................................................................... 376

Rozdział 12. Zabezpieczenia                                                                                                            379
             Zapobieganie spamowi ........................................................................................ 380




                                                                                                                                                    Spis treści
             Walidacja danych według typu ........................................................................... 387
             Zapobieganie atakom XSS ................................................................................... 392
             Zapobieganie wstrzykiwaniu poleceń SQL........................................................ 395
             Szyfrowanie i bazy danych .................................................................................. 401

Rozdział 13. Wyrażenie regularne Perl                                                                                                 407
             Skrypt testujący.................................................................................................... 408
             Definiowanie prostych wzorców......................................................................... 412
             Stosowanie kwantyfikatorów ............................................................................... 415
             Klasy znaków ........................................................................................................ 418
             Wyszukiwanie wszystkich dopasowań................................................................ 421
             Stosowanie modyfikatorów.................................................................................. 425
             Dopasowywanie i zastępowanie wzorców.......................................................... 427

Rozdział 14. Tworzenie uniwersalnych witryn                                                                                            431
             Zbiory znaków i kodowanie................................................................................. 432
             Tworzenie wielojęzycznych stron WWW .......................................................... 434
             Unicode w PHP ................................................................................................... 438
             Uporządkowanie zbioru znaków w PHP ............................................................ 442
             Transliteracja w PHP........................................................................................... 445
             Języki i MySQL.................................................................................................... 448
             Strefy czasowe i MySQL ..................................................................................... 452
             Lokalizatory .......................................................................................................... 455

                                                                                                                                                7
Spis treści


              Rozdział 15. Forum dyskusyjne — przykład                                                                                            459
                            Baza danych.......................................................................................................... 460
                            Szablony................................................................................................................ 469
                            Strona domowa..................................................................................................... 478
                            Strona forum......................................................................................................... 479
                            Strona wątku......................................................................................................... 484
                            Wstawianie wiadomości....................................................................................... 489

              Rozdział 16. Rejestracja użytkowników — przykład                                                                                     501
                            Tworzenie szablonu ............................................................................................. 502
                            Skrypty konfiguracyjne........................................................................................ 508
                            Tworzenie strony domowej ................................................................................. 516
                            Rejestracja ............................................................................................................ 518
                            Aktywacja konta ................................................................................................... 527
                            Logowanie i wylogowywanie się......................................................................... 531
                            Zarządzanie hasłami............................................................................................. 537

              Rozdział 17. Sklep internetowy — przykład                                                                                            547
                            Tworzenie bazy danych ....................................................................................... 548
Spis treści




                            Część administracyjna aplikacji .......................................................................... 554
                            Tworzenie szablonu części publicznej aplikacji................................................. 571
                            Katalog produktów............................................................................................... 575
                            Koszyk................................................................................................................... 587
                            Rejestrowanie zamówień ..................................................................................... 597

              Dodatek A     Instalacja                                                                                                            605
                            Instalacja w systemie Windows .......................................................................... 606
                            Definiowanie uprawnień MySQL....................................................................... 609
                            Testowanie instalacji............................................................................................ 613
                            Konfigurowanie PHP........................................................................................... 616

                            Skorowidz                                                                                                              619




              8
Zaawansowany SQL i MySQL                                                        6
Rozdział 6. Zaawansowany SQL i MySQL

Rozdział ten zaczyna się w miejscu, w którym ostatni się kończył. Omówię w nim bardziej
zaawansowane zagadnienia dotyczące SQL-a i MySQL-a. Poznałeś już podstawy obu tych
technologii i z pewnością wystarczą Ci one do realizacji wielu projektów, ale dopiero ich
bardziej wyszukane możliwości wyniosą Twe aplikacje internetowe na wyższy poziom.
Zacznę od szczegółowego omówienia procesu projektowania bazy danych, opierając się
na przykładzie systemu zarządzania forum. Doprowadzi nas to oczywiście do tematu
złączeń, będących integralną częścią każdej relacyjnej bazy danych. Następnie będę
opisywał kolejną kategorię funkcji wbudowanych MySQL-a używanych do grupowania
wyników zapytań.
Na zakończenie przejdę do bardziej zaawansowanych zagadnień. Powiem o indeksach,
nauczę Cię zmieniać strukturę istniejących tabel oraz omówię typy tabel dostępne
w MySQL-u. Rozdział zakończę omówieniem dwóch dodatkowych możliwości MySQL-a:
przeszukiwania tekstów i transakcji.




                                                                                            Zaawansowany SQL i MySQL




                                                                                      175
Rozdział 6.


                      Projekt bazy danych                                  W moim przykładowym systemie będę chciał
                                                                           stworzyć forum, na którym użytkownicy mogą
                      Pierwsze, co musisz zrobić, gdy pracujesz z systemem zamieszczać swoje opinie i odpowiadać innym
                      zarządzania relacyjnymi bazami danych, takim jak internautom. Aby korzystać z forum, użytkownik
                      MySQL, to utworzyć strukturę bazy (zwaną również będzie musiał się zarejestrować, a następnie
                      schematem bazy danych). Projektowanie bazy danych uwierzytelnić za pomocą kombinacji nazwy i hasła.
                      lub inaczej modelowanie danych to niezbędny etap Przewiduję również możliwość istnienia wielu
                      gwarantujący długotrwałe i bezproblemowe zarządzanie forów poświęconych różnym tematom. W tabeli
                      Twoimi informacjami. W procesie zwanym normalizacją 6.1 pokazałem, jak wygląda przykładowy rekord.
                      eliminuje się niepotrzebne powtórzenia informacji    Baza danych będzie nosić nazwę forum.
                      i inne problemy, które zagrażają spójności danych.
                                                                               Wskazówki
                      Dzięki technikom, które poznasz w tym rozdziale,
                      Twoje bazy będą wydajne i niezawodne. Jeden                 Istnieje bardzo dobra metoda na określenie,
                      z przykładów, które zaprezentuję — forum, na którym         jakiego rodzaju informacje powinny się
                      użytkownicy mogą wymieniać się opiniami — będzie            znaleźć w bazie danych. Wystarczy,
                      intensywnie wykorzystywany dopiero w rozdziale 15.,         że zastanowisz się, jakiego rodzaju pytania
                      „Forum dyskusyjne — przykład”. Jednak omówione              o dane będą zadawane przez użytkowników
                      przeze mnie zasady normalizacji odnoszą się                 i jakie dane będą musiały się znaleźć
                      do wszystkich aplikacji bazodanowych, jakie możesz          w odpowiedziach.
                      utworzyć. (Przykład bazy sitename używany                   Nauka normalizacji może sprawić Ci trudności,
                      w poprzednich dwóch rozdziałach został poprawnie            jeśli niepotrzebnie skoncentrujesz się na
                      zaprojektowany również z punktu widzenia normalizacji,      szczegółach. Każda z postaci normalnych jest
                      ale zagadnienie to nie zostało jeszcze omówione.)           zdefiniowana w dość skomplikowany sposób,
                                                                                  a próba przełożenia tych definicji na język
Projekt bazy danych




                      Normalizacja                                                niefachowy może być myląca. Dlatego radzę
                      Proces normalizacji został wymyślony na początku lat        Ci, abyś podczas lektury omówienia postaci
                      siedemdziesiątych przez E.F. Codda, naukowca z firmy        normalnych skoncentrował się na ogólnym
                      IBM, który wymyślił też relacyjne bazy danych. Tego         obrazie zmian zachodzących w schemacie
                      rodzaju bazy to nic innego jak tylko zbiór danych           bazy danych. Po zakończeniu normalizacji
                      ułożonych w pewien określony sposób. Istnieje szereg        i otrzymaniu końcowej postaci bazy danych
                      tak zwanych postaci normalnych (NF, z ang. Normal           cały proces powinien stać się dla Ciebie
                      Form), które ułatwiają definiowanie struktury danych.       wystarczająco zrozumiały.
                      W tym rozdziale omówię pierwsze trzy z nich,          Tabela 6.1. Przykładowy rekord pokazujący, jakiego
                      ponieważ w większości przypadków są one w pełni rodzaju informacje chcę przechowywać w mojej
                      wystarczające.                                        bazie danych
                      Zanim zaczniesz normalizować swoją bazę danych,          Przykładowe dane forum
                      musisz określić, jakie funkcje będzie pełniła Twoja      Element           Przykład
                      aplikacja. Być może będziesz musiał w tym celu           username         janek
                      porozmawiać z klientem lub samodzielnie zastanowić       password         haslo
                      się nad tym zagadnieniem. W każdym razie struktura       actual name      Jan Kowalski
                      bazy danych zależy od sposobu, w jaki aplikacja będzie
                                                                               user email       jank@example.com
                      odwoływała się do zgromadzonych w niej informacji.
                                                                               forum            MySQL
                      Na tym etapie będziesz więc potrzebował raczej kartki
                                                                               message subject Pytanie na temat normalizacji
                      i ołówka niż MySQL-a. Oczywiście, w ten sposób
                                                                               message body     Nie rozumiem jednej rzeczy. Dla drugiej
                      projektuje się wszystkie relacyjne bazy danych,
                                                                                                postaci normalnej (2NF) podano...
                      nie tylko te działające w systemie MySQL.
                                                                               message date     2 lutego 2008 12:20


                      176
Zaawansowany SQL i MySQL


Klucze                                              Baza danych forum składa 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
wspominałem już, że klucze są integralną częścią klucz główny (klucze obce pojawią się w następnych
znormalizowanych baz danych. Spotkasz się           krokach).
z dwoma rodzajami kluczy, głównymi i obcymi.
Klucz główny to unikatowy identyfikator, który Aby przypisać klucz główny:
podlega pewnym ściśle określonym regułom.
Musi on:                                             1. Poszukaj pól, które spełniają wszystkie trzy warunki
                                                        określone dla kluczy głównych.
    Zawsze mieć jakąś wartość (inną niż NULL).
                                                        W naszym przykładzie (tabela 6.1) żadna z kolumn
    Mieć stałą wartość (taką, która nigdy nie ulega     nie spełnia kryteriów klucza głównego. Nazwa
    zmianie).                                           użytkownika i adres e-mail są unikalne dla każdego
    Mieć inną wartość dla każdego rekordu               użytkownika forum, ale nie dla każdego rekordu
    w tabeli.                                           bazy danych (ten sam użytkownik może umieszczać
                                                        wiele wiadomości na forum). Również ten sam
Najlepszym, z życia wziętym przykładem klucza           temat wiadomości może występować wiele razy.
głównego jest numer ubezpieczenia społecznego           Tekst wiadomości będzie prawdopodobnie zawsze
przydzielany obywatelom USA. Każdy ma tam               unikalny, ale może się zmieniać na skutek
własny, niezmienny, unikatowy numer polisy.             późniejszych poprawek, tym samym naruszając
Ułatwia to identyfikowanie osób. Wkrótce                jedno z kryteriów wyboru klucza głównego.
przekonasz się, że wielokrotnie sam będziesz
tworzył we wszystkich tabelach klucze główne.        2. Jeżeli nie istnieje żaden logiczny kandydat na klucz
Jest to po prostu dobra praktyka projektowa.            główny — wprowadź go! (tabela 6.2).




                                                                                                                   Projekt bazy danych
Drugi rodzaj kluczy stanowią klucze obce.                      Sytuacja, w której musisz sam utworzyć klucz
Reprezentują one w tabeli B klucze główne                      główny, ponieważ żadne z istniejących pól nie
tabeli A. Jeżeli masz na przykład bazę danych                  nadaje się do pełnienia tej roli, występuje dość
filmy, w której występują tabele film i reżyser,               często. W tym konkretnym przykładzie utworzę
to klucz główny tabeli reżyser będzie pełnił                   pole message ID.
rolę klucza obcego w tabeli film. Już niedługo
zobaczysz, jak to wszystko działa w praktyce.                Wskazówki
                                                               Stosuję się do reguły, w myśl której w nazwach
Tabela 6.2. Dodałem do tabeli klucz główny, dzięki czemu       kluczy głównych powinna wystąpić przynajmniej
będę mógł łatwo odwoływać się do rekordów                      część nazwy tabeli (np. message) i przyrostek id.
 Baza danych forum                                             Niektórzy projektanci dodają również skrót pk
                                                               (ang. primary key — klucz główny).
 Element           Przykład
 message ID        1                                           MySQL zezwala na stosowanie w każdej tabeli
 username          janek                                       tylko jednego klucza głównego, choć możesz oprzeć
 password          haslo                                       go na kilku kolumnach (oznacza to, że kombinacja
 actual name       Jan Kowalski                                tych kolumn musi być unikatowa).
 user email        jank@example.com                            Najlepiej byłoby, gdyby Twój klucz główny
 forum             MySQL                                       był zawsze liczbą całkowitą, ponieważ pozwala
 message subject Pytanie na temat normalizacji                 to MySQL-owi osiągnąć najwyższą możliwą
 message body      Nie rozumiem jednej rzeczy. Dla drugiej     wydajność.
                   postaci normalnej (2NF) podano...
 message date      2 lutego 2008 12:20



                                                                                                             177
Rozdział 6.


                      Zależności                                             Wskazówki
                      Mówiąc o zależnościach w bazach danych mam                Modelowanie baz danych rządzi się
                      na myśli to, w jaki sposób dane z jednej tabeli są        pewnymi regułami. Istnieje określona
                      powiązane z danymi występującymi w drugiej.               konwencja reprezentowania struktury
                      Zależności między dwiema tabelami mogą                    bazy (zostanie ona tutaj zachowana).
                      przybierać postać jeden do jednego, jeden do wielu        Na rysunku 6.1 pokazałem symbole trzech
                      lub wiele do wielu. (Dwie tabele tej samej bazy           rodzajów zależności.
                      danych mogą być również wcale niepowiązane).              Proces projektowania bazy danych prowadzi
                      O zależności „jeden do jednego” mówimy wtedy,             do powstania diagramu zależności między
                      gdy jeden i tylko jeden element tabeli A odnosi się       encjami (ERD), na którym występują
                      do jednego i tylko jednego elementu tabeli B              prostokąty reprezentujące tabele oraz
                      (np. każdy mieszkaniec USA ma tylko jeden numer           symbole z rysunku 6.1.
                      ubezpieczenia społecznego, a każdy numer polisy           Istnieje wiele programów służących
                      jest przyporządkowany tylko do jednego obywatela.         do tworzenia schematów baz danych.
                      Nikt nie może mieć dwóch polis, podobnie jak              Jednym z nich jest MySQL Workbench
                      żaden numer ubezpieczenia nie może odnosić się            (www.mysql.com).
                      do dwóch osób).
                                                                                Termin „relacyjny” w określeniu „system
                      Zależność „jeden do wielu” występuje wtedy,               zarządzania relacyjnymi bazami danych”
                      gdy jakiś element tabeli A może odnosić się do kilku      odnosi się do tabel, które nazywa się
                      różnych elementów tabeli B. Na przykład,                  relacjami.
                      określenia mężczyzna i kobieta mogą być używane
                      w odniesieniu do wielu osób, ale każdy człowiek
Projekt bazy danych




                      może mieć tylko jedną płeć. Jest to najczęściej
                      występująca zależność między tabelami
                      w znormalizowanych bazach danych.
                      Istnieje też zależność „wiele do wielu”, w której
                      kilka elementów tabeli A może odnosić się do kilku
                      elementów tabeli B. Na przykład rekord płyta
                      może zawierać piosenki wykonywane przez różnych
                      artystów, a każdy artysta może mieć na swoim
                      koncie kilka płyt. W swoich projektach powinieneś
                      unikać tego typu zależności, ponieważ prowadzą one
                      do problemów ze spójnością danych i sprzyjają ich      Rysunek 6.1. Pokazane tu symbole często spotyka
                      powielaniu. Zamiast zależności „wiele do wielu”        się na diagramach strukturalnych. Opisują one
                      stworzysz tabelę pośrednią, dzięki której zależność    zależności występujące między tabelami
                      „wiele do wielu” zostanie rozbita na dwie zależności
                      „jeden do wielu”.
                      Temat zależności jest w pewien sposób związany
                      z zagadnieniem kluczy, ponieważ klucze
                      zdefiniowane w jednej tabeli odwołują się zazwyczaj
                      do pól występujących w innych tabelach.



                      178
Zaawansowany SQL i MySQL


Pierwsza postać normalna                      Na przykład tabela zawierająca pole, w którym
                                              można umieścić kilka numerów telefonów (domowy,
Jak już powiedziałem wcześniej, normalizacja komórkowy, 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 może się znaleźć więcej niż jedna wartość.
Dostosowywanie to musi być precyzyjne         Jeśli chodzi o drugi warunek, to tabela film
i odbywać się w określonej kolejności.        zawierająca kolumny aktor1, aktor2, aktor3 i tak
Mówimy, że baza danych jest pierwszej postaci dalej, nie będzie w pierwszej postaci normalnej,
normalnej (1NF), jeżeli:                      ponieważ powtarzające się kolumny zawierają
                                              ten sam rodzaj informacji.
    Każda kolumna zawiera tylko jedną wartość
    (czyli jest atomowa lub niepodzielna).    Proces normalizacji rozpocznę od sprawdzenia,
                                              czy aktualna struktura bazy (tabela 6.2) jest zgodna
    Żadna tabela nie ma powtarzających się z 1NF. Kolumny, które nie są atomowe, zostaną
    kolumn dla danych pozostających w pewnej rozbite na wiele kolumn. Jeśli tabela posiada
    zależności.                               powtarzające się, podobne kolumny, to zostaną
                                              one przekształcone w osobną tabelę.

                                                    Aby uczynić bazę zgodną z 1NF:
                                                     1. Zidentyfikuj pole, które może zawierać kilka
                                                       informacji naraz.
                                                       Gdy spojrzysz jeszcze raz na tabelę 6.2,
                                                       zobaczysz, że jedno z pól nie jest zgodne




                                                                                                         Projekt bazy danych
                                                       z 1NF: actual name. Zawiera ono zarówno
                                                       imię jak i nazwisko użytkownika.
                                                       Pole message date (data dodania do bazy)
                                                       przechowuje, co prawda, dzień, miesiąc i rok,
                                                       ale raczej nie będzie nas interesować taki
                                                       poziom szczegółowości i potraktujemy
Tabela 6.3. Tabela z atomowymi kolumnami
                                                       przechowywaną przez nie wartość jako
Baza danych forum                                      niepodzielną. Zresztą pod koniec poprzedniego
Element             Przykład                           rozdziału pokazałem, że MySQL potrafi
message ID          1                                  doskonale obsługiwać dane reprezentujące
username            janek                              daty i czas za pomocą typu DATETIME.
password            haslo                              Gdyby tabela zawierała na przykład jedną,
first name          Jan                                wspólną kolumnę dla imienia i nazwiska zamiast
last name           Kowalski                           dwóch osobnych albo przechowywała wiele
user email          jank@example.com                   numerów telefonów (stacjonarny, komórkowy,
forum               MySQL                              domowy, służbowy) w jednej kolumnie,
message subject     Pytanie na temat normalizacji      to kolumny te również należałoby rozbić.
message body        Nie rozumiem jednej rzeczy.
                    Dla drugiej postaci normalnej
                                                     2. Rozbij wszystkie pola odszukane w kroku 1.
                    (2NF) podano...                    na kilka mniejszych, niepodzielnych pól
message date        2 lutego 2008 12:20                (tabela 6.3).


                                                                                                   179
Rozdział 6.


                         Aby poradzić sobie z tym problemem, utwórz        Wskazówki
                         osobne pola first name i last name, które będą
                                                                                Dostosowanie tabeli do 1NF wymaga
                         zawierać tylko jedną wartość.
                                                                                analizy tabeli w poziomie. Wszystkie
                       3. Przekształć każdą grupę powtarzających się            kolumny jednego rekordu przeglądamy
                         kolumn w osobną tabelę.                                pod kątem występowania w nich danych,
                                                                                które nie są atomowe oraz występowania
                         Problem ten nie występuje w bazie danych
                                                                                powtarzających się, podobnych danych.
                         forum. Zademonstruję go zatem na przykładzie
                         przedstawionym w tabeli 6.4. Powtarzające się          Postacie normalne opisane są w różnych
                         kolumny zawierające informacje o aktorach              źródłach w różny sposób, często z użyciem
                         powodują dwa problemy. Po pierwsze,                    bardziej technicznego żargonu.
                         dla każdego filmu można podać tylko                    Najważniejszy jest jednak sens i końcowy
                         ograniczoną liczbę aktorów. Nawet jeśli                rezultat procesu normalizacji, a nie
                         wprowadzimy kolumny aktor 1 aż do aktor 100,           słownictwo zastosowane do jego opisu.
                         to ograniczeniem będzie stu aktorów. Po drugie,
                         każdy rekord, który nie zawiera maksymalnej       Tabela 6.4. Tabela film nie jest zgodna z 1NF
                         liczby aktorów, będzie mieć wartości NULL         z dwóch powodów. Po pierwsze, zawiera
                         w nadmiarowych kolumnach. W schemacie             powtarzające się kolumny podobnych danych
                         bazy danych powinniśmy unikać kolumn              (aktor1 itd.). Po drugie, kolumny aktor i reżyser
                         zawierających wartości NULL. Dodatkowym           nie zawierają wartości atomowych
                         problemem jest również to, że kolumny             Tabela film
                         zawierające informacje o reżyserze i aktorach     Kolumna                 Wartość
                         nie są atomowe.                                   film ID                 976
Projekt bazy danych




                         Aby rozwiązać problemy występujące w tabeli       tytuł filmu             Casablanca
                         film, utworzę dodatkową tabelę (tabela 6.5).      rok produkcji           1943
                         Każdy jej rekord zawiera informacje o jednym      reżyser                 Michael Curtiz
                         autorze, co rozwiązuje problemy opisane           aktor1                  Humphrey Bogart
                         powyżej. Także nazwiska i imiona aktorów są       aktor2                  Ingrid Bergman
                         teraz przechowywane jako wartości atomowe.        aktor3                  Peter Lorre
                         Zwróć również uwagę, że do nowej tabeli
                         dodałem kolumnę indeksu głównego. Zasada,         Tabela 6.5. Aby tabela film (tabela 6.4) była zgodna
                         że każda tabela posiada klucz główny, wynika      z 1NF, powiążę aktorów z filmami za pomocą tabeli
                         wprost z pierwszej postaci normalnej.             film-aktor
                       4. Upewnij się, że wszystkie nowe pola utworzone    Tabela film-aktor
                         w kroku 2. i 3. są zgodne z 1NF.                  ID    Film              Imię aktora   Nazwisko aktora
                                                                           1     Casablanca        Humphrey      Bogart
                                                                           2     Casablanca        Ingrid        Bergman
                                                                           3     Casablanca        Peter         Lorre
                                                                           4     Sokół maltański   Humphrey      Bogart
                                                                           5     Sokół maltański   Peter         Lorre




                      180
Zaawansowany SQL i MySQL


                                                  Druga postać normalna
                                                   Każda baza, która ma spełniać drugą postać
                                                   normalną (2NF), musi być najpierw zgodna z 1NF
                                                   (proces normalizacji trzeba przeprowadzać
                                                   we właściwej kolejności). Następnie wszystkie
                                                   kolumny, które nie zawierają kluczy (kluczy obcych),
                                                   muszą być powiązane zależnością z kluczem
                                                   głównym. Kolumny, które naruszają ten warunek,
Rysunek 6.2. Aby baza danych o filmach była zgodna łatwo zidentyfikować po tym, że zawierają wartości
z 2NF, potrzebne są cztery tabele. Reżyserzy są
                                                   niebędące kluczami i powtarzające się w różnych
reprezentowani w tabeli film za pomocą klucza
                                                   rekordach. Wartości te muszą zostać umieszczone
reżyser ID; filmy są reprezentowane w tabeli
film-aktor za pomocą klucza film ID; aktorzy są    w osobnej tabeli i być powiązane z tabelą wyjściową
reprezentowani w tabeli film-aktor za pomocą       za pomocą klucza.
klucza aktor ID                                   Przykładem może być fikcyjna tabela film
                                                  (tabela 6.4), która zawierałaby ponad dwadzieścia
                                                  razy nazwisko Martina Scorsese jako reżysera
                                                  różnych filmów. Sytuacja taka jest niezgodna z drugą
                                                  postacią normalną, ponieważ kolumna zawierająca
                                                  informację o reżyserze nie jest kluczem i nie jest
                                                  powiązana zależnością z kluczem głównym (film ID).
                                                  Rozwiązanie polega na utworzeniu osobnej tabeli
                                                  reżyserzy wyposażonej we własny klucz główny,




                                                                                                          Projekt bazy danych
                                                  który wystąpiłby jako klucz obcy w tabeli film,
                                                  tworząc w ten sposób powiązanie obu tabel.
                                                  Patrząc na tabelę 6.5, można dostrzec dwa kolejne
                                                  naruszenia drugiej 2NF — ani tytuły filmów,
                                                  ani nazwiska aktorów nie są powiązane z kluczem
                                                  głównym tabeli. Zatem baza danych o filmach
                                                  w najprostszej postaci wymaga czterech tabel
                                                  (rysunek 6.2). W ten sposób informacje o każdym
                                                  filmie, aktorze i reżyserze są przechowywane tylko
                                                  jeden raz, a każda kolumna niebędąca kluczem
                                                  jest zależna od klucza głównego danej tabeli.
                                                  W zasadzie proces normalizacji można by określić
                                                  jako tworzenie coraz większej liczby tabel, tak
                                                  aby całkowicie wyeliminować możliwość powielenia
                                                  jakichkolwiek danych.




                                                                                                    181
Rozdział 6.


                      Aby uczynić bazę zgodną z 2NF:
                       1. Zidentyfikuj kolumny, które nie są kluczami
                            i które nie są powiązane z kluczem głównym.
                            Przyglądając się tabeli 6.3 zauważysz, że żadne
                            z pól username, first name, last name, email
                            i forum nie są kluczami (jedyną kolumną będącą
                            kluczem jest na razie message ID) i żadne z nich
                            nie jest powiązane zależnością z message ID.
                            Natomiast message subject, body i date również
                                                                                 Rysunek 6.3. Aby baza danych forum była zgodna
                            nie są kluczami, ale ich wartości zależą od klucza   z 2NF, potrzebne są trzy tabele
                            message ID.

                       2. Utwórz odpowiednie tabele (patrz rysunek 6.3).
                            Najlogiczniejsza modyfikacja istniejącej struktury
                            polega na utworzeniu trzech tabel: users, forums
                            i messages.
                            Na diagramie bazy danych każda tabela została
                            przeze mnie oznaczona prostokątem. Jej nazwa
                            pełni rolę nagłówka, pod którym wymienione
                            są wszystkie kolumny (atrybuty) tabeli.
                       3. Przypisz lub utwórz nowe klucze główne
Projekt bazy danych




                            (rysunek 6.4).
                                                                                 Rysunek 6.4. Każda tabela powinna mieć własny
                            Posługując się technikami opisanymi wcześniej        klucz główny
                            w tym rozdziale, upewnij się, że każda nowa
                            tabela ma zdefiniowany klucz główny. W tabeli
                            users stworzyłem 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 każdego rekordu i zawsze
                            mieć wartość, to mógłbyś użyć ich jako kluczy
                            głównych. Oznaczałoby to jednak, że wartości
                            tych pól nie mogą się zmieniać (zgodnie
                            z jednym z kryteriów wyboru klucza głównego).
                            Użycie kluczy tekstowych zamiast numerycznych
                            powodowałoby również nieco wolniejsze
                            działanie bazy danych.




                      182
Zaawansowany SQL i MySQL


                                                    4. Utwórz pomocnicze klucze obce, które połączą
                                                      tabele zależnościami (rysunek 6.5).
                                                      Ostatni krok na drodze do zgodności z 2NF
                                                      polega na dodaniu kluczy obcych, które określą
                                                      powiązania między tabelami. Pamiętaj, że to,
                                                      co w jednej tabeli jest kluczem głównym,
                                                      w drugiej najprawdopodobniej będzie kluczem
                                                      obcym.
                                                      W naszym przykładzie kolumna user ID z tabeli
                                                      users łączy się z kolumną user ID z tabeli
Rysunek 6.5. Aby zdefiniować zależność między         messages. Dlatego też tabela users pozostaje
tymi trzema tabelami, dodałem do tabeli messages      w zależności „jeden do wielu” z tabelą messages
dwa klucze obce, z których każdy łączy ją z jedną     (każdy użytkownik może umieścić na forum
z pozostałych dwóch tabel                             wiele wiadomości, ale każda wiadomość może
                                                      mieć tylko jednego autora).
                                                      Połączone zostały również dwie kolumny
                                                      forum ID, tworząc w ten sposób zależność „jeden
                                                      do wielu” pomiędzy tabelami messages i forums
                                                      (każda wiadomość może należeć tylko do jednego
                                                      forum, ale dane forum może zawierać wiele
                                                      wiadomości).




                                                                                                         Projekt bazy danych
Wskazówki
   Inny sposób sprawdzenia, czy tabele                W prawidłowo znormalizowanej bazie danych
   spełniają drugą postać normalną, polega            w jednej tabeli nie mają prawa pojawić się
   na przyjrzeniu się powiązaniom tabel.              dwa takie same rekordy (dwa lub więcej
   Idealna sytuacja polega na występowaniu            rekordów, w których wartości występujące
   samych zależności „jeden do wielu”.                w poszczególnych kolumnach są identyczne).
   Tabele podlegające zależnościom „wiele
                                                      Aby łatwiej przyswoić sobie proces normalizacji,
   do wielu” mogą wymagać restrukturyzacji.
                                                      zapamiętaj, że pierwsza postać normalna
   Jeśli przyjrzymy się jeszcze raz rysunkowi         wiąże się z analizą tabeli w poziomie, podczas
   6.2, możemy zauważyć, że tabela film-aktor         gdy druga postać normalna powstaje na skutek
   spełnia funkcję tabeli pośredniczącej.             analizy w pionie (poszukiwania wartości
   Pozwala ona zamienić zależność „wiele              powtarzających się w wielu rekordach).
   do wielu” zachodzącą pomiędzy filmami
   i aktorami na dwie zależności „jeden
   do wielu”. Tabele pośredniczące łatwo
   rozpoznać po tym, że wszystkie ich kolumny
   są kluczami obcymi. W tym przypadku
   kolumna odgrywająca rolę klucza głównego
   nie jest potrzebna, ponieważ kluczem
   głównym może być kombinacja obu
   kolumn tabeli.

                                                                                                   183
Rozdział 6.


                      Trzecia postać normalna                                 Aby uczynić bazę zgodną z 3NF:
                      Mówimy, że baza danych spełnia trzecią postać            1. Zidentyfikuj wszystkie pola, które nie są
                      normalną (3NF), jeżeli jest ona zgodna z 2NF,              bezpośrednio powiązane z kluczem
                      a każda kolumna, która nie jest kluczem, jest zależna      głównym.
                      od klucza głównego. Jeżeli prawidłowo przeszedłeś          Jak już wspomniałem, na tym etapie
                      przez pierwsze dwa etapy normalizacji,                     poszukujemy kolumn, które powiązane są
                      prawdopodobnie dostosowanie bazy danych do 3NF             między sobą zależnościami (tak jak miasto
                      nie będzie już wymagać żadnych zmian. W moim               i stan) zamiast z kluczem głównym.
                      przykładzie (patrz rysunek 6.5) również nie ma             W bazie danych forum nie występowały
                      problemów, które należałoby rozwiązać, aby baza            takie zależności. Przyjrzyjmy się tabeli
                      była zgodna z trzecią postacią normalną. Dlatego           messages. Każda wartość pola subject
                      też przedstawię je omawiając hipotetyczną sytuację.        jest specyficzna dla danego message ID,
                      Weźmy na przykład pojedynczą tabelę                        każda wartość pola body jest specyficzna
                      przechowującą informacje o zarejestrowanych                dla wybranego message ID itd.
                      klientach: imię, nazwisko, e-mail, numer telefonu,       2. Utwórz odpowiednie tabele.
                      adres pocztowy itp. Tabela taka nie jest zgodna            Jeśli w punkcie 1. udało się odnaleźć
                      z 3NF, ponieważ wiele kolumn nie będzie zależnych          problematyczne kolumny, takie jak
                      od klucza głównego. Nazwa ulicy będzie zależeć             na przykład miasto i stan, to tworzymy
                      od miasta, a miasto od stanu. Również kod pocztowy         dla nich osobne tabele cities i states.
                      nie będzie zależeć od tego, jaką osobę opisuje
                                                                               3. Przypisz lub utwórz nowe klucze główne.
                      rekord. Aby znormalizować taką bazę danych,
                      powinno się stworzyć osobną tabelę reprezentującą          Każda tabela musi mieć klucz główny,
                                                                                 wobec czego do nowych tabel dodaję
Projekt bazy danych




                      państwa, osobną reprezentującą miasta (połączoną
                      kluczem obcym z tabelą państw) i jeszcze inną              kolumny city ID i state ID.
                      dla kodów. Wszystkie te tabele byłyby połączone         4. Utwórz pomocnicze klucze obce, definiując
                      z tabelą opisującą klientów.                               tym samym zależności (rysunek 6.6).
                      Jeśli takie rozwiązanie wydaje Ci się przesadą,            Na zakończenie dodałem do tabeli Cities
                      to masz rację. Wyższy stopień normalizacji często          klucz obcy State ID oraz klucz obcy City ID
                      nie jest konieczny. Chociaż powinno się dążyć              do tabeli Clients. W efekcie uzyskałem
                                                                                 połączenie rekordu klienta nie tylko
                      do jak najpełniejszej normalizacji, to czasami warto
                                                                                 z informacją o mieście, w którym jest
                      ją poświęcić na rzecz prostoty. (patrz ramka
                                                                                 zameldowany, ale również o stanie.
                      „Rezygnacja z normalizacji”). W praktyce stopień
                      normalizacji zależy od potrzeb konkretnej aplikacji
                      i szczegółów bazy danych.
                      Jak już wspomniałem, nasz przykład bazy forum
                      nie wymaga dalszej normalizacji (jest już zgodny
                      z 3NF) i dlatego proces dostosowywania do trzeciej
                      postaci normalnej przedstawię właśnie na przykładzie
                      omówionej wyżej bazy danych o klientach.


                                                                              Rysunek 6.6. Uproszczona wersja hipotetycznej
                                                                              bazy clients będzie zawierać dwie nowe tabele
                                                                              przechowujące informacje o miastach i stanach

                      184
Zaawansowany SQL i MySQL


                                                  Wskazówka
                                                    W praktyce nie normalizowałbym tabeli Clients
                                                    aż do takiego stopnia. Gdybym pozostawił
                                                    pola opisujące miasto i stan w tabeli Clients,
                                                    to najgorszą rzeczą, jaka mogłaby się zdarzyć,
                                                    byłaby zmiana nazwy miasta i związana z tym
                                                    konieczność aktualizacji rekordów wszystkich
                                                    klientów będących jego mieszkańcami.
                                                    W rzeczywistości jednak sytuacja taka zdarza
                                                    się bardzo rzadko.
                                                    Mimo istnienia zasad normalizacji baz danych
                                                    dwóch różnych projektantów może dokonać
                                                    normalizacji tej samej bazy w nieco inny sposób.
                                                    Projektowanie baz danych pozostawia pewien
                                                    margines dla indywidualnych preferencji
     Rezygnacja z normalizacji                      i interpretacji. Najważniejsze jest,
Choć spełnienie trzeciej postaci normalnej          by zaprojektowana baza danych nie naruszała
jest korzystne, nie oznacza to jeszcze,             postaci normalnej, gdyż prędzej czy później
że masz normalizować każdą bazę danych,             doprowadzi to do pojawienia się poważnych
z którą pracujesz. Jednocześnie                     problemów.
powinieneś uzmysłowić sobie, że odejście
od sprawdzonych metod może mieć




                                                                                                       Projekt bazy danych
w perspektywie dłuższego czasu
katastrofalne skutki.
Z normalizacji rezygnuje się zazwyczaj
z dwóch powodów — ze względu
na wydajność i dla wygody. Dużo łatwiej
jest ogarnąć mniejszą liczbę tabel, a poza
tym — łatwiej się nimi zarządza. Ze względu
na liczbę powiązań między tabelami,
uaktualnianie, odczytywanie i modyfikowanie
danych w znormalizowanych bazach danych
trwa z reguły dłużej. Krótko mówiąc,
normalizacja jest poświęceniem prostoty
i szybkości na rzecz spójności i skalowalności.
Należy jednak pamiętać, że istnieje znacznie
więcej sposobów na przyspieszenie bazy
danych niż na odzyskanie informacji
utraconych na skutek przechowywania ich
w źle zaprojektowanej bazie.
W miarę nabywania doświadczenia będziesz
potrafił coraz lepiej modelować bazy danych,
ale mimo wszystko staraj się trzymać
po stronie normalizacji.


                                                                                                 185
Rozdział 6.


                      Tworzenie bazy danych                                  2. Utwórz bazę danych forum (rysunek 6.7).
                      Aby zakończyć projekt bazy danych, musimy                    CREATE DATABASE forum;
                      wykonać trzy ostatnie kroki:                                 USE forum;

                       1. Sprawdzić, czy w bazie znajdą się wszystkie          Możliwe, że Twoja konfiguracja nie pozwala
                         potrzebne informacje.                                 na tworzenie nowych baz danych. W takiej
                                                                               sytuacji po prostu wykorzystaj jakąś już
                       2. Zidentyfikować typy kolumn.                          istniejącą bazę i dodawaj do niej kolejne
                       3. Nazwać wszystkie elementy bazy danych.               tabele.

                      Ostateczny projekt bazy danych został                Tabela 6.6. Ostateczny projekt bazy forum
                      przedstawiony w tabeli 6.6. W porównaniu             wraz z typami kolumn
                      do rysunku 6.5 została dodana jeszcze jedna           forum
                      kolumna. Ponieważ wiadomość umieszczana
                                                                            Nazwa kolumny Tabela       Typ kolumny
                      na forum może być odpowiedzią na inną wiadomość,
                      musimy jakoś reprezentować tę zależność w bazie.      forum_id         forums    TINYINT

                      Rozwiązanie polega na dodaniu kolumny parent_id       name             forums    VARCHAR(60)
                      w tabeli messages. Jeśli wiadomość jest odpowiedzią, message_id        messages INT
                      to jej pole parent_id będzie zawierać wartość pola    forum_id         messages TINYINT
                      message_id oryginalnej wiadomości (czyli message_id   parent_id        messages INT
                      spełnia funkcję klucza obcego w tej samej tabeli).    user_id          messages MEDIUMINT
                      Jeśli pole parent_id ma wartość równą 0, oznacza      subject          messages VARCHAR(100)
                      to, że wiadomość stanowi początek nowego wątku,       body             messages LONGTEXT
                      czyli nie jest odpowiedzią na żadną inną wiadomość. date_entered       messages TIMESTAMP
Projekt bazy danych




                                                                            user_id           users     MEDIUMINT
                      Jeśli wprowadzasz jakiekolwiek zmiany w strukturze
                                                                            username          users     VARCHAR(30)
                      tabel, powinieneś ponownie sprawdzić, czy spełniają
                                                                            pass              users     CHAR(40)
                      one wszystkie postacie normalne, aby mieć pewność,
                                                                            first_name        users     VARCHAR(20)
                      że baza danych jest nadal znormalizowana.
                                                                            last_name         users     VARCHAR(40)
                      Zagadnienie nazw tabel i kolumn oraz wyboru typów     email             users     VARCHAR(80)
                      kolumn omówiłem już w rozdziale 4.
                      Gdy schemat jest gotowy, możesz utworzyć
                      odpowiadającą mu bazę danych MySQL-a
                      za pomocą poleceń omówionych w rozdziale 5.,
                      „Wprowadzenie do SQL”.

                      Aby utworzyć bazę danych:
                       1. Użyj wybranego klienta do dostępu do serwera      Rysunek 6.7. Najpierw musisz utworzyć
                         MySQL-a.                                           i wybrać bazę danych

                         Podobnie jak w poprzednim rozdziale,
                         we wszystkich przykładach będziemy posługiwali
                         się monitorem (klientem) mysqla. Oczywiście
                         możesz też śmiało korzystać z phpMyAdmina
                         i innych narzędzi.


                      186
Zaawansowany SQL i MySQL


 3. Utwórz tabelę forums (rysunek 6.8).         Tabela ta zawiera tylko dwie kolumny
     CREATE TABLE forums (                      (sytuacja taka ma często miejsce w przypadku
        forum_id TINYINT UNSIGNED               znormalizowanych baz danych). Ponieważ nie
          NOT NULL AUTO_INCREMENT,              spodziewam się, że tabela ta będzie zawierać
        name VARCHAR(60) NOT NULL,              dużą liczbę rekordów, klucz główny otrzymał
        PRIMARY KEY (forum_id)
     );                                         typ TINYINT. Jeśli chcesz, by baza zawierała
                                                również opis każdego forum, możesz dodać
   Kolejność, w jakiej tworzysz tabele,         do tej tabeli kolumnę typu VARCHAR(255).
   nie ma oczywiście znaczenia. Ja zacznę
   od forums. Pamiętaj, że zawsze możesz      4. Utwórz tabelę messages (rysunek 6.9).
   rozpisać polecenie SQL w kilku wierszach       CREATE TABLE messages (
   na ekranie, jeżeli tylko będzie Ci tak            message_id INT UNSIGNED
                                                       NOT NULL AUTO_INCREMENT,
   wygodniej.
                                                     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 główny musi być
                                                zdecydowanie bardziej pojemny, ponieważ




                                                                                                Projekt bazy danych
                                                spodziewam się, że tabela ta będzie zawierać
                                                bardzo dużo rekordów. Trzy kolumny będące
                                                kluczami obcymi — forum_id, parent_id
                                                i user_id — będą mieć taki sam rozmiar i typ
Rysunek 6.8. Utwórz pierwszą tabelę             jak ich odpowiedniki będące kluczami
                                                głównymi w innych tabelach. Pole subject
                                                zostało ograniczone do 100 znaków, a pole
                                                body może zawierać znaczną ilość tekstu. Pole
                                                date_entered otrzymało typ TIMESTAMP. Będzie
                                                ono przechowywać datę i czas dodania rekordu.
                                                Jego wartość zostanie automatycznie
                                                zaktualizowana (bieżącą datą i czasem)
                                                w momencie wstawienia rekordu (właśnie
                                                w ten sposób zachowuje się typ TIMESTAMP).

Rysunek 6.9. Utwórz drugą tabelę




                                                                                          187
Rozdział 6.


                       5. Utwórz tabelę users (rysunek 6.10).                  6. Jeśli chcesz, możesz upewnić się, że baza
                              CREATE TABLE users (                                danych ma taką strukturę jak powinna
                                 user_id MEDIUMINT UNSIGNED                       (rysunek 6.11).
                                   NOT NULL AUTO_INCREMENT,
                                                                                    SHOW   TABLES;
                                 username VARCHAR(30) NOT NULL,
                                                                                    SHOW   COLUMNS FROM forums;
                                 pass CHAR(40) NOT NULL,
                                                                                    SHOW   COLUMNS FROM messages;
                                 first_name VARCHAR(20) NOT NULL,
                                                                                    SHOW   COLUMNS FROM users;
                                 last_name VARCHAR(40) NOT NULL,
                                 email VARCHAR(80) NOT NULL,                      Ten krok jest opcjonalny, ponieważ MySQL
                                 PRIMARY KEY (user_id)
                              );
                                                                                  i tak wyświetla informacje o pomyślnym
                                                                                  wykonaniu każdego wprowadzanego
                            Większość kolumn tej tabeli wykorzystuje              polecenia. Warto jednak przypomnieć
                            definicje znane z tabeli users bazy sitename          sobie strukturę bazy danych.
                            używanej w poprzednich dwóch rozdziałach.
                            Kolumna pass jest typu CHAR(40), ponieważ         Wskazówka
                            dla haseł będę stosować funkcję SHA1(), która
                                                                                  W przypadku połączenia klucz
                            zwraca zawsze łańcuch o długości 40 znaków
                                                                                  główny-klucz obcy (na przykład forum_id
                            (patrz rozdział 5.).
                                                                                  tabeli forum z forum_id tabeli messages),
                                                                                  obie kolumny muszą być tego samego typu
                                                                                  (w naszym przykładzie: TINYINT UNSIGNED
                                                                                  NOT NULL).
Projekt bazy danych




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


                      188
Zaawansowany SQL i MySQL


Wypełnianie bazy danych                             Aby zapełnić bazę danymi:
W rozdziale 15. napiszemy w PHP interfejs            1. Dodaj kilka nowych rekordów do tabeli forums
WWW dla bazy forums. Będzie on dostarczać              (rysunek 6.12).
standardowego sposobu wypełniania bazy                   INSERT INTO forums (name) VALUES ('MySQL'),
danymi (poprzez rejestrowanie się                        ('PHP'), ('Programowanie'), ('HTML'),
użytkowników i umieszczanie wiadomości                   ('CSS'), ('Bazy danych');
na forum). Zanim jednak dojdziemy do tego              Ponieważ tablica messages jest zależna od
punktu, musisz się jeszcze sporo nauczyć.              wartości odczytywanych z tabel forums i users,
Dlatego na razie wypełnimy bazę danymi                 wypełnię najpierw te ostatnie. W przypadku
za pomocą klienta mysqla. Możesz wykonać               powyższego polecenia INSERT wystarczy jedynie
po kolei poniższe kroki lub skorzystać                 podać wartość kolumny name (MySQL
z gotowych poleceń SQL-a dołączonych do                automatycznie nada wartość kolumnie forum_id).
przykładów zamieszczonych na serwerze ftp.
                                                     2. Dodaj nowe rekordy do tabeli users
                                                       (rysunek 6.13).
                                                         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'), 'Małgorzata',
                                                         'Malinowska', 'mm@example.com');
Rysunek 6.12. Dodawanie rekordów do tabeli forums




                                                                                                            Projekt bazy danych
                                                       Jeśli masz wątpliwości co do składni polecenia
                                                       INSERT lub zastosowania funkcji SHA1(), skorzystaj
                                                       z informacji podanych w rozdziale 5.




Rysunek 6.13. Dodawanie rekordów do tabeli users




                                                                                                     189
Rozdział 6.


                       3. Wstaw nowe rekordy do tabeli messages                      Sprawę dodatkowo komplikuje kolumna
                         (patrz rysunek 6.14).                                       parent_id. Musi ona zawierać wartość
                            SELECT * FROM forums;                                    message_id tej wiadomości, na którą
                            SELECT user_id, username FROM users;                     odpowiedź stanowi nowa wiadomość.
                            INSERT INTO messages (forum_id,                          Druga wiadomość umieszczona w bazie
                            parent_id, user_id, subject, body)                       danych będzie mieć message_id równy
                            VALUES
                            (1, 0, 1, 'Pytanie na temat normalizacji',               2 i wobec tego każda wiadomość stanowiąca
                              'Nie rozumiem jednej rzeczy. Dla drugiej               odpowiedź na tę wiadomość będzie musiała
                              postaci normalnej (2NF) podano...'),                   mieć wartość parent_id równą 2.
                            (1, 0, 2, 'Projekt bazy danych', 'Projektuję
                              nową bazę danych i natrafiłem na pewien                W tworzonych przez Ciebie skryptach
                              problem. Ile tabel powinna mieć moja                   PHP, wszystko to będzie wyglądało
                              baza?...'),
                            (1, 2, 1, 'Projekt bazy danych', 'Liczba
                                                                                     znacznie prościej. Muszę teraz jednak
                              tabel w Twojej bazie danych...'),                      wyłożyć Ci całą teorię, posługując się
                            (1, 3, 2, 'Projekt bazy danych', 'OK,                    terminologią języka SQL.
                              dziękuję!'),
                            (2, 0, 3, 'Błędy PHP', 'Próbuję uruchomić                Zwróć również uwagę, że nie wprowadziłem
                              skrypty z rozdziału 3. i pierwszy skrypt               wartości dla pola date_entered. MySQL
                              kalkulatora nie działa. Gdy akceptuję
                                                                                     automatycznie umieści w nim bieżącą
                              formularz...');
                                                                                     datę i czas, ponieważ jest to kolumna
                         Ponieważ dwa pola tabeli messages (forum_id                 typu TIMESTAMP.
                         oraz user _id) odwołują się do wartości
                                                                                  4. Powtórz kroki od 1. do 3., aby zapełnić
                         przechowywanych w innych tabelach,
                                                                                     bazę danymi.
                         przed wstawieniem nowych rekordów
Projekt bazy danych




                         dokonam wyboru tych wartości. Na przykład,                  We wszystkich kolejnych przykładach
                         gdy użytkownik janek utworzy nową wiadomość                 w tym rozdziale będę wykorzystywał bazę,
                         na forum MySQL-a, musisz użyć forum_id                      którą właśnie zapełniłem. Jeśli chcesz,
                         równy 1 i user_id równy 1.                                  możesz wykonać u siebie te same polecenia
                                                                                     INSERT co ja lub utworzyć swoje własne.




                      Rysunek 6.14. W przypadku znormalizowanych baz danych bardzo często spotkasz się z sytuacją,
                      w której, aby wstawić jakiś rekord do tabeli, będziesz musiał znać wartości przechowywane w innych tabelach


                      190
Zaawansowany SQL i MySQL

                                                     SELECT * FROM messages
Złączenia                                              INNER JOIN forums
                                                       ON messages.forum_id =
Ponieważ relacyjne bazy danych mają złożoną            forums.forum_id
strukturę, aby wydobyć te informacje, które            WHERE forums.name = 'MySQL'
najbardziej nas interesują, musimy czasem
                                                  Złączenie to wybiera wszystkie kolumny obu tabel,
wykonać jakieś niestandardowe zapytanie.
                                                  jeśli spełnione są dwa warunki. Po pierwsze,
Na przykład, jeśli chcesz dowiedzieć się, jakie
                                                  kolumna forums.name musi zawierać wartość
wiadomości zawiera forum MySQL-a, musisz
najpierw dowiedzieć się, jaka jest wartość        MySQL (której odpowiada wartość forum_id
forum_id dla tego forum, a następnie użyć
                                                  równa 1). Po drugie, wartość forum_id w tabeli
                                                  forums musi odpowiadać wartości forum_id
jej do pobrania wszystkich rekordów tabeli
message, które mają taką wartość forum_id.
                                                  w tabeli messages. Ze względu na sprawdzenie
Jak z tego wynika, to proste zadanie wymaga       równości dotyczące pól w różnych tabelach
wykonania dwóch zapytań. Jednak stosując          (messages.forum_id = forums.forum_id) złączenie
złączenie, możesz poradzić sobie z nim            takie nazywa się równościowym.
w jednym kroku.                                   Złączenia wewnętrzne możesz również zapisywać
Złączenie jest zapytaniem SQL-a używającym        bez stosowania klauzuli INNER JOIN:
dwóch lub więcej tabel i tworzącym wirtualną         SELECT * FROM messages, forums WHERE
tabelę wyników. W specyfikacji SQL-a                 messages.forum_id = forums.forum_id
                                                     AND forums.name = 'mySQL'
występują dwa główne typy złączeń:
wewnętrzne i zewnętrzne (oba mają szereg          Jeżeli wybierasz dane z wielu tabel i kolumn,
podtypów).                                        a w kilku tabelach występują kolumny o takiej samej
                                                  nazwie, musisz zastosować notację z kropką
Złączenie wewnętrzne zwraca wszystkie
                                                  (tabela.kolumna). W przypadku relacyjnych baz
rekordy podanych tabel, dla których zachodzi
                                                  danych robi się to praktycznie zawsze, ponieważ
dopasowanie. Na przykład, aby uzyskać




                                                                                                           Złączenia
                                                  klucz główny jednej tabeli ma taką samą nazwę
wszystkie wiadomości zamieszczone
                                                  jak obcy klucz drugiej. Jeżeli nie wskażesz
na forum MySQL, powinieneś użyć
                                                  jednoznacznie kolumny, do której się odwołujesz,
następującego złączenia wewnętrznego
                                                  zobaczysz komunikat o błędzie (rysunek 6.16).
(rysunek 6.15):




Rysunek 6.15. To złączenie zwraca kolumny obu tabel dla rekordów, dla których wartości
forum_id są równe MySQL (1)



                                                         Rysunek 6.16. Ogólne odwołanie do kolumny
                                                         występującej w kilku tabelach spowoduje
                                                         wystąpienie błędu niejednoznaczności

                                                                                                     191
Rozdział 6.


            Złączenia zewnętrzne różnią się od złączeń                  Jeżeli w warunku porównania złączenia
            wewnętrznych tym, że potrafią zwracać rekordy,              zewnętrznego bądź wewnętrznego występuje
            które nie spełniają wyrażenia warunkowego.                  kolumna o takiej samej nazwie w obu tabelach,
            Istnieją trzy podtypy złączeń zewnętrznych: left            możesz uprościć zapis zapytania, stosując
            (lewe), right (prawe) i full (pełne). Przykładem            klauzulę USING:
            pierwszego podtypu jest następujące złączenie:                 SELECT * FROM messages
              SELECT * FROM forums                                           INNER JOIN forums
              LEFT JOIN messages ON                                          USING (forum_id)
              forums.forum_id = messages.forum_id;                           WHERE forums.name = 'mySQL'
                                                                           SELECT * FROM forums
            Najważniejsze przy tego rodzaju złączeniach                      LEFT JOIN messages
            jest to, które tabele należy wymienić jako pierwsze.             USING (forum_id)
            W powyższym przykładzie w przypadku udanego                 Zanim przejdę do przykładów, jeszcze dwie
            dopasowania zwrócone zostaną wszystkie rekordy              uwagi. Po pierwsze, ponieważ składnia
            tabeli forums wraz ze wszystkimi informacjami               wymagana przy tworzeniu złączeń jest dość
            z tabeli messages. Jeśli dla danego rekordu tabeli          skomplikowana, przy ich pisaniu przydają się
            forums nie można dopasować informacji w tabeli              aliasy omówione w rozdziale 5. Po drugie,
            messages, to zamiast nich zostaną zwrócone                  ponieważ złączenia często zwracają dużo
            wartości NULL (rysunek 6.17).                               danych, to najlepiej zawsze określić, które
                                                                        kolumny nas interesują, zamiast wybierać
                                                                        wszystkie.
Złączenia




            Rysunek 6.17. To złączenie zewnętrzne zwraca więcej rekordów niż złączenie wewnętrzne, ponieważ zwraca
            wszystkie wiersze pierwszej tabeli. Zapytanie to zwraca również nazwy wszystkich forów, nawet jeśli nie zawierają
            one jeszcze żadnej wiadomości




            192
Zaawansowany SQL i MySQL


Aby wykorzystać złączenia:                        2. Pobierz temat i datę wprowadzenia każdej
                                                    wiadomości wysłanej przez użytkownika janek
 1. Pobierz nazwę forum i temat wiadomości
                                                    (rysunek 6.19).
    dla każdego rekordu tabeli messages
   (patrz rysunek 6.18).                              SELECT m.subject,
                                                        DATE_FORMAT(m.date_entered,
     SELECT f.name, m.subject                             '%M %D, %Y') AS Date
     FROM forums                                        FROM users AS u INNER JOIN
     AS f INNER JOIN messages AS m                        messages AS m
     USING (forum_id) ORDER BY f.name;                  USING (user_id)
                                                        WHERE u.username = 'janek';
   Zapytanie to zawiera złączenie wewnętrzne,
   które spowoduje w efekcie zastąpienie            Również to złączenie używa dwóch tabel,
   wartości forum_id z tabeli messages              users i messages. Złączenie obu tabel odbywa
   odpowiadającą jej wartością name z tabeli        się za pomocą kolumny user_id i dlatego
   forums dla każdego rekordu tabeli messages.      została ona umieszczona wewnątrz klauzuli
   W wyniku otrzymasz zatem temat każdej            USING. Wyrażenie warunkowe WHERE pozwala
   wiadomości wraz z nazwą forum, do którego        zidentyfikować interesującego nas użytkownika,
   należy ta wiadomość.                             a funkcja DATE_FORMAT sformatować wartość
                                                    pola date_entered.
   Zwróć uwagę, że w połączeniach nadal
   możesz używać klauzul ORDER BY.




                                                                                                      Złączenia
Rysunek 6.18. Podstawowe złączenie wewnętrzne    Rysunek 6.19. Nieco bardziej skomplikowana wersja
zwraca w tym przykładzie tylko dwie kolumny      złączenia wewnętrznego tabele users i messages




                                                                                                193
Rozdział 6.


             3. Pobierz identyfikator wiadomości, temat oraz            4. Dla każdego użytkownika pobierz nazwę
                  nazwę forum dla każdej wiadomości, której               użytkownika, temat wiadomości i nazwę
                  autorem jest użytkownik janek (patrz                    forum (patrz rysunek 6.21).
                  rysunek 6.20).                                             SELECT u.username, m.subject,
                    SELECT m.message_id, m.subject,                          f.name FROM users AS u LEFT JOIN
                      f.name FROM users AS u                                 messages AS m USING (user_id)
                      INNER JOIN                                             LEFT JOIN forums AS f
                      messages AS m USING (user_id)                          USING (forum_id);
                      INNER JOIN forums AS f
                      USING (forum_id)                                    Gdybyś zastosował podobne złączenie
                      WHERE u.username = 'janek';                         wewnętrzne, to użytkownicy, którzy nie
                                                                          są jeszcze autorami żadnej wiadomości,
                  Powyższe złączenie jest podobne                         nie zostaliby uwzględnieni (patrz rysunek
                  do zastosowanego w punkcie 2., ale idzie o krok         6.22). Zatem jeśli interesują Cię wszyscy
                  dalej, dołączając trzecią tabelę. Zwróć szczególną      użytkownicy, powinieneś użyć złączenia
                  uwagę na sposób konstrukcji złączenia                   zewnętrznego. Zwróć uwagę, że tabela,
                  wewnętrznego trzech tabel oraz zastosowanie             która ma być uwzględniona w całości
                  aliasów w celu łatwiejszego odwoływania się             (users w tym przypadku), musi być podana
                  do tabel i ich kolumn.                                  jako pierwsza tabela złączenia typu left.
Złączenia




            Rysunek 6.20. Złączenie wewnętrzne wszystkich trzech       Rysunek 6.21. To złączenie zewnętrzne zwraca
            tabel bazy                                                 dla każdego użytkownika temat każdej wiadomości
                                                                       i nazwę każdego forum. Jeśli użytkownik nie umieścił
                                                                       jeszcze żadnej wiadomości na forum (tak jak tomekj
                                                                       widoczny na dole rysunku), to temat wiadomości
                                                                       i nazwa forum będą mieć dla niego wartości NULL




            194
Zaawansowany SQL i MySQL


Wskazówki                                          Złączenia, które nie zawierają klauzuli WHERE
                                                   (np. SELECT * FROM urls, url_associations),
  Możesz nawet złączyć tabelę z nią samą.
                                                   nazywamy złączeniami pełnymi. Zwracają one
  Złączenia można tworzyć z wykorzystaniem         rekordy z obu tabel. W przypadku dużych tabel
  wyrażeń warunkowych odwołujących się             ilość zwracanych danych może stanowić pewien
  do dowolnych kolumn. Nie muszą one               problem.
  pełnić roli kluczy, choć sytuacja taka jest
                                                   Nigdy nie zostanie zwrócona wartość NULL
  najczęstsza.
                                                   występująca w kolumnie, do której odwołujemy
  Stosując składnię bazadanych.tabela.             się w złączeniu. To dlatego, że nie jest ona równa
  kolumna, możesz wykonywać złączenia              żadnej innej wartości, w tym także innym
  tabeli należących do różnych baz danych,         wartościom NULL.
  o ile tylko wszystkie znajdują się na tym
  samym serwerze. Ta metoda nie zadziała,
  jeżeli bazy komunikują się ze sobą
  za pośrednictwem sieci.




                                                                                                        Złączenia
                         Rysunek 6.22. To złączenie wewnętrzne nie zwróci
                         użytkownika, który nie umieścił jeszcze żadnej
                         wiadomości na forum (tak jak tomekj widoczny
                         na dole rysunku 6.21)




                                                                                                  195
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start
PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start

Contenu connexe

Tendances

Bezstronność sądu i jej gwarancje w polskim procesie karnym
Bezstronność sądu i jej gwarancje w polskim procesie karnymBezstronność sądu i jej gwarancje w polskim procesie karnym
Bezstronność sądu i jej gwarancje w polskim procesie karnymepartnerzy.com
 
Obywatel w post-cywilnym-calosc (1)
Obywatel w post-cywilnym-calosc (1)Obywatel w post-cywilnym-calosc (1)
Obywatel w post-cywilnym-calosc (1)Dawid Bodziony
 
Prawo konkurencji a regulacja sektorowa - ebook
Prawo konkurencji a regulacja sektorowa - ebookPrawo konkurencji a regulacja sektorowa - ebook
Prawo konkurencji a regulacja sektorowa - ebooke-booksweb.pl
 
Ustawa o działalności pożytku publicznego i o wolontariacie. Komentarz - ebook
Ustawa o działalności pożytku publicznego i o wolontariacie. Komentarz - ebookUstawa o działalności pożytku publicznego i o wolontariacie. Komentarz - ebook
Ustawa o działalności pożytku publicznego i o wolontariacie. Komentarz - ebooke-booksweb.pl
 
Proces karny. część szczególna - ebook
Proces karny. część szczególna - ebookProces karny. część szczególna - ebook
Proces karny. część szczególna - ebooke-booksweb.pl
 
Ppej 28 01 2014
Ppej 28 01 2014Ppej 28 01 2014
Ppej 28 01 2014ptwp
 
Kodeks pracy - ebook
Kodeks pracy - ebookKodeks pracy - ebook
Kodeks pracy - ebooke-booksweb.pl
 
Wadliwa spółka partnerska - ebook
Wadliwa spółka partnerska - ebookWadliwa spółka partnerska - ebook
Wadliwa spółka partnerska - ebooke-booksweb.pl
 
Cywilnoprawna ochrona dziecka poczętego a stosowanie procedur medycznych - ebook
Cywilnoprawna ochrona dziecka poczętego a stosowanie procedur medycznych - ebookCywilnoprawna ochrona dziecka poczętego a stosowanie procedur medycznych - ebook
Cywilnoprawna ochrona dziecka poczętego a stosowanie procedur medycznych - ebooke-booksweb.pl
 
Środki odwoławcze w postępowaniu cywilnym - ebook
Środki odwoławcze w postępowaniu cywilnym - ebookŚrodki odwoławcze w postępowaniu cywilnym - ebook
Środki odwoławcze w postępowaniu cywilnym - ebooke-booksweb.pl
 
Ochrona dóbr osobistych w zatrudnieniu - ebook
Ochrona dóbr osobistych w zatrudnieniu - ebookOchrona dóbr osobistych w zatrudnieniu - ebook
Ochrona dóbr osobistych w zatrudnieniu - ebooke-booksweb.pl
 
Helion.2005.php.i.my sql.tworzenie.stron.www.vademecum.profesjonalisty.wyd3
Helion.2005.php.i.my sql.tworzenie.stron.www.vademecum.profesjonalisty.wyd3Helion.2005.php.i.my sql.tworzenie.stron.www.vademecum.profesjonalisty.wyd3
Helion.2005.php.i.my sql.tworzenie.stron.www.vademecum.profesjonalisty.wyd3nicollabre
 
Przestępczość przeciwko zabytkom archeologicznym. Problematyka prawno krymina...
Przestępczość przeciwko zabytkom archeologicznym. Problematyka prawno krymina...Przestępczość przeciwko zabytkom archeologicznym. Problematyka prawno krymina...
Przestępczość przeciwko zabytkom archeologicznym. Problematyka prawno krymina...e-booksweb.pl
 
Ponadnarodowość w systemie politycznym unii europejskiej - ebook
Ponadnarodowość w systemie politycznym unii europejskiej - ebookPonadnarodowość w systemie politycznym unii europejskiej - ebook
Ponadnarodowość w systemie politycznym unii europejskiej - ebooke-booksweb.pl
 
Psychologia Wywieranie Wplywu Darmowy Fragment
Psychologia Wywieranie Wplywu   Darmowy FragmentPsychologia Wywieranie Wplywu   Darmowy Fragment
Psychologia Wywieranie Wplywu Darmowy Fragmentebook
 
Instrukcja obslugi pompy objetosciowej Medima P2
Instrukcja obslugi pompy objetosciowej Medima P2Instrukcja obslugi pompy objetosciowej Medima P2
Instrukcja obslugi pompy objetosciowej Medima P2Polanest
 
Kodeks karny. Praktyczny komentarz - ebook
Kodeks karny. Praktyczny komentarz - ebookKodeks karny. Praktyczny komentarz - ebook
Kodeks karny. Praktyczny komentarz - ebooke-booksweb.pl
 

Tendances (20)

Bezstronność sądu i jej gwarancje w polskim procesie karnym
Bezstronność sądu i jej gwarancje w polskim procesie karnymBezstronność sądu i jej gwarancje w polskim procesie karnym
Bezstronność sądu i jej gwarancje w polskim procesie karnym
 
Obywatel w post-cywilnym-calosc (1)
Obywatel w post-cywilnym-calosc (1)Obywatel w post-cywilnym-calosc (1)
Obywatel w post-cywilnym-calosc (1)
 
Prawo konkurencji a regulacja sektorowa - ebook
Prawo konkurencji a regulacja sektorowa - ebookPrawo konkurencji a regulacja sektorowa - ebook
Prawo konkurencji a regulacja sektorowa - ebook
 
Ustawa o działalności pożytku publicznego i o wolontariacie. Komentarz - ebook
Ustawa o działalności pożytku publicznego i o wolontariacie. Komentarz - ebookUstawa o działalności pożytku publicznego i o wolontariacie. Komentarz - ebook
Ustawa o działalności pożytku publicznego i o wolontariacie. Komentarz - ebook
 
Proces karny. część szczególna - ebook
Proces karny. część szczególna - ebookProces karny. część szczególna - ebook
Proces karny. część szczególna - ebook
 
Od zera-do-ecedeela-cz-4
Od zera-do-ecedeela-cz-4Od zera-do-ecedeela-cz-4
Od zera-do-ecedeela-cz-4
 
Ppej 28 01 2014
Ppej 28 01 2014Ppej 28 01 2014
Ppej 28 01 2014
 
Kodeks pracy - ebook
Kodeks pracy - ebookKodeks pracy - ebook
Kodeks pracy - ebook
 
Wadliwa spółka partnerska - ebook
Wadliwa spółka partnerska - ebookWadliwa spółka partnerska - ebook
Wadliwa spółka partnerska - ebook
 
Cywilnoprawna ochrona dziecka poczętego a stosowanie procedur medycznych - ebook
Cywilnoprawna ochrona dziecka poczętego a stosowanie procedur medycznych - ebookCywilnoprawna ochrona dziecka poczętego a stosowanie procedur medycznych - ebook
Cywilnoprawna ochrona dziecka poczętego a stosowanie procedur medycznych - ebook
 
Środki odwoławcze w postępowaniu cywilnym - ebook
Środki odwoławcze w postępowaniu cywilnym - ebookŚrodki odwoławcze w postępowaniu cywilnym - ebook
Środki odwoławcze w postępowaniu cywilnym - ebook
 
Ochrona dóbr osobistych w zatrudnieniu - ebook
Ochrona dóbr osobistych w zatrudnieniu - ebookOchrona dóbr osobistych w zatrudnieniu - ebook
Ochrona dóbr osobistych w zatrudnieniu - ebook
 
Helion.2005.php.i.my sql.tworzenie.stron.www.vademecum.profesjonalisty.wyd3
Helion.2005.php.i.my sql.tworzenie.stron.www.vademecum.profesjonalisty.wyd3Helion.2005.php.i.my sql.tworzenie.stron.www.vademecum.profesjonalisty.wyd3
Helion.2005.php.i.my sql.tworzenie.stron.www.vademecum.profesjonalisty.wyd3
 
Przestępczość przeciwko zabytkom archeologicznym. Problematyka prawno krymina...
Przestępczość przeciwko zabytkom archeologicznym. Problematyka prawno krymina...Przestępczość przeciwko zabytkom archeologicznym. Problematyka prawno krymina...
Przestępczość przeciwko zabytkom archeologicznym. Problematyka prawno krymina...
 
Ponadnarodowość w systemie politycznym unii europejskiej - ebook
Ponadnarodowość w systemie politycznym unii europejskiej - ebookPonadnarodowość w systemie politycznym unii europejskiej - ebook
Ponadnarodowość w systemie politycznym unii europejskiej - ebook
 
Psychologia Wywieranie Wplywu Darmowy Fragment
Psychologia Wywieranie Wplywu   Darmowy FragmentPsychologia Wywieranie Wplywu   Darmowy Fragment
Psychologia Wywieranie Wplywu Darmowy Fragment
 
Instrukcja obslugi pompy objetosciowej Medima P2
Instrukcja obslugi pompy objetosciowej Medima P2Instrukcja obslugi pompy objetosciowej Medima P2
Instrukcja obslugi pompy objetosciowej Medima P2
 
Kodeks karny. Praktyczny komentarz - ebook
Kodeks karny. Praktyczny komentarz - ebookKodeks karny. Praktyczny komentarz - ebook
Kodeks karny. Praktyczny komentarz - ebook
 
Zasady uspokajania ruchu
Zasady uspokajania ruchuZasady uspokajania ruchu
Zasady uspokajania ruchu
 
Biala ksiega
Biala ksiegaBiala ksiega
Biala ksiega
 

En vedette

Marketing Internetowy W Praktyce
Marketing Internetowy W PraktyceMarketing Internetowy W Praktyce
Marketing Internetowy W PraktyceGregory Grex
 
30. Montowanie i badanie instalacji do odbioru telewizji satelitarnej
30. Montowanie i badanie instalacji do odbioru telewizji satelitarnej30. Montowanie i badanie instalacji do odbioru telewizji satelitarnej
30. Montowanie i badanie instalacji do odbioru telewizji satelitarnejLukas Pobocha
 
Informacja zawodowa
Informacja zawodowaInformacja zawodowa
Informacja zawodowabogna88
 

En vedette (7)

Marketing Internetowy W Praktyce
Marketing Internetowy W PraktyceMarketing Internetowy W Praktyce
Marketing Internetowy W Praktyce
 
30. Montowanie i badanie instalacji do odbioru telewizji satelitarnej
30. Montowanie i badanie instalacji do odbioru telewizji satelitarnej30. Montowanie i badanie instalacji do odbioru telewizji satelitarnej
30. Montowanie i badanie instalacji do odbioru telewizji satelitarnej
 
Informacja zawodowa
Informacja zawodowaInformacja zawodowa
Informacja zawodowa
 
O1.02
O1.02O1.02
O1.02
 
KultPM
KultPMKultPM
KultPM
 
Bachelor Thesis
Bachelor ThesisBachelor Thesis
Bachelor Thesis
 
Periodyzacja taktyczna
Periodyzacja taktycznaPeriodyzacja taktyczna
Periodyzacja taktyczna
 

Similaire à PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start

Ajax, JavaScript i PHP. Intensywny trening
Ajax, JavaScript i PHP. Intensywny treningAjax, JavaScript i PHP. Intensywny trening
Ajax, JavaScript i PHP. Intensywny treningWydawnictwo Helion
 
PHP i MySQL. Dynamiczne strony WWW. Szybki start. Wydanie II
PHP i MySQL. Dynamiczne strony WWW. Szybki start. Wydanie IIPHP i MySQL. Dynamiczne strony WWW. Szybki start. Wydanie II
PHP i MySQL. Dynamiczne strony WWW. Szybki start. Wydanie IIWydawnictwo Helion
 
Pozycjonowanie i optymalizacja stron WWW. Jak się to robi. Wydanie II poprawi...
Pozycjonowanie i optymalizacja stron WWW. Jak się to robi. Wydanie II poprawi...Pozycjonowanie i optymalizacja stron WWW. Jak się to robi. Wydanie II poprawi...
Pozycjonowanie i optymalizacja stron WWW. Jak się to robi. Wydanie II poprawi...Wydawnictwo Helion
 
Witryny nie do ukrycia. Jak zbudować stronę, którą znajdzie każda wyszukiwarka
Witryny nie do ukrycia. Jak zbudować stronę, którą znajdzie każda wyszukiwarkaWitryny nie do ukrycia. Jak zbudować stronę, którą znajdzie każda wyszukiwarka
Witryny nie do ukrycia. Jak zbudować stronę, którą znajdzie każda wyszukiwarkaWydawnictwo Helion
 
PHP i MySQL. Dynamiczne strony WWW. Szybki start
PHP i MySQL. Dynamiczne strony WWW. Szybki startPHP i MySQL. Dynamiczne strony WWW. Szybki start
PHP i MySQL. Dynamiczne strony WWW. Szybki startWydawnictwo Helion
 
Po prostu PHP. Techniki zaawansowane
Po prostu PHP. Techniki zaawansowanePo prostu PHP. Techniki zaawansowane
Po prostu PHP. Techniki zaawansowaneWydawnictwo Helion
 
Serwer SQL 2008. Administracja i programowanie
Serwer SQL 2008. Administracja i programowanieSerwer SQL 2008. Administracja i programowanie
Serwer SQL 2008. Administracja i programowanieWydawnictwo Helion
 
Kurs tworzenia stron internetowych
Kurs tworzenia stron internetowychKurs tworzenia stron internetowych
Kurs tworzenia stron internetowychWydawnictwo Helion
 
Pajączek 5 NxG. Oficjalny podręcznik
Pajączek 5 NxG. Oficjalny podręcznikPajączek 5 NxG. Oficjalny podręcznik
Pajączek 5 NxG. Oficjalny podręcznikWydawnictwo Helion
 
Java. Techniki zaawansowane. Wydanie VIII
Java. Techniki zaawansowane. Wydanie VIIIJava. Techniki zaawansowane. Wydanie VIII
Java. Techniki zaawansowane. Wydanie VIIIWydawnictwo Helion
 
Oracle Database 11g. Programowanie w języku PL/SQL
Oracle Database 11g. Programowanie w języku PL/SQLOracle Database 11g. Programowanie w języku PL/SQL
Oracle Database 11g. Programowanie w języku PL/SQLWydawnictwo Helion
 
Godzina dziennie z Web Analytics. Stwórz dobrą strategię e-marketingową
Godzina dziennie z Web Analytics. Stwórz dobrą strategię e-marketingowąGodzina dziennie z Web Analytics. Stwórz dobrą strategię e-marketingową
Godzina dziennie z Web Analytics. Stwórz dobrą strategię e-marketingowąWydawnictwo Helion
 
Microsoft Visual Studio 2008. Księga eksperta
Microsoft Visual Studio 2008. Księga ekspertaMicrosoft Visual Studio 2008. Księga eksperta
Microsoft Visual Studio 2008. Księga ekspertaWydawnictwo Helion
 
Microsoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Microsoft Visual C++ 2008. Tworzenie aplikacji dla WindowsMicrosoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Microsoft Visual C++ 2008. Tworzenie aplikacji dla WindowsWydawnictwo Helion
 
PHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danych
PHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danychPHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danych
PHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danychWydawnictwo Helion
 
CATIA V5. Podstawy budowy modeli autogenerujących
CATIA V5. Podstawy budowy modeli autogenerującychCATIA V5. Podstawy budowy modeli autogenerujących
CATIA V5. Podstawy budowy modeli autogenerującychWydawnictwo Helion
 
Visual Basic 2008. Warsztat programisty
Visual Basic 2008. Warsztat programistyVisual Basic 2008. Warsztat programisty
Visual Basic 2008. Warsztat programistyWydawnictwo Helion
 

Similaire à PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start (20)

Ajax, JavaScript i PHP. Intensywny trening
Ajax, JavaScript i PHP. Intensywny treningAjax, JavaScript i PHP. Intensywny trening
Ajax, JavaScript i PHP. Intensywny trening
 
PHP i MySQL. Dynamiczne strony WWW. Szybki start. Wydanie II
PHP i MySQL. Dynamiczne strony WWW. Szybki start. Wydanie IIPHP i MySQL. Dynamiczne strony WWW. Szybki start. Wydanie II
PHP i MySQL. Dynamiczne strony WWW. Szybki start. Wydanie II
 
Pozycjonowanie i optymalizacja stron WWW. Jak się to robi. Wydanie II poprawi...
Pozycjonowanie i optymalizacja stron WWW. Jak się to robi. Wydanie II poprawi...Pozycjonowanie i optymalizacja stron WWW. Jak się to robi. Wydanie II poprawi...
Pozycjonowanie i optymalizacja stron WWW. Jak się to robi. Wydanie II poprawi...
 
Witryny nie do ukrycia. Jak zbudować stronę, którą znajdzie każda wyszukiwarka
Witryny nie do ukrycia. Jak zbudować stronę, którą znajdzie każda wyszukiwarkaWitryny nie do ukrycia. Jak zbudować stronę, którą znajdzie każda wyszukiwarka
Witryny nie do ukrycia. Jak zbudować stronę, którą znajdzie każda wyszukiwarka
 
PHP i MySQL. Dynamiczne strony WWW. Szybki start
PHP i MySQL. Dynamiczne strony WWW. Szybki startPHP i MySQL. Dynamiczne strony WWW. Szybki start
PHP i MySQL. Dynamiczne strony WWW. Szybki start
 
Po prostu PHP. Techniki zaawansowane
Po prostu PHP. Techniki zaawansowanePo prostu PHP. Techniki zaawansowane
Po prostu PHP. Techniki zaawansowane
 
Serwer SQL 2008. Administracja i programowanie
Serwer SQL 2008. Administracja i programowanieSerwer SQL 2008. Administracja i programowanie
Serwer SQL 2008. Administracja i programowanie
 
Kurs tworzenia stron internetowych
Kurs tworzenia stron internetowychKurs tworzenia stron internetowych
Kurs tworzenia stron internetowych
 
Pajączek 5 NxG. Oficjalny podręcznik
Pajączek 5 NxG. Oficjalny podręcznikPajączek 5 NxG. Oficjalny podręcznik
Pajączek 5 NxG. Oficjalny podręcznik
 
Java. Techniki zaawansowane. Wydanie VIII
Java. Techniki zaawansowane. Wydanie VIIIJava. Techniki zaawansowane. Wydanie VIII
Java. Techniki zaawansowane. Wydanie VIII
 
Oracle Database 11g. Programowanie w języku PL/SQL
Oracle Database 11g. Programowanie w języku PL/SQLOracle Database 11g. Programowanie w języku PL/SQL
Oracle Database 11g. Programowanie w języku PL/SQL
 
Oracle Discoverer
Oracle DiscovererOracle Discoverer
Oracle Discoverer
 
MySQL. Szybki start
MySQL. Szybki startMySQL. Szybki start
MySQL. Szybki start
 
Godzina dziennie z Web Analytics. Stwórz dobrą strategię e-marketingową
Godzina dziennie z Web Analytics. Stwórz dobrą strategię e-marketingowąGodzina dziennie z Web Analytics. Stwórz dobrą strategię e-marketingową
Godzina dziennie z Web Analytics. Stwórz dobrą strategię e-marketingową
 
Po prostu FrontPage 2003 PL
Po prostu FrontPage 2003 PLPo prostu FrontPage 2003 PL
Po prostu FrontPage 2003 PL
 
Microsoft Visual Studio 2008. Księga eksperta
Microsoft Visual Studio 2008. Księga ekspertaMicrosoft Visual Studio 2008. Księga eksperta
Microsoft Visual Studio 2008. Księga eksperta
 
Microsoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Microsoft Visual C++ 2008. Tworzenie aplikacji dla WindowsMicrosoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Microsoft Visual C++ 2008. Tworzenie aplikacji dla Windows
 
PHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danych
PHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danychPHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danych
PHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danych
 
CATIA V5. Podstawy budowy modeli autogenerujących
CATIA V5. Podstawy budowy modeli autogenerującychCATIA V5. Podstawy budowy modeli autogenerujących
CATIA V5. Podstawy budowy modeli autogenerujących
 
Visual Basic 2008. Warsztat programisty
Visual Basic 2008. Warsztat programistyVisual Basic 2008. Warsztat programisty
Visual Basic 2008. Warsztat programisty
 

Plus de Wydawnictwo Helion

Tworzenie filmów w Windows XP. Projekty
Tworzenie filmów w Windows XP. ProjektyTworzenie filmów w Windows XP. Projekty
Tworzenie filmów w Windows XP. ProjektyWydawnictwo Helion
 
Blog, więcej niż internetowy pamiętnik
Blog, więcej niż internetowy pamiętnikBlog, więcej niż internetowy pamiętnik
Blog, więcej niż internetowy pamiętnikWydawnictwo Helion
 
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktycznePozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczneWydawnictwo Helion
 
E-wizerunek. Internet jako narzędzie kreowania image'u w biznesie
E-wizerunek. Internet jako narzędzie kreowania image'u w biznesieE-wizerunek. Internet jako narzędzie kreowania image'u w biznesie
E-wizerunek. Internet jako narzędzie kreowania image'u w biznesieWydawnictwo Helion
 
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie IICo potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie IIWydawnictwo Helion
 
Makrofotografia. Magia szczegółu
Makrofotografia. Magia szczegółuMakrofotografia. Magia szczegółu
Makrofotografia. Magia szczegółuWydawnictwo Helion
 
Java. Efektywne programowanie. Wydanie II
Java. Efektywne programowanie. Wydanie IIJava. Efektywne programowanie. Wydanie II
Java. Efektywne programowanie. Wydanie IIWydawnictwo Helion
 
PowerPoint 2007 PL. Seria praktyk
PowerPoint 2007 PL. Seria praktykPowerPoint 2007 PL. Seria praktyk
PowerPoint 2007 PL. Seria praktykWydawnictwo Helion
 
Serwisy społecznościowe. Budowa, administracja i moderacja
Serwisy społecznościowe. Budowa, administracja i moderacjaSerwisy społecznościowe. Budowa, administracja i moderacja
Serwisy społecznościowe. Budowa, administracja i moderacjaWydawnictwo Helion
 
USB. Praktyczne programowanie z Windows API w C++
USB. Praktyczne programowanie z Windows API w C++USB. Praktyczne programowanie z Windows API w C++
USB. Praktyczne programowanie z Windows API w C++Wydawnictwo Helion
 
Rewizor GT. Prowadzenie ewidencji księgowej
Rewizor GT. Prowadzenie ewidencji księgowejRewizor GT. Prowadzenie ewidencji księgowej
Rewizor GT. Prowadzenie ewidencji księgowejWydawnictwo Helion
 

Plus de Wydawnictwo Helion (20)

Tworzenie filmów w Windows XP. Projekty
Tworzenie filmów w Windows XP. ProjektyTworzenie filmów w Windows XP. Projekty
Tworzenie filmów w Windows XP. Projekty
 
Blog, więcej niż internetowy pamiętnik
Blog, więcej niż internetowy pamiętnikBlog, więcej niż internetowy pamiętnik
Blog, więcej niż internetowy pamiętnik
 
Access w biurze i nie tylko
Access w biurze i nie tylkoAccess w biurze i nie tylko
Access w biurze i nie tylko
 
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktycznePozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
 
E-wizerunek. Internet jako narzędzie kreowania image'u w biznesie
E-wizerunek. Internet jako narzędzie kreowania image'u w biznesieE-wizerunek. Internet jako narzędzie kreowania image'u w biznesie
E-wizerunek. Internet jako narzędzie kreowania image'u w biznesie
 
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie IICo potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
 
Makrofotografia. Magia szczegółu
Makrofotografia. Magia szczegółuMakrofotografia. Magia szczegółu
Makrofotografia. Magia szczegółu
 
Windows PowerShell. Podstawy
Windows PowerShell. PodstawyWindows PowerShell. Podstawy
Windows PowerShell. Podstawy
 
Java. Efektywne programowanie. Wydanie II
Java. Efektywne programowanie. Wydanie IIJava. Efektywne programowanie. Wydanie II
Java. Efektywne programowanie. Wydanie II
 
JavaScript. Pierwsze starcie
JavaScript. Pierwsze starcieJavaScript. Pierwsze starcie
JavaScript. Pierwsze starcie
 
PowerPoint 2007 PL. Seria praktyk
PowerPoint 2007 PL. Seria praktykPowerPoint 2007 PL. Seria praktyk
PowerPoint 2007 PL. Seria praktyk
 
Excel 2007 PL. Seria praktyk
Excel 2007 PL. Seria praktykExcel 2007 PL. Seria praktyk
Excel 2007 PL. Seria praktyk
 
Access 2007 PL. Seria praktyk
Access 2007 PL. Seria praktykAccess 2007 PL. Seria praktyk
Access 2007 PL. Seria praktyk
 
Word 2007 PL. Seria praktyk
Word 2007 PL. Seria praktykWord 2007 PL. Seria praktyk
Word 2007 PL. Seria praktyk
 
Serwisy społecznościowe. Budowa, administracja i moderacja
Serwisy społecznościowe. Budowa, administracja i moderacjaSerwisy społecznościowe. Budowa, administracja i moderacja
Serwisy społecznościowe. Budowa, administracja i moderacja
 
AutoCAD 2008 i 2008 PL
AutoCAD 2008 i 2008 PLAutoCAD 2008 i 2008 PL
AutoCAD 2008 i 2008 PL
 
Bazy danych. Pierwsze starcie
Bazy danych. Pierwsze starcieBazy danych. Pierwsze starcie
Bazy danych. Pierwsze starcie
 
Inventor. Pierwsze kroki
Inventor. Pierwsze krokiInventor. Pierwsze kroki
Inventor. Pierwsze kroki
 
USB. Praktyczne programowanie z Windows API w C++
USB. Praktyczne programowanie z Windows API w C++USB. Praktyczne programowanie z Windows API w C++
USB. Praktyczne programowanie z Windows API w C++
 
Rewizor GT. Prowadzenie ewidencji księgowej
Rewizor GT. Prowadzenie ewidencji księgowejRewizor GT. Prowadzenie ewidencji księgowej
Rewizor GT. Prowadzenie ewidencji księgowej
 

PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start

  • 1. PHP6 i MySQL 5. Dynammiczne strony www. Szybki start Autor: Larry Ullman T³umaczenie: Jaromir Senczyk ISBN: 978-83-246-1723-4 Tytu³ orygina³u: PHP 6 and MySQL 5 for Dynamic Web Sites: Visual QuickPro Guide Format: 170x230, stron: 640 Poznaj mo¿liwoœci PHP6 oraz MySQL 5 i twórz dynamiczne strony WWW • Jak utworzyæ podstawowy skrypt PHP? • Jak korzystaæ z wielowymiarowych tablic? • Jak budowaæ bazy danych? Ka¿da funkcjonalna i atrakcyjna dla u¿ytkowników strona internetowa musi byæ na bie¿¹co aktualizowana, a umieszczone na niej interesuj¹ce informacje powinny byæ ³atwo dostêpne. Najpopularniejsze narzêdzia typu open source, s³u¿¹ce do tworzenia dynamicznych witryn, to jêzyk PHP i system zarz¹dzania relacyjnymi bazami danych MySQL. Oba te narzêdzia oferuj¹ wysok¹ wydajnoœæ, przenoœnoœæ i niezawodnoœæ. Wœród wielu ogromnych mo¿liwoœci oraz zalet PHP i MySQL maj¹ tak¿e tak¹, ¿e sprawne pos³ugiwanie siê nimi nie jest zbyt skomplikowane nawet dla pocz¹tkuj¹cych. Ksi¹¿ka „PHP6 i MySQL 5. Dynamiczne strony WWW. Szybki start” zawiera precyzyjny opis czynnoœci oraz bogato ilustrowane zrzutami ekranu niezbêdne wskazówki i wyjaœnienia, u³atwiaj¹ce samodzielne zbudowanie dynamicznej strony internetowej. Dziêki temu podrêcznikowi nauczysz siê wyszukiwaæ i usuwaæ b³êdy w skryptach PHP, tworzyæ formularze w jêzyku HTML oraz zapobiegaæ atakom na Twoje witryny. Poznasz tak¿e podstawowe i zaawansowane techniki tworzenia ró¿nych aplikacji (na przyk³ad stron wielojêzycznych lub obs³uguj¹cych fora dyskusyjne). • PHP i MySQL • Tworzenie formularza w jêzyku HTML • Tablice i ³añcuchy • Tworzenie i wywo³ywanie w³asnych funkcji • Wype³nianie baz danych • Zabezpieczenia • Stosowanie modyfikatorów • Szyfrowanie danych • Tworzenie uniwersalnych witryn • Budowanie strony domowej • Wielojêzyczna strona WWW • Tworzenie kont u¿ytkowników i nadawanie uprawnieñ Szybko i ³atwo naucz siê tworzyæ funkcjonalne oraz bezpieczne witryny internetowe
  • 2. Spis treści Wprowadzenie 9 Czym są dynamiczne strony WWW? ................................................................... 10 Co będzie Ci potrzebne? ....................................................................................... 16 O tej książce ........................................................................................................... 17 Rozdział 1. Wprowadzenie do PHP 19 Podstawy składni.................................................................................................... 20 Przesyłanie danych do przeglądarki internetowej ............................................... 24 Wstawianie komentarzy......................................................................................... 28 Co to są zmienne? .................................................................................................. 32 Łańcuchy ................................................................................................................ 36 Łączenie łańcuchów............................................................................................... 39 Spis treści Liczby ..................................................................................................................... 41 Stałe ........................................................................................................................ 45 Apostrof kontra cudzysłów .................................................................................... 48 Rozdział 2. Programowanie w PHP 51 Tworzenie formularza w języku HTML ............................................................... 52 Obsługa formularza HTML................................................................................... 56 Wyrażenia warunkowe i operatory ....................................................................... 60 Weryfikacja danych pochodzących z formularza ................................................. 64 Co to są tablice? ..................................................................................................... 70 Pętle for i while ...................................................................................................... 88 Rozdział 3. Tworzenie dynamicznych stron WWW 91 Wykorzystywanie plików zewnętrznych .............................................................. 92 Wyświetlanie i obsługa formularza przez jeden skrypt ....................................... 102 Tworzenie formularzy z pamięcią ....................................................................... 107 Tworzenie i wywoływanie własnych funkcji ...................................................... 110 Rozdział 4. Wprowadzenie do MySQL 125 Elementy bazy danych i ich nazwy..................................................................... 126 Wybór typu kolumny ........................................................................................... 128 Wybór innych właściwości kolumn .................................................................... 132 Korzystanie z serwera MySQL-a ........................................................................ 134 5
  • 3. Spis treści Rozdział 5. Wprowadzenie do SQL 141 Tworzenie baz danych i tabel.............................................................................. 142 Wprowadzanie rekordów..................................................................................... 145 Wybieranie danych .............................................................................................. 149 Wyrażenia warunkowe ........................................................................................ 151 Stosowanie LIKE i NOT LIKE .......................................................................... 154 Sortowanie wyników zapytania ........................................................................... 156 Ograniczanie wyników zapytania........................................................................ 158 Uaktualnianie danych .......................................................................................... 160 Usuwanie danych ................................................................................................. 162 Funkcje ................................................................................................................. 164 Rozdział 6. Zaawansowany SQL i MySQL 175 Projekt bazy danych............................................................................................. 176 Złączenia............................................................................................................... 191 Grupowanie wyników zapytania ......................................................................... 196 Indeksy ................................................................................................................. 198 Stosowanie różnych typów tabeli........................................................................ 203 Wyszukiwanie FULLTEXT ................................................................................ 206 Spis treści Wykonywanie transakcji...................................................................................... 212 Rozdział 7. Obsługa i usuwanie błędów 217 Ogólne typy błędów i ich usuwanie.................................................................... 218 Wyświetlanie błędów PHP.................................................................................. 224 Sterowanie raportowaniem błędów PHP ........................................................... 226 Tworzenie własnych funkcji obsługi błędów ..................................................... 229 Techniki usuwania błędów z PHP ...................................................................... 234 Techniki usuwania błędów 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 wyników zapytania ...................................................................... 257 Bezpieczeństwo zapytań...................................................................................... 261 Zliczanie zwróconych rekordów ......................................................................... 267 Uaktualnianie rekordów w PHP ......................................................................... 269 Rozdział 9. Tworzenie aplikacji internetowych 277 Przekazywanie wartości do skryptu..................................................................... 278 Stosowanie ukrytych pól formularza................................................................... 282 Edycja istniejących rekordów ............................................................................. 288 6
  • 4. Spis treści Stronicowanie wyników zapytań......................................................................... 295 Wyświetlanie tabel z możliwością sortowania.................................................... 303 Rozdział 10. Tworzenie aplikacji internetowych 309 Wysyłanie poczty elektronicznej ........................................................................ 310 Funkcje daty i czasu............................................................................................. 316 Obsługa przesyłania plików................................................................................. 320 Skrypty PHP i JavaScript .................................................................................... 333 Nagłówki HTTP ................................................................................................... 340 Rozdział 11. Sesje i „ciasteczka” 345 Strona logowania .................................................................................................. 346 Funkcje logowania ............................................................................................... 349 Posługiwanie się ciasteczkami............................................................................. 354 Sesje ...................................................................................................................... 367 Zwiększanie bezpieczeństwa sesji ...................................................................... 376 Rozdział 12. Zabezpieczenia 379 Zapobieganie spamowi ........................................................................................ 380 Spis treści Walidacja danych według typu ........................................................................... 387 Zapobieganie atakom XSS ................................................................................... 392 Zapobieganie wstrzykiwaniu poleceń SQL........................................................ 395 Szyfrowanie i bazy danych .................................................................................. 401 Rozdział 13. Wyrażenie regularne Perl 407 Skrypt testujący.................................................................................................... 408 Definiowanie prostych wzorców......................................................................... 412 Stosowanie kwantyfikatorów ............................................................................... 415 Klasy znaków ........................................................................................................ 418 Wyszukiwanie wszystkich dopasowań................................................................ 421 Stosowanie modyfikatorów.................................................................................. 425 Dopasowywanie i zastępowanie wzorców.......................................................... 427 Rozdział 14. Tworzenie uniwersalnych witryn 431 Zbiory znaków i kodowanie................................................................................. 432 Tworzenie wielojęzycznych stron WWW .......................................................... 434 Unicode w PHP ................................................................................................... 438 Uporządkowanie zbioru znaków w PHP ............................................................ 442 Transliteracja w PHP........................................................................................... 445 Języki i MySQL.................................................................................................... 448 Strefy czasowe i MySQL ..................................................................................... 452 Lokalizatory .......................................................................................................... 455 7
  • 5. Spis treści Rozdział 15. Forum dyskusyjne — przykład 459 Baza danych.......................................................................................................... 460 Szablony................................................................................................................ 469 Strona domowa..................................................................................................... 478 Strona forum......................................................................................................... 479 Strona wątku......................................................................................................... 484 Wstawianie wiadomości....................................................................................... 489 Rozdział 16. Rejestracja użytkowników — przykład 501 Tworzenie szablonu ............................................................................................. 502 Skrypty konfiguracyjne........................................................................................ 508 Tworzenie strony domowej ................................................................................. 516 Rejestracja ............................................................................................................ 518 Aktywacja konta ................................................................................................... 527 Logowanie i wylogowywanie się......................................................................... 531 Zarządzanie hasłami............................................................................................. 537 Rozdział 17. Sklep internetowy — przykład 547 Tworzenie bazy danych ....................................................................................... 548 Spis treści Część administracyjna aplikacji .......................................................................... 554 Tworzenie szablonu części publicznej aplikacji................................................. 571 Katalog produktów............................................................................................... 575 Koszyk................................................................................................................... 587 Rejestrowanie zamówień ..................................................................................... 597 Dodatek A Instalacja 605 Instalacja w systemie Windows .......................................................................... 606 Definiowanie uprawnień MySQL....................................................................... 609 Testowanie instalacji............................................................................................ 613 Konfigurowanie PHP........................................................................................... 616 Skorowidz 619 8
  • 6. Zaawansowany SQL i MySQL 6 Rozdział 6. Zaawansowany SQL i MySQL Rozdział ten zaczyna się w miejscu, w którym ostatni się kończył. Omówię w nim bardziej zaawansowane zagadnienia dotyczące SQL-a i MySQL-a. Poznałeś już podstawy obu tych technologii i z pewnością wystarczą Ci one do realizacji wielu projektów, ale dopiero ich bardziej wyszukane możliwości wyniosą Twe aplikacje internetowe na wyższy poziom. Zacznę od szczegółowego omówienia procesu projektowania bazy danych, opierając się na przykładzie systemu zarządzania forum. Doprowadzi nas to oczywiście do tematu złączeń, będących integralną częścią każdej relacyjnej bazy danych. Następnie będę opisywał kolejną kategorię funkcji wbudowanych MySQL-a używanych do grupowania wyników zapytań. Na zakończenie przejdę do bardziej zaawansowanych zagadnień. Powiem o indeksach, nauczę Cię zmieniać strukturę istniejących tabel oraz omówię typy tabel dostępne w MySQL-u. Rozdział zakończę omówieniem dwóch dodatkowych możliwości MySQL-a: przeszukiwania tekstów i transakcji. Zaawansowany SQL i MySQL 175
  • 7. Rozdział 6. Projekt bazy danych W moim przykładowym systemie będę chciał stworzyć forum, na którym użytkownicy mogą Pierwsze, co musisz zrobić, gdy pracujesz z systemem zamieszczać swoje opinie i odpowiadać innym zarządzania relacyjnymi bazami danych, takim jak internautom. Aby korzystać z forum, użytkownik MySQL, to utworzyć strukturę bazy (zwaną również będzie musiał się zarejestrować, a następnie schematem bazy danych). Projektowanie bazy danych uwierzytelnić za pomocą kombinacji nazwy i hasła. lub inaczej modelowanie danych to niezbędny etap Przewiduję również możliwość istnienia wielu gwarantujący długotrwałe i bezproblemowe zarządzanie forów poświęconych różnym tematom. W tabeli Twoimi informacjami. W procesie zwanym normalizacją 6.1 pokazałem, jak wygląda przykładowy rekord. eliminuje się niepotrzebne powtórzenia informacji Baza danych będzie nosić nazwę forum. i inne problemy, które zagrażają spójności danych. Wskazówki Dzięki technikom, które poznasz w tym rozdziale, Twoje bazy będą wydajne i niezawodne. Jeden Istnieje bardzo dobra metoda na określenie, z przykładów, które zaprezentuję — forum, na którym jakiego rodzaju informacje powinny się użytkownicy mogą wymieniać się opiniami — będzie znaleźć w bazie danych. Wystarczy, intensywnie wykorzystywany dopiero w rozdziale 15., że zastanowisz się, jakiego rodzaju pytania „Forum dyskusyjne — przykład”. Jednak omówione o dane będą zadawane przez użytkowników przeze mnie zasady normalizacji odnoszą się i jakie dane będą musiały się znaleźć do wszystkich aplikacji bazodanowych, jakie możesz w odpowiedziach. utworzyć. (Przykład bazy sitename używany Nauka normalizacji może sprawić Ci trudności, w poprzednich dwóch rozdziałach został poprawnie jeśli niepotrzebnie skoncentrujesz się na zaprojektowany również z punktu widzenia normalizacji, szczegółach. Każda z postaci normalnych jest ale zagadnienie to nie zostało jeszcze omówione.) zdefiniowana w dość skomplikowany sposób, a próba przełożenia tych definicji na język Projekt bazy danych Normalizacja niefachowy może być myląca. Dlatego radzę Proces normalizacji został wymyślony na początku lat Ci, abyś podczas lektury omówienia postaci siedemdziesiątych przez E.F. Codda, naukowca z firmy normalnych skoncentrował się na ogólnym IBM, który wymyślił też relacyjne bazy danych. Tego obrazie zmian zachodzących w schemacie rodzaju bazy to nic innego jak tylko zbiór danych bazy danych. Po zakończeniu normalizacji ułożonych w pewien określony sposób. Istnieje szereg i otrzymaniu końcowej postaci bazy danych tak zwanych postaci normalnych (NF, z ang. Normal cały proces powinien stać się dla Ciebie Form), które ułatwiają definiowanie struktury danych. wystarczająco zrozumiały. W tym rozdziale omówię pierwsze trzy z nich, Tabela 6.1. Przykładowy rekord pokazujący, jakiego ponieważ w większości przypadków są one w pełni rodzaju informacje chcę przechowywać w mojej wystarczające. bazie danych Zanim zaczniesz normalizować swoją bazę danych, Przykładowe dane forum musisz określić, jakie funkcje będzie pełniła Twoja Element Przykład aplikacja. Być może będziesz musiał w tym celu username janek porozmawiać z klientem lub samodzielnie zastanowić password haslo się nad tym zagadnieniem. W każdym razie struktura actual name Jan Kowalski bazy danych zależy od sposobu, w jaki aplikacja będzie user email jank@example.com odwoływała się do zgromadzonych w niej informacji. forum MySQL Na tym etapie będziesz więc potrzebował raczej kartki message subject Pytanie na temat normalizacji i ołówka niż MySQL-a. Oczywiście, w ten sposób message body Nie rozumiem jednej rzeczy. Dla drugiej projektuje się wszystkie relacyjne bazy danych, postaci normalnej (2NF) podano... nie tylko te działające w systemie MySQL. message date 2 lutego 2008 12:20 176
  • 8. Zaawansowany SQL i MySQL Klucze Baza danych forum składa 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 wspominałem już, że klucze są integralną częścią klucz główny (klucze obce pojawią się w następnych znormalizowanych baz danych. Spotkasz się krokach). z dwoma rodzajami kluczy, głównymi i obcymi. Klucz główny to unikatowy identyfikator, który Aby przypisać klucz główny: podlega pewnym ściśle określonym regułom. Musi on: 1. Poszukaj pól, które spełniają wszystkie trzy warunki określone dla kluczy głównych. Zawsze mieć jakąś wartość (inną niż NULL). W naszym przykładzie (tabela 6.1) żadna z kolumn Mieć stałą wartość (taką, która nigdy nie ulega nie spełnia kryteriów klucza głównego. Nazwa zmianie). użytkownika i adres e-mail są unikalne dla każdego Mieć inną wartość dla każdego rekordu użytkownika forum, ale nie dla każdego rekordu w tabeli. bazy danych (ten sam użytkownik może umieszczać wiele wiadomości na forum). Również ten sam Najlepszym, z życia wziętym przykładem klucza temat wiadomości może występować wiele razy. głównego jest numer ubezpieczenia społecznego Tekst wiadomości będzie prawdopodobnie zawsze przydzielany obywatelom USA. Każdy ma tam unikalny, ale może się zmieniać na skutek własny, niezmienny, unikatowy numer polisy. późniejszych poprawek, tym samym naruszając Ułatwia to identyfikowanie osób. Wkrótce jedno z kryteriów wyboru klucza głównego. przekonasz się, że wielokrotnie sam będziesz tworzył we wszystkich tabelach klucze główne. 2. Jeżeli nie istnieje żaden logiczny kandydat na klucz Jest to po prostu dobra praktyka projektowa. główny — wprowadź go! (tabela 6.2). Projekt bazy danych Drugi rodzaj kluczy stanowią klucze obce. Sytuacja, w której musisz sam utworzyć klucz Reprezentują one w tabeli B klucze główne główny, ponieważ żadne z istniejących pól nie tabeli A. Jeżeli masz na przykład bazę danych nadaje się do pełnienia tej roli, występuje dość filmy, w której występują tabele film i reżyser, często. W tym konkretnym przykładzie utworzę to klucz główny tabeli reżyser będzie pełnił pole message ID. rolę klucza obcego w tabeli film. Już niedługo zobaczysz, jak to wszystko działa w praktyce. Wskazówki Stosuję się do reguły, w myśl której w nazwach Tabela 6.2. Dodałem do tabeli klucz główny, dzięki czemu kluczy głównych powinna wystąpić przynajmniej będę mógł łatwo odwoływać się do rekordów część nazwy tabeli (np. message) i przyrostek id. Baza danych forum Niektórzy projektanci dodają również skrót pk (ang. primary key — klucz główny). Element Przykład message ID 1 MySQL zezwala na stosowanie w każdej tabeli username janek tylko jednego klucza głównego, choć możesz oprzeć password haslo go na kilku kolumnach (oznacza to, że kombinacja actual name Jan Kowalski tych kolumn musi być unikatowa). user email jank@example.com Najlepiej byłoby, gdyby Twój klucz główny forum MySQL był zawsze liczbą całkowitą, ponieważ pozwala message subject Pytanie na temat normalizacji to MySQL-owi osiągnąć najwyższą możliwą message body Nie rozumiem jednej rzeczy. Dla drugiej wydajność. postaci normalnej (2NF) podano... message date 2 lutego 2008 12:20 177
  • 9. Rozdział 6. Zależności Wskazówki Mówiąc o zależnościach w bazach danych mam Modelowanie baz danych rządzi się na myśli to, w jaki sposób dane z jednej tabeli są pewnymi regułami. Istnieje określona powiązane z danymi występującymi w drugiej. konwencja reprezentowania struktury Zależności między dwiema tabelami mogą bazy (zostanie ona tutaj zachowana). przybierać postać jeden do jednego, jeden do wielu Na rysunku 6.1 pokazałem symbole trzech lub wiele do wielu. (Dwie tabele tej samej bazy rodzajów zależności. danych mogą być również wcale niepowiązane). Proces projektowania bazy danych prowadzi O zależności „jeden do jednego” mówimy wtedy, do powstania diagramu zależności między gdy jeden i tylko jeden element tabeli A odnosi się encjami (ERD), na którym występują do jednego i tylko jednego elementu tabeli B prostokąty reprezentujące tabele oraz (np. każdy mieszkaniec USA ma tylko jeden numer symbole z rysunku 6.1. ubezpieczenia społecznego, a każdy numer polisy Istnieje wiele programów służących jest przyporządkowany tylko do jednego obywatela. do tworzenia schematów baz danych. Nikt nie może mieć dwóch polis, podobnie jak Jednym z nich jest MySQL Workbench żaden numer ubezpieczenia nie może odnosić się (www.mysql.com). do dwóch osób). Termin „relacyjny” w określeniu „system Zależność „jeden do wielu” występuje wtedy, zarządzania relacyjnymi bazami danych” gdy jakiś element tabeli A może odnosić się do kilku odnosi się do tabel, które nazywa się różnych elementów tabeli B. Na przykład, relacjami. określenia mężczyzna i kobieta mogą być używane w odniesieniu do wielu osób, ale każdy człowiek Projekt bazy danych może mieć tylko jedną płeć. Jest to najczęściej występująca zależność między tabelami w znormalizowanych bazach danych. Istnieje też zależność „wiele do wielu”, w której kilka elementów tabeli A może odnosić się do kilku elementów tabeli B. Na przykład rekord płyta może zawierać piosenki wykonywane przez różnych artystów, a każdy artysta może mieć na swoim koncie kilka płyt. W swoich projektach powinieneś unikać tego typu zależności, ponieważ prowadzą one do problemów ze spójnością danych i sprzyjają ich Rysunek 6.1. Pokazane tu symbole często spotyka powielaniu. Zamiast zależności „wiele do wielu” się na diagramach strukturalnych. Opisują one stworzysz tabelę pośrednią, dzięki której zależność zależności występujące między tabelami „wiele do wielu” zostanie rozbita na dwie zależności „jeden do wielu”. Temat zależności jest w pewien sposób związany z zagadnieniem kluczy, ponieważ klucze zdefiniowane w jednej tabeli odwołują się zazwyczaj do pól występujących w innych tabelach. 178
  • 10. Zaawansowany SQL i MySQL Pierwsza postać normalna Na przykład tabela zawierająca pole, w którym można umieścić kilka numerów telefonów (domowy, Jak już powiedziałem wcześniej, normalizacja komórkowy, 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 może się znaleźć więcej niż jedna wartość. Dostosowywanie to musi być precyzyjne Jeśli chodzi o drugi warunek, to tabela film i odbywać się w określonej kolejności. zawierająca kolumny aktor1, aktor2, aktor3 i tak Mówimy, że baza danych jest pierwszej postaci dalej, nie będzie w pierwszej postaci normalnej, normalnej (1NF), jeżeli: ponieważ powtarzające się kolumny zawierają ten sam rodzaj informacji. Każda kolumna zawiera tylko jedną wartość (czyli jest atomowa lub niepodzielna). Proces normalizacji rozpocznę od sprawdzenia, czy aktualna struktura bazy (tabela 6.2) jest zgodna Żadna tabela nie ma powtarzających się z 1NF. Kolumny, które nie są atomowe, zostaną kolumn dla danych pozostających w pewnej rozbite na wiele kolumn. Jeśli tabela posiada zależności. powtarzające się, podobne kolumny, to zostaną one przekształcone w osobną tabelę. Aby uczynić bazę zgodną z 1NF: 1. Zidentyfikuj pole, które może zawierać kilka informacji naraz. Gdy spojrzysz jeszcze raz na tabelę 6.2, zobaczysz, że jedno z pól nie jest zgodne Projekt bazy danych z 1NF: actual name. Zawiera ono zarówno imię jak i nazwisko użytkownika. Pole message date (data dodania do bazy) przechowuje, co prawda, dzień, miesiąc i rok, ale raczej nie będzie nas interesować taki poziom szczegółowości i potraktujemy Tabela 6.3. Tabela z atomowymi kolumnami przechowywaną przez nie wartość jako Baza danych forum niepodzielną. Zresztą pod koniec poprzedniego Element Przykład rozdziału pokazałem, że MySQL potrafi message ID 1 doskonale obsługiwać dane reprezentujące username janek daty i czas za pomocą typu DATETIME. password haslo Gdyby tabela zawierała na przykład jedną, first name Jan wspólną kolumnę dla imienia i nazwiska zamiast last name Kowalski dwóch osobnych albo przechowywała wiele user email jank@example.com numerów telefonów (stacjonarny, komórkowy, forum MySQL domowy, służbowy) w jednej kolumnie, message subject Pytanie na temat normalizacji to kolumny te również należałoby rozbić. message body Nie rozumiem jednej rzeczy. Dla drugiej postaci normalnej 2. Rozbij wszystkie pola odszukane w kroku 1. (2NF) podano... na kilka mniejszych, niepodzielnych pól message date 2 lutego 2008 12:20 (tabela 6.3). 179
  • 11. Rozdział 6. Aby poradzić sobie z tym problemem, utwórz Wskazówki osobne pola first name i last name, które będą Dostosowanie tabeli do 1NF wymaga zawierać tylko jedną wartość. analizy tabeli w poziomie. Wszystkie 3. Przekształć każdą grupę powtarzających się kolumny jednego rekordu przeglądamy kolumn w osobną tabelę. pod kątem występowania w nich danych, które nie są atomowe oraz występowania Problem ten nie występuje w bazie danych powtarzających się, podobnych danych. forum. Zademonstruję go zatem na przykładzie przedstawionym w tabeli 6.4. Powtarzające się Postacie normalne opisane są w różnych kolumny zawierające informacje o aktorach źródłach w różny sposób, często z użyciem powodują dwa problemy. Po pierwsze, bardziej technicznego żargonu. dla każdego filmu można podać tylko Najważniejszy jest jednak sens i końcowy ograniczoną liczbę aktorów. Nawet jeśli rezultat procesu normalizacji, a nie wprowadzimy kolumny aktor 1 aż do aktor 100, słownictwo zastosowane do jego opisu. to ograniczeniem będzie stu aktorów. Po drugie, każdy rekord, który nie zawiera maksymalnej Tabela 6.4. Tabela film nie jest zgodna z 1NF liczby aktorów, będzie mieć wartości NULL z dwóch powodów. Po pierwsze, zawiera w nadmiarowych kolumnach. W schemacie powtarzające się kolumny podobnych danych bazy danych powinniśmy unikać kolumn (aktor1 itd.). Po drugie, kolumny aktor i reżyser zawierających wartości NULL. Dodatkowym nie zawierają wartości atomowych problemem jest również to, że kolumny Tabela film zawierające informacje o reżyserze i aktorach Kolumna Wartość nie są atomowe. film ID 976 Projekt bazy danych Aby rozwiązać problemy występujące w tabeli tytuł filmu Casablanca film, utworzę dodatkową tabelę (tabela 6.5). rok produkcji 1943 Każdy jej rekord zawiera informacje o jednym reżyser Michael Curtiz autorze, co rozwiązuje problemy opisane aktor1 Humphrey Bogart powyżej. Także nazwiska i imiona aktorów są aktor2 Ingrid Bergman teraz przechowywane jako wartości atomowe. aktor3 Peter Lorre Zwróć również uwagę, że do nowej tabeli dodałem kolumnę indeksu głównego. Zasada, Tabela 6.5. Aby tabela film (tabela 6.4) była zgodna że każda tabela posiada klucz główny, wynika z 1NF, powiążę aktorów z filmami za pomocą tabeli wprost z pierwszej postaci normalnej. film-aktor 4. Upewnij się, że wszystkie nowe pola utworzone Tabela film-aktor w kroku 2. i 3. są zgodne z 1NF. ID Film Imię aktora Nazwisko aktora 1 Casablanca Humphrey Bogart 2 Casablanca Ingrid Bergman 3 Casablanca Peter Lorre 4 Sokół maltański Humphrey Bogart 5 Sokół maltański Peter Lorre 180
  • 12. Zaawansowany SQL i MySQL Druga postać normalna Każda baza, która ma spełniać drugą postać normalną (2NF), musi być najpierw zgodna z 1NF (proces normalizacji trzeba przeprowadzać we właściwej kolejności). Następnie wszystkie kolumny, które nie zawierają kluczy (kluczy obcych), muszą być powiązane zależnością z kluczem głównym. Kolumny, które naruszają ten warunek, Rysunek 6.2. Aby baza danych o filmach była zgodna łatwo zidentyfikować po tym, że zawierają wartości z 2NF, potrzebne są cztery tabele. Reżyserzy są niebędące kluczami i powtarzające się w różnych reprezentowani w tabeli film za pomocą klucza rekordach. Wartości te muszą zostać umieszczone reżyser ID; filmy są reprezentowane w tabeli film-aktor za pomocą klucza film ID; aktorzy są w osobnej tabeli i być powiązane z tabelą wyjściową reprezentowani w tabeli film-aktor za pomocą za pomocą klucza. klucza aktor ID Przykładem może być fikcyjna tabela film (tabela 6.4), która zawierałaby ponad dwadzieścia razy nazwisko Martina Scorsese jako reżysera różnych filmów. Sytuacja taka jest niezgodna z drugą postacią normalną, ponieważ kolumna zawierająca informację o reżyserze nie jest kluczem i nie jest powiązana zależnością z kluczem głównym (film ID). Rozwiązanie polega na utworzeniu osobnej tabeli reżyserzy wyposażonej we własny klucz główny, Projekt bazy danych który wystąpiłby jako klucz obcy w tabeli film, tworząc w ten sposób powiązanie obu tabel. Patrząc na tabelę 6.5, można dostrzec dwa kolejne naruszenia drugiej 2NF — ani tytuły filmów, ani nazwiska aktorów nie są powiązane z kluczem głównym tabeli. Zatem baza danych o filmach w najprostszej postaci wymaga czterech tabel (rysunek 6.2). W ten sposób informacje o każdym filmie, aktorze i reżyserze są przechowywane tylko jeden raz, a każda kolumna niebędąca kluczem jest zależna od klucza głównego danej tabeli. W zasadzie proces normalizacji można by określić jako tworzenie coraz większej liczby tabel, tak aby całkowicie wyeliminować możliwość powielenia jakichkolwiek danych. 181
  • 13. Rozdział 6. Aby uczynić bazę zgodną z 2NF: 1. Zidentyfikuj kolumny, które nie są kluczami i które nie są powiązane z kluczem głównym. Przyglądając się tabeli 6.3 zauważysz, że żadne z pól username, first name, last name, email i forum nie są kluczami (jedyną kolumną będącą kluczem jest na razie message ID) i żadne z nich nie jest powiązane zależnością z message ID. Natomiast message subject, body i date również Rysunek 6.3. Aby baza danych forum była zgodna nie są kluczami, ale ich wartości zależą od klucza z 2NF, potrzebne są trzy tabele message ID. 2. Utwórz odpowiednie tabele (patrz rysunek 6.3). Najlogiczniejsza modyfikacja istniejącej struktury polega na utworzeniu trzech tabel: users, forums i messages. Na diagramie bazy danych każda tabela została przeze mnie oznaczona prostokątem. Jej nazwa pełni rolę nagłówka, pod którym wymienione są wszystkie kolumny (atrybuty) tabeli. 3. Przypisz lub utwórz nowe klucze główne Projekt bazy danych (rysunek 6.4). Rysunek 6.4. Każda tabela powinna mieć własny Posługując się technikami opisanymi wcześniej klucz główny w tym rozdziale, upewnij się, że każda nowa tabela ma zdefiniowany klucz główny. W tabeli users stworzyłem 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 każdego rekordu i zawsze mieć wartość, to mógłbyś użyć ich jako kluczy głównych. Oznaczałoby to jednak, że wartości tych pól nie mogą się zmieniać (zgodnie z jednym z kryteriów wyboru klucza głównego). Użycie kluczy tekstowych zamiast numerycznych powodowałoby również nieco wolniejsze działanie bazy danych. 182
  • 14. Zaawansowany SQL i MySQL 4. Utwórz pomocnicze klucze obce, które połączą tabele zależnościami (rysunek 6.5). Ostatni krok na drodze do zgodności z 2NF polega na dodaniu kluczy obcych, które określą powiązania między tabelami. Pamiętaj, że to, co w jednej tabeli jest kluczem głównym, w drugiej najprawdopodobniej będzie kluczem obcym. W naszym przykładzie kolumna user ID z tabeli users łączy się z kolumną user ID z tabeli Rysunek 6.5. Aby zdefiniować zależność między messages. Dlatego też tabela users pozostaje tymi trzema tabelami, dodałem do tabeli messages w zależności „jeden do wielu” z tabelą messages dwa klucze obce, z których każdy łączy ją z jedną (każdy użytkownik może umieścić na forum z pozostałych dwóch tabel wiele wiadomości, ale każda wiadomość może mieć tylko jednego autora). Połączone zostały również dwie kolumny forum ID, tworząc w ten sposób zależność „jeden do wielu” pomiędzy tabelami messages i forums (każda wiadomość może należeć tylko do jednego forum, ale dane forum może zawierać wiele wiadomości). Projekt bazy danych Wskazówki Inny sposób sprawdzenia, czy tabele W prawidłowo znormalizowanej bazie danych spełniają drugą postać normalną, polega w jednej tabeli nie mają prawa pojawić się na przyjrzeniu się powiązaniom tabel. dwa takie same rekordy (dwa lub więcej Idealna sytuacja polega na występowaniu rekordów, w których wartości występujące samych zależności „jeden do wielu”. w poszczególnych kolumnach są identyczne). Tabele podlegające zależnościom „wiele Aby łatwiej przyswoić sobie proces normalizacji, do wielu” mogą wymagać restrukturyzacji. zapamiętaj, że pierwsza postać normalna Jeśli przyjrzymy się jeszcze raz rysunkowi wiąże się z analizą tabeli w poziomie, podczas 6.2, możemy zauważyć, że tabela film-aktor gdy druga postać normalna powstaje na skutek spełnia funkcję tabeli pośredniczącej. analizy w pionie (poszukiwania wartości Pozwala ona zamienić zależność „wiele powtarzających się w wielu rekordach). do wielu” zachodzącą pomiędzy filmami i aktorami na dwie zależności „jeden do wielu”. Tabele pośredniczące łatwo rozpoznać po tym, że wszystkie ich kolumny są kluczami obcymi. W tym przypadku kolumna odgrywająca rolę klucza głównego nie jest potrzebna, ponieważ kluczem głównym może być kombinacja obu kolumn tabeli. 183
  • 15. Rozdział 6. Trzecia postać normalna Aby uczynić bazę zgodną z 3NF: Mówimy, że baza danych spełnia trzecią postać 1. Zidentyfikuj wszystkie pola, które nie są normalną (3NF), jeżeli jest ona zgodna z 2NF, bezpośrednio powiązane z kluczem a każda kolumna, która nie jest kluczem, jest zależna głównym. od klucza głównego. Jeżeli prawidłowo przeszedłeś Jak już wspomniałem, na tym etapie przez pierwsze dwa etapy normalizacji, poszukujemy kolumn, które powiązane są prawdopodobnie dostosowanie bazy danych do 3NF między sobą zależnościami (tak jak miasto nie będzie już wymagać żadnych zmian. W moim i stan) zamiast z kluczem głównym. przykładzie (patrz rysunek 6.5) również nie ma W bazie danych forum nie występowały problemów, które należałoby rozwiązać, aby baza takie zależności. Przyjrzyjmy się tabeli była zgodna z trzecią postacią normalną. Dlatego messages. Każda wartość pola subject też przedstawię je omawiając hipotetyczną sytuację. jest specyficzna dla danego message ID, Weźmy na przykład pojedynczą tabelę każda wartość pola body jest specyficzna przechowującą informacje o zarejestrowanych dla wybranego message ID itd. klientach: imię, nazwisko, e-mail, numer telefonu, 2. Utwórz odpowiednie tabele. adres pocztowy itp. Tabela taka nie jest zgodna Jeśli w punkcie 1. udało się odnaleźć z 3NF, ponieważ wiele kolumn nie będzie zależnych problematyczne kolumny, takie jak od klucza głównego. Nazwa ulicy będzie zależeć na przykład miasto i stan, to tworzymy od miasta, a miasto od stanu. Również kod pocztowy dla nich osobne tabele cities i states. nie będzie zależeć od tego, jaką osobę opisuje 3. Przypisz lub utwórz nowe klucze główne. rekord. Aby znormalizować taką bazę danych, powinno się stworzyć osobną tabelę reprezentującą Każda tabela musi mieć klucz główny, wobec czego do nowych tabel dodaję Projekt bazy danych państwa, osobną reprezentującą miasta (połączoną kluczem obcym z tabelą państw) i jeszcze inną kolumny city ID i state ID. dla kodów. Wszystkie te tabele byłyby połączone 4. Utwórz pomocnicze klucze obce, definiując z tabelą opisującą klientów. tym samym zależności (rysunek 6.6). Jeśli takie rozwiązanie wydaje Ci się przesadą, Na zakończenie dodałem do tabeli Cities to masz rację. Wyższy stopień normalizacji często klucz obcy State ID oraz klucz obcy City ID nie jest konieczny. Chociaż powinno się dążyć do tabeli Clients. W efekcie uzyskałem połączenie rekordu klienta nie tylko do jak najpełniejszej normalizacji, to czasami warto z informacją o mieście, w którym jest ją poświęcić na rzecz prostoty. (patrz ramka zameldowany, ale również o stanie. „Rezygnacja z normalizacji”). W praktyce stopień normalizacji zależy od potrzeb konkretnej aplikacji i szczegółów bazy danych. Jak już wspomniałem, nasz przykład bazy forum nie wymaga dalszej normalizacji (jest już zgodny z 3NF) i dlatego proces dostosowywania do trzeciej postaci normalnej przedstawię właśnie na przykładzie omówionej wyżej bazy danych o klientach. Rysunek 6.6. Uproszczona wersja hipotetycznej bazy clients będzie zawierać dwie nowe tabele przechowujące informacje o miastach i stanach 184
  • 16. Zaawansowany SQL i MySQL Wskazówka W praktyce nie normalizowałbym tabeli Clients aż do takiego stopnia. Gdybym pozostawił pola opisujące miasto i stan w tabeli Clients, to najgorszą rzeczą, jaka mogłaby się zdarzyć, byłaby zmiana nazwy miasta i związana z tym konieczność aktualizacji rekordów wszystkich klientów będących jego mieszkańcami. W rzeczywistości jednak sytuacja taka zdarza się bardzo rzadko. Mimo istnienia zasad normalizacji baz danych dwóch różnych projektantów może dokonać normalizacji tej samej bazy w nieco inny sposób. Projektowanie baz danych pozostawia pewien margines dla indywidualnych preferencji Rezygnacja z normalizacji i interpretacji. Najważniejsze jest, Choć spełnienie trzeciej postaci normalnej by zaprojektowana baza danych nie naruszała jest korzystne, nie oznacza to jeszcze, postaci normalnej, gdyż prędzej czy później że masz normalizować każdą bazę danych, doprowadzi to do pojawienia się poważnych z którą pracujesz. Jednocześnie problemów. powinieneś uzmysłowić sobie, że odejście od sprawdzonych metod może mieć Projekt bazy danych w perspektywie dłuższego czasu katastrofalne skutki. Z normalizacji rezygnuje się zazwyczaj z dwóch powodów — ze względu na wydajność i dla wygody. Dużo łatwiej jest ogarnąć mniejszą liczbę tabel, a poza tym — łatwiej się nimi zarządza. Ze względu na liczbę powiązań między tabelami, uaktualnianie, odczytywanie i modyfikowanie danych w znormalizowanych bazach danych trwa z reguły dłużej. Krótko mówiąc, normalizacja jest poświęceniem prostoty i szybkości na rzecz spójności i skalowalności. Należy jednak pamiętać, że istnieje znacznie więcej sposobów na przyspieszenie bazy danych niż na odzyskanie informacji utraconych na skutek przechowywania ich w źle zaprojektowanej bazie. W miarę nabywania doświadczenia będziesz potrafił coraz lepiej modelować bazy danych, ale mimo wszystko staraj się trzymać po stronie normalizacji. 185
  • 17. Rozdział 6. Tworzenie bazy danych 2. Utwórz bazę danych forum (rysunek 6.7). Aby zakończyć projekt bazy danych, musimy CREATE DATABASE forum; wykonać trzy ostatnie kroki: USE forum; 1. Sprawdzić, czy w bazie znajdą się wszystkie Możliwe, że Twoja konfiguracja nie pozwala potrzebne informacje. na tworzenie nowych baz danych. W takiej sytuacji po prostu wykorzystaj jakąś już 2. Zidentyfikować typy kolumn. istniejącą bazę i dodawaj do niej kolejne 3. Nazwać wszystkie elementy bazy danych. tabele. Ostateczny projekt bazy danych został Tabela 6.6. Ostateczny projekt bazy forum przedstawiony w tabeli 6.6. W porównaniu wraz z typami kolumn do rysunku 6.5 została dodana jeszcze jedna forum kolumna. Ponieważ wiadomość umieszczana Nazwa kolumny Tabela Typ kolumny na forum może być odpowiedzią na inną wiadomość, musimy jakoś reprezentować tę zależność w bazie. forum_id forums TINYINT Rozwiązanie polega na dodaniu kolumny parent_id name forums VARCHAR(60) w tabeli messages. Jeśli wiadomość jest odpowiedzią, message_id messages INT to jej pole parent_id będzie zawierać wartość pola forum_id messages TINYINT message_id oryginalnej wiadomości (czyli message_id parent_id messages INT spełnia funkcję klucza obcego w tej samej tabeli). user_id messages MEDIUMINT Jeśli pole parent_id ma wartość równą 0, oznacza subject messages VARCHAR(100) to, że wiadomość stanowi początek nowego wątku, body messages LONGTEXT czyli nie jest odpowiedzią na żadną inną wiadomość. date_entered messages TIMESTAMP Projekt bazy danych user_id users MEDIUMINT Jeśli wprowadzasz jakiekolwiek zmiany w strukturze username users VARCHAR(30) tabel, powinieneś ponownie sprawdzić, czy spełniają pass users CHAR(40) one wszystkie postacie normalne, aby mieć pewność, first_name users VARCHAR(20) że baza danych jest nadal znormalizowana. last_name users VARCHAR(40) Zagadnienie nazw tabel i kolumn oraz wyboru typów email users VARCHAR(80) kolumn omówiłem już w rozdziale 4. Gdy schemat jest gotowy, możesz utworzyć odpowiadającą mu bazę danych MySQL-a za pomocą poleceń omówionych w rozdziale 5., „Wprowadzenie do SQL”. Aby utworzyć bazę danych: 1. Użyj wybranego klienta do dostępu do serwera Rysunek 6.7. Najpierw musisz utworzyć MySQL-a. i wybrać bazę danych Podobnie jak w poprzednim rozdziale, we wszystkich przykładach będziemy posługiwali się monitorem (klientem) mysqla. Oczywiście możesz też śmiało korzystać z phpMyAdmina i innych narzędzi. 186
  • 18. Zaawansowany SQL i MySQL 3. Utwórz tabelę forums (rysunek 6.8). Tabela ta zawiera tylko dwie kolumny CREATE TABLE forums ( (sytuacja taka ma często miejsce w przypadku forum_id TINYINT UNSIGNED znormalizowanych baz danych). Ponieważ nie NOT NULL AUTO_INCREMENT, spodziewam się, że tabela ta będzie zawierać name VARCHAR(60) NOT NULL, dużą liczbę rekordów, klucz główny otrzymał PRIMARY KEY (forum_id) ); typ TINYINT. Jeśli chcesz, by baza zawierała również opis każdego forum, możesz dodać Kolejność, w jakiej tworzysz tabele, do tej tabeli kolumnę typu VARCHAR(255). nie ma oczywiście znaczenia. Ja zacznę od forums. Pamiętaj, że zawsze możesz 4. Utwórz tabelę messages (rysunek 6.9). rozpisać polecenie SQL w kilku wierszach CREATE TABLE messages ( na ekranie, jeżeli tylko będzie Ci tak message_id INT UNSIGNED NOT NULL AUTO_INCREMENT, wygodniej. 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 główny musi być zdecydowanie bardziej pojemny, ponieważ Projekt bazy danych spodziewam się, że tabela ta będzie zawierać bardzo dużo rekordów. Trzy kolumny będące kluczami obcymi — forum_id, parent_id i user_id — będą mieć taki sam rozmiar i typ Rysunek 6.8. Utwórz pierwszą tabelę jak ich odpowiedniki będące kluczami głównymi w innych tabelach. Pole subject zostało ograniczone do 100 znaków, a pole body może zawierać znaczną ilość tekstu. Pole date_entered otrzymało typ TIMESTAMP. Będzie ono przechowywać datę i czas dodania rekordu. Jego wartość zostanie automatycznie zaktualizowana (bieżącą datą i czasem) w momencie wstawienia rekordu (właśnie w ten sposób zachowuje się typ TIMESTAMP). Rysunek 6.9. Utwórz drugą tabelę 187
  • 19. Rozdział 6. 5. Utwórz tabelę users (rysunek 6.10). 6. Jeśli chcesz, możesz upewnić się, że baza CREATE TABLE users ( danych ma taką strukturę jak powinna user_id MEDIUMINT UNSIGNED (rysunek 6.11). NOT NULL AUTO_INCREMENT, SHOW TABLES; username VARCHAR(30) NOT NULL, SHOW COLUMNS FROM forums; pass CHAR(40) NOT NULL, SHOW COLUMNS FROM messages; first_name VARCHAR(20) NOT NULL, SHOW COLUMNS FROM users; last_name VARCHAR(40) NOT NULL, email VARCHAR(80) NOT NULL, Ten krok jest opcjonalny, ponieważ MySQL PRIMARY KEY (user_id) ); i tak wyświetla informacje o pomyślnym wykonaniu każdego wprowadzanego Większość kolumn tej tabeli wykorzystuje polecenia. Warto jednak przypomnieć definicje znane z tabeli users bazy sitename sobie strukturę bazy danych. używanej w poprzednich dwóch rozdziałach. Kolumna pass jest typu CHAR(40), ponieważ Wskazówka dla haseł będę stosować funkcję SHA1(), która W przypadku połączenia klucz zwraca zawsze łańcuch o długości 40 znaków główny-klucz obcy (na przykład forum_id (patrz rozdział 5.). tabeli forum z forum_id tabeli messages), obie kolumny muszą być tego samego typu (w naszym przykładzie: TINYINT UNSIGNED NOT NULL). Projekt bazy danych Rysunek 6.10. Trzecia i ostatnia tabela w bazie Rysunek 6.11. Sprawdź strukturę bazy za pomocą polecenia SHOW 188
  • 20. Zaawansowany SQL i MySQL Wypełnianie bazy danych Aby zapełnić bazę danymi: W rozdziale 15. napiszemy w PHP interfejs 1. Dodaj kilka nowych rekordów do tabeli forums WWW dla bazy forums. Będzie on dostarczać (rysunek 6.12). standardowego sposobu wypełniania bazy INSERT INTO forums (name) VALUES ('MySQL'), danymi (poprzez rejestrowanie się ('PHP'), ('Programowanie'), ('HTML'), użytkowników i umieszczanie wiadomości ('CSS'), ('Bazy danych'); na forum). Zanim jednak dojdziemy do tego Ponieważ tablica messages jest zależna od punktu, musisz się jeszcze sporo nauczyć. wartości odczytywanych z tabel forums i users, Dlatego na razie wypełnimy bazę danymi wypełnię najpierw te ostatnie. W przypadku za pomocą klienta mysqla. Możesz wykonać powyższego polecenia INSERT wystarczy jedynie po kolei poniższe kroki lub skorzystać podać wartość kolumny name (MySQL z gotowych poleceń SQL-a dołączonych do automatycznie nada wartość kolumnie forum_id). przykładów zamieszczonych na serwerze ftp. 2. Dodaj nowe rekordy do tabeli users (rysunek 6.13). 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'), 'Małgorzata', 'Malinowska', 'mm@example.com'); Rysunek 6.12. Dodawanie rekordów do tabeli forums Projekt bazy danych Jeśli masz wątpliwości co do składni polecenia INSERT lub zastosowania funkcji SHA1(), skorzystaj z informacji podanych w rozdziale 5. Rysunek 6.13. Dodawanie rekordów do tabeli users 189
  • 21. Rozdział 6. 3. Wstaw nowe rekordy do tabeli messages Sprawę dodatkowo komplikuje kolumna (patrz rysunek 6.14). parent_id. Musi ona zawierać wartość SELECT * FROM forums; message_id tej wiadomości, na którą SELECT user_id, username FROM users; odpowiedź stanowi nowa wiadomość. INSERT INTO messages (forum_id, Druga wiadomość umieszczona w bazie parent_id, user_id, subject, body) danych będzie mieć message_id równy VALUES (1, 0, 1, 'Pytanie na temat normalizacji', 2 i wobec tego każda wiadomość stanowiąca 'Nie rozumiem jednej rzeczy. Dla drugiej odpowiedź na tę wiadomość będzie musiała postaci normalnej (2NF) podano...'), mieć wartość parent_id równą 2. (1, 0, 2, 'Projekt bazy danych', 'Projektuję nową bazę danych i natrafiłem na pewien W tworzonych przez Ciebie skryptach problem. Ile tabel powinna mieć moja PHP, wszystko to będzie wyglądało baza?...'), (1, 2, 1, 'Projekt bazy danych', 'Liczba znacznie prościej. Muszę teraz jednak tabel w Twojej bazie danych...'), wyłożyć Ci całą teorię, posługując się (1, 3, 2, 'Projekt bazy danych', 'OK, terminologią języka SQL. dziękuję!'), (2, 0, 3, 'Błędy PHP', 'Próbuję uruchomić Zwróć również uwagę, że nie wprowadziłem skrypty z rozdziału 3. i pierwszy skrypt wartości dla pola date_entered. MySQL kalkulatora nie działa. Gdy akceptuję automatycznie umieści w nim bieżącą formularz...'); datę i czas, ponieważ jest to kolumna Ponieważ dwa pola tabeli messages (forum_id typu TIMESTAMP. oraz user _id) odwołują się do wartości 4. Powtórz kroki od 1. do 3., aby zapełnić przechowywanych w innych tabelach, bazę danymi. przed wstawieniem nowych rekordów Projekt bazy danych dokonam wyboru tych wartości. Na przykład, We wszystkich kolejnych przykładach gdy użytkownik janek utworzy nową wiadomość w tym rozdziale będę wykorzystywał bazę, na forum MySQL-a, musisz użyć forum_id którą właśnie zapełniłem. Jeśli chcesz, równy 1 i user_id równy 1. możesz wykonać u siebie te same polecenia INSERT co ja lub utworzyć swoje własne. Rysunek 6.14. W przypadku znormalizowanych baz danych bardzo często spotkasz się z sytuacją, w której, aby wstawić jakiś rekord do tabeli, będziesz musiał znać wartości przechowywane w innych tabelach 190
  • 22. Zaawansowany SQL i MySQL SELECT * FROM messages Złączenia INNER JOIN forums ON messages.forum_id = Ponieważ relacyjne bazy danych mają złożoną forums.forum_id strukturę, aby wydobyć te informacje, które WHERE forums.name = 'MySQL' najbardziej nas interesują, musimy czasem Złączenie to wybiera wszystkie kolumny obu tabel, wykonać jakieś niestandardowe zapytanie. jeśli spełnione są dwa warunki. Po pierwsze, Na przykład, jeśli chcesz dowiedzieć się, jakie kolumna forums.name musi zawierać wartość wiadomości zawiera forum MySQL-a, musisz najpierw dowiedzieć się, jaka jest wartość MySQL (której odpowiada wartość forum_id forum_id dla tego forum, a następnie użyć równa 1). Po drugie, wartość forum_id w tabeli forums musi odpowiadać wartości forum_id jej do pobrania wszystkich rekordów tabeli message, które mają taką wartość forum_id. w tabeli messages. Ze względu na sprawdzenie Jak z tego wynika, to proste zadanie wymaga równości dotyczące pól w różnych tabelach wykonania dwóch zapytań. Jednak stosując (messages.forum_id = forums.forum_id) złączenie złączenie, możesz poradzić sobie z nim takie nazywa się równościowym. w jednym kroku. Złączenia wewnętrzne możesz również zapisywać Złączenie jest zapytaniem SQL-a używającym bez stosowania klauzuli INNER JOIN: dwóch lub więcej tabel i tworzącym wirtualną SELECT * FROM messages, forums WHERE tabelę wyników. W specyfikacji SQL-a messages.forum_id = forums.forum_id AND forums.name = 'mySQL' występują dwa główne typy złączeń: wewnętrzne i zewnętrzne (oba mają szereg Jeżeli wybierasz dane z wielu tabel i kolumn, podtypów). a w kilku tabelach występują kolumny o takiej samej nazwie, musisz zastosować notację z kropką Złączenie wewnętrzne zwraca wszystkie (tabela.kolumna). W przypadku relacyjnych baz rekordy podanych tabel, dla których zachodzi danych robi się to praktycznie zawsze, ponieważ dopasowanie. Na przykład, aby uzyskać Złączenia klucz główny jednej tabeli ma taką samą nazwę wszystkie wiadomości zamieszczone jak obcy klucz drugiej. Jeżeli nie wskażesz na forum MySQL, powinieneś użyć jednoznacznie kolumny, do której się odwołujesz, następującego złączenia wewnętrznego zobaczysz komunikat o błędzie (rysunek 6.16). (rysunek 6.15): Rysunek 6.15. To złączenie zwraca kolumny obu tabel dla rekordów, dla których wartości forum_id są równe MySQL (1) Rysunek 6.16. Ogólne odwołanie do kolumny występującej w kilku tabelach spowoduje wystąpienie błędu niejednoznaczności 191
  • 23. Rozdział 6. Złączenia zewnętrzne różnią się od złączeń Jeżeli w warunku porównania złączenia wewnętrznych tym, że potrafią zwracać rekordy, zewnętrznego bądź wewnętrznego występuje które nie spełniają wyrażenia warunkowego. kolumna o takiej samej nazwie w obu tabelach, Istnieją trzy podtypy złączeń zewnętrznych: left możesz uprościć zapis zapytania, stosując (lewe), right (prawe) i full (pełne). Przykładem klauzulę USING: pierwszego podtypu jest następujące złączenie: SELECT * FROM messages SELECT * FROM forums INNER JOIN forums LEFT JOIN messages ON USING (forum_id) forums.forum_id = messages.forum_id; WHERE forums.name = 'mySQL' SELECT * FROM forums Najważniejsze przy tego rodzaju złączeniach LEFT JOIN messages jest to, które tabele należy wymienić jako pierwsze. USING (forum_id) W powyższym przykładzie w przypadku udanego Zanim przejdę do przykładów, jeszcze dwie dopasowania zwrócone zostaną wszystkie rekordy uwagi. Po pierwsze, ponieważ składnia tabeli forums wraz ze wszystkimi informacjami wymagana przy tworzeniu złączeń jest dość z tabeli messages. Jeśli dla danego rekordu tabeli skomplikowana, przy ich pisaniu przydają się forums nie można dopasować informacji w tabeli aliasy omówione w rozdziale 5. Po drugie, messages, to zamiast nich zostaną zwrócone ponieważ złączenia często zwracają dużo wartości NULL (rysunek 6.17). danych, to najlepiej zawsze określić, które kolumny nas interesują, zamiast wybierać wszystkie. Złączenia Rysunek 6.17. To złączenie zewnętrzne zwraca więcej rekordów niż złączenie wewnętrzne, ponieważ zwraca wszystkie wiersze pierwszej tabeli. Zapytanie to zwraca również nazwy wszystkich forów, nawet jeśli nie zawierają one jeszcze żadnej wiadomości 192
  • 24. Zaawansowany SQL i MySQL Aby wykorzystać złączenia: 2. Pobierz temat i datę wprowadzenia każdej wiadomości wysłanej przez użytkownika janek 1. Pobierz nazwę forum i temat wiadomości (rysunek 6.19). dla każdego rekordu tabeli messages (patrz rysunek 6.18). SELECT m.subject, DATE_FORMAT(m.date_entered, SELECT f.name, m.subject '%M %D, %Y') AS Date FROM forums FROM users AS u INNER JOIN AS f INNER JOIN messages AS m messages AS m USING (forum_id) ORDER BY f.name; USING (user_id) WHERE u.username = 'janek'; Zapytanie to zawiera złączenie wewnętrzne, które spowoduje w efekcie zastąpienie Również to złączenie używa dwóch tabel, wartości forum_id z tabeli messages users i messages. Złączenie obu tabel odbywa odpowiadającą jej wartością name z tabeli się za pomocą kolumny user_id i dlatego forums dla każdego rekordu tabeli messages. została ona umieszczona wewnątrz klauzuli W wyniku otrzymasz zatem temat każdej USING. Wyrażenie warunkowe WHERE pozwala wiadomości wraz z nazwą forum, do którego zidentyfikować interesującego nas użytkownika, należy ta wiadomość. a funkcja DATE_FORMAT sformatować wartość pola date_entered. Zwróć uwagę, że w połączeniach nadal możesz używać klauzul ORDER BY. Złączenia Rysunek 6.18. Podstawowe złączenie wewnętrzne Rysunek 6.19. Nieco bardziej skomplikowana wersja zwraca w tym przykładzie tylko dwie kolumny złączenia wewnętrznego tabele users i messages 193
  • 25. Rozdział 6. 3. Pobierz identyfikator wiadomości, temat oraz 4. Dla każdego użytkownika pobierz nazwę nazwę forum dla każdej wiadomości, której użytkownika, temat wiadomości i nazwę autorem jest użytkownik janek (patrz forum (patrz rysunek 6.21). rysunek 6.20). SELECT u.username, m.subject, SELECT m.message_id, m.subject, f.name FROM users AS u LEFT JOIN f.name FROM users AS u messages AS m USING (user_id) INNER JOIN LEFT JOIN forums AS f messages AS m USING (user_id) USING (forum_id); INNER JOIN forums AS f USING (forum_id) Gdybyś zastosował podobne złączenie WHERE u.username = 'janek'; wewnętrzne, to użytkownicy, którzy nie są jeszcze autorami żadnej wiadomości, Powyższe złączenie jest podobne nie zostaliby uwzględnieni (patrz rysunek do zastosowanego w punkcie 2., ale idzie o krok 6.22). Zatem jeśli interesują Cię wszyscy dalej, dołączając trzecią tabelę. Zwróć szczególną użytkownicy, powinieneś użyć złączenia uwagę na sposób konstrukcji złączenia zewnętrznego. Zwróć uwagę, że tabela, wewnętrznego trzech tabel oraz zastosowanie która ma być uwzględniona w całości aliasów w celu łatwiejszego odwoływania się (users w tym przypadku), musi być podana do tabel i ich kolumn. jako pierwsza tabela złączenia typu left. Złączenia Rysunek 6.20. Złączenie wewnętrzne wszystkich trzech Rysunek 6.21. To złączenie zewnętrzne zwraca tabel bazy dla każdego użytkownika temat każdej wiadomości i nazwę każdego forum. Jeśli użytkownik nie umieścił jeszcze żadnej wiadomości na forum (tak jak tomekj widoczny na dole rysunku), to temat wiadomości i nazwa forum będą mieć dla niego wartości NULL 194
  • 26. Zaawansowany SQL i MySQL Wskazówki Złączenia, które nie zawierają klauzuli WHERE (np. SELECT * FROM urls, url_associations), Możesz nawet złączyć tabelę z nią samą. nazywamy złączeniami pełnymi. Zwracają one Złączenia można tworzyć z wykorzystaniem rekordy z obu tabel. W przypadku dużych tabel wyrażeń warunkowych odwołujących się ilość zwracanych danych może stanowić pewien do dowolnych kolumn. Nie muszą one problem. pełnić roli kluczy, choć sytuacja taka jest Nigdy nie zostanie zwrócona wartość NULL najczęstsza. występująca w kolumnie, do której odwołujemy Stosując składnię bazadanych.tabela. się w złączeniu. To dlatego, że nie jest ona równa kolumna, możesz wykonywać złączenia żadnej innej wartości, w tym także innym tabeli należących do różnych baz danych, wartościom NULL. o ile tylko wszystkie znajdują się na tym samym serwerze. Ta metoda nie zadziała, jeżeli bazy komunikują się ze sobą za pośrednictwem sieci. Złączenia Rysunek 6.22. To złączenie wewnętrzne nie zwróci użytkownika, który nie umieścił jeszcze żadnej wiadomości na forum (tak jak tomekj widoczny na dole rysunku 6.21) 195