Aliasy, tworzenie relacji

MySQL jest relacyjnÄ… bazÄ… danych. Niestety wielu (zwÅ‚aszcza poczÄ…tkujÄ…cych) jej użytkowników zupeÅ‚nie nie rozumie tego terminu. SpróbujÄ™ wytÅ‚umaczyć go na przykÅ‚adzie. ZaÅ‚óżmy, że katalogujesz dane o rozmaitych albumach muzycznych. Utworzysz dla nich tabelkÄ™ albumy, w której chcesz zawrzeć tytuÅ‚ albumu, wykonawcÄ™, rok wydania oraz jego zawartość. Tu pojawia siÄ™ jednak poważny problem - stwierdzenie, iż wszystkie albumy zawierajÄ… tÄ™ samÄ… ilość utworów, jest absurdem. Jak zatem odwzorować ich listÄ™ w tabeli? Cóż... można utworzyć 10 pól, a gdyby utworów byÅ‚o wiÄ™cej - dla jednego albumu tworzyÅ‚oby siÄ™ dwa rekordy. Kolejny problem - gdy albumów bÄ™dzie nie 10, nie 20, a np. 17? Część miejsca zmarnuje siÄ™. Podobna sytuacja wystÄ…pi, gdyby album byÅ‚ tworzony przez kilku wykonawców.

Na szczęście MySQL umożliwia proste tworzenie relacji - nic nie stoi na przeszkodzie, byÅ› utworzyÅ‚ osobnÄ… tabelkÄ™ dla utworów, do której dodasz pole przechowujÄ…ce ID albumu, do którego tenże przynależy. Ba - możesz posunąć siÄ™ jeszcze dalej - utworzyć dwie tabelki: jednÄ… z nazwÄ… utworu, a drugÄ… łączÄ…cÄ… utwór z jakimÅ› albumem - wtedy bÄ™dziesz w stanie obsÅ‚użyć sytuacjÄ™, gdy jeden utwór znajdzie siÄ™ na kilku albumach. Samo tworzenie tabelek to nie wszystko (wszak takie coÅ› to da radÄ™ także na murze kredÄ… napisać :)). MySQL daje nam bowiem możliwość operowania na wielu tabelach w jednym zapytaniu! I to jest wÅ‚aÅ›nie relacja. Bez wzglÄ™du na to, w ilu tabelach przechowujesz dane - w prawie każdej sytuacji bÄ™dziesz w stanie je pobrać jednym zapytaniem.

ZostaÅ„my przy naszej bazie albumów. Na niej chciaÅ‚bym zademonstrować dziaÅ‚anie relacji w praktyce. Na poczÄ…tek przygotujmy tabelki i wrzućmy do nich jakieÅ› dane:

CREATE TABLE `albumy` (
   `id` int(8) NOT NULL AUTO_INCREMENT,
   `tytul` varchar(64) NOT NULL DEFAULT '',
   `wykonawca` varchar(32) NOT NULL DEFAULT '',
   `rok_wydania` int(6) NOT NULL DEFAULT '0',
   PRIMARY KEY (`id`)
);
 
INSERT INTO `albumy` VALUES (1, 'Nightflight to Venus', 'Boney M', 1978);
INSERT INTO `albumy` VALUES (2, 'Love for sale', 'Boney M', 1977);
INSERT INTO `albumy` VALUES (3, 'Spirits Having Flown', 'Bee Gees', 1979);
 
CREATE TABLE `utwory` (
   `id` int(8) NOT NULL AUTO_INCREMENT,
   `tytul` varchar(64) NOT NULL DEFAULT '',
   `wykonawca` varchar(32) NOT NULL DEFAULT '',
   `rok_wydania` int(6) NOT NULL DEFAULT '0',
   PRIMARY KEY (`id`)
);
 
INSERT INTO `utwory` VALUES (1, 'Rasputin', 'Boney M', 1978);
INSERT INTO `utwory` VALUES (2, 'Nightflight to Venus', 'Boney M', 1978);
INSERT INTO `utwory` VALUES (3, 'Daddy Cool', 'Boney M', 1976);
INSERT INTO `utwory` VALUES (4, 'Tragedy', 'Bee Gees', 1979);
INSERT INTO `utwory` VALUES (5, 'Too much heaven', 'Bee Gees', 1979);
 
CREATE TABLE `album_utwor` (
   `album_id` int(8) NOT NULL DEFAULT '0',
   `utwor_id` int(8) NOT NULL DEFAULT '0',
   KEY `album_id` (`album_id`,`utwor_id`)
) TYPE=MyISAM;
 
INSERT INTO `album_utwor` VALUES (1, 1);
INSERT INTO `album_utwor` VALUES (1, 2);
INSERT INTO `album_utwor` VALUES (2, 3);
INSERT INTO `album_utwor` VALUES (3, 4);
INSERT INTO `album_utwor` VALUES (3, 5);
# Male info dla fanow Bee Gees'ow - gdyby byl jakis blad
# w dacie wydania albumu/utworow, prosze mnie zawiadomic; 

A więc mamy strukturę tabelek będącą odpowiednikiem tego, co pisałem powyżej. Aby dodatkowo nie gmatwać wszystkiego, uprościłem gromadzenie danych o wykonawcy.

Spróbujmy teraz pobrać jakieÅ› dane. ZaÅ‚óżmy, że chcemy sprawdzić, w jakim albumie ukazaÅ‚ siÄ™ utwór Rasputin. Możemy zrealizować to takim zapytaniem:

SELECT a.tytul, a.wykonawca FROM albumy a, utwory u, album_utwor au WHERE a.id = au.album_id AND au.utwor_id = u.id AND u.tytul = 'Rasputin';

Wynik:

TYTUL                  WYKONAWCA
Nightflight to Venus   Boney M

W zapytaniu pojawiÅ‚o nam siÄ™ sporo nowych elementów. Najbardziej rzuca siÄ™ w oczy rozbudowanie klazuli FROM, wiÄ™c to od niej zaczniemy. WymieniÅ‚em tam listÄ™ tabel, którymi bÄ™dÄ™ siÄ™ posiÅ‚kować w moich zmaganiach. Ale - po nazwie każdej w tabel podaÅ‚em alias, czyli krótki identyfikator, którego użyjÄ™ dalej do okreÅ›lania, że to wÅ‚aÅ›nie o tÄ™, a nie o innÄ… tabelkÄ™ mi chodzi. W spisie danych do pobrania zaznaczyÅ‚em przy polu, że dane majÄ… być pobrane z tabeli albumy, nie z utwory (tam bowiem wystÄ™pujÄ… takie same pola). Najpierw podaÅ‚em nazwÄ™ tabelki, z tym że pod postaciÄ… aliasu, po czym oddzieliÅ‚em jÄ… kropkÄ… od nazwy pola.

OK, baza wie, co ma pobrać i skÄ…d. Jednak aby wiedziaÅ‚a, JAKIE sÄ… zależnoÅ›ci miÄ™dzy poszczególnymi tabelami, potrzebna jest nam klazula WHERE. Ta także ulegÅ‚a rozbudowaniu. Zobacz, jak połączone sÄ… tabele. Przy pomocy zwykÅ‚ego operatora porównania = okreÅ›liÅ‚em, iż w zbiorze wyników znajdÄ… siÄ™ rekordy albumu skojarzonego poprzez tabelÄ™ album_utwor (a.id = au.album_id AND au.utwor_id = u.id) z piosenkÄ… o tytule Rasputin.

Teraz coÅ› trudniejszego - pragniemy pobrać tytuÅ‚y wszystkich piosenek wraz z nazwami albumów, w jakich siÄ™ ukazaÅ‚y, posortowane wedÅ‚ug daty ich premiery. Tabele albumy oraz utwory zostanÄ… skojarzone w taki sam sposób, jak w poprzednim przykÅ‚adzie.

SELECT u.tytul, u.wykonawca, a.tytul AS `album_tytul` FROM albumy a, utwory u, album_utwor au WHERE a.id = au.album_id AND au.utwor_id = u.id ORDER BY u.rok_wydania

Wykonaj to zapytanie i zobacz, że to dziaÅ‚a! PobraliÅ›my naraz dane z dwóch tabel. Zwróć uwagÄ™ na interesujÄ…ce AS wystÄ™pujÄ…ce w spisie danych do pobrania - dziÄ™ki niemu okreÅ›liÅ‚em, że w zbiorze wyników dane o albumie, z którego pochodzi utwór, bÄ™dÄ… widoczne pod tytuÅ‚em album_tytul.

Mam nadziejÄ™, iż przekonaÅ‚em CiÄ™ o potÄ™dze relacji oraz o możliwoÅ›ciach, jakie one stwarzajÄ…. Przy ich pomocy znaczÄ…co zmniejszysz liczbÄ™ zapytaÅ„ w twoich skryptach. Jako ciekawostkÄ™ podam, iż relacje można stosować NIE TYLKO w klauzulach SELECT! Oto przykÅ‚ady wprost z moich wÅ‚asnych zasobów :)

UPDATE users, sessions SET user_lastvisit = sessions.session_time WHERE sessions.session_time < (UNIX_TIMESTAMP() - 3600);
DELETE sessions FROM users, sessions WHERE users.user_id = sessions.session_user_id;

Do góry

Waszym zdaniem:

Uwaga: To jest jedynie część artykułu. Komentarze dotyczą całości tekstu.

Nikt jeszcze nie dodał swojego komentarza. Możesz być pierwszy!


Twoim zdaniem:

Reklama

banner

Partnerzy

CityDesign.pl
phpSolutions