Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Bazy Danych W04: JOIN (złączenia) Wojciech St. Mościbrodzki

Podobne prezentacje


Prezentacja na temat: "Bazy Danych W04: JOIN (złączenia) Wojciech St. Mościbrodzki"— Zapis prezentacji:

1 Bazy Danych W04: JOIN (złączenia) Wojciech St. Mościbrodzki wojmos@wojmos.com

2 JOIN – w pytaniach i odpowiedziach  Do czego służą operacje typu JOIN  Do umożliwienia wykonywania operacji (np. SELECT) na danych przechowywanych w wielu tabelach  Na jakich obiektach przeprowadza się JOIN  Operacje JOIN są wykonywane na dwóch (lub więcej) tablicach (zwykle – pozostających w pewnej relacji)  Jak wykonywane są "długie" operacje JOIN  Każdą wielotablicową operację JOIN można rozpatrywać jako łańcuch "binarnych" (dwutablicowych) JOINów.

3 Dane przykładowe do operacji JOIN  Rozpatrzmy dwa zbiory danych: encje STUDENT i JĘZYK create table pracownik ( id int auto_increment primary key, imie char(10), nazwisko char(30), placa int ); create table jezyk ( id int auto_increment primary key, nazwa char(15) ); insert into pracownik values (1,'Jan','Nowak',3400); insert into pracownik values (2,'Ewa','Malina',2100); insert into pracownik values (3,'Iza','Trus',4000); insert into jezyk values (11,'polski'); insert into jezyk values (12,'angielski'); insert into jezyk values (13,'niemiecki'); (w tej chwili nie ma pomiędzy naszymi encjami relacji)

4 Iloczyn kartezjański  Iloczyn kartezjański  Wersja algebry relacji: Iloczynem kartezjańskim zbiorów A i B nazywamy zbiór wszystkich par (a,b), takich, że a  A b  B  Wersja bazodanowa: iloczyn kartezjański dwóch encji A i B to zbiór wszystkich par (a,b), takich, że a jest elementem encji A, zaś b jest elementem encji B  Iloczyn kartezjański zawiera KAŻDĄ możliwą parę (zbiór wszystkich par) mysql> select * from pracownik, jezyk; +----+------+----------+-------+----+-----------+ | id | imie | nazwisko | placa | id | nazwa | +----+------+----------+-------+----+-----------+ | 1 | Jan | Nowak | 3400 | 11 | polski | | 2 | Ewa | Malina | 2100 | 11 | polski | | 3 | Iza | Trus | 4000 | 11 | polski | | 1 | Jan | Nowak | 3400 | 12 | angielski | | 2 | Ewa | Malina | 2100 | 12 | angielski | | 3 | Iza | Trus | 4000 | 12 | angielski | | 1 | Jan | Nowak | 3400 | 13 | niemiecki | | 2 | Ewa | Malina | 2100 | 13 | niemiecki | | 3 | Iza | Trus | 4000 | 13 | niemiecki | +----+------+----------+-------+----+-----------+

5 Iloczyn kartezjański a relacja  Relację tworzą tylko te pary, które mają określoną właściwość (spełniają określony warunek).  Innymi słowy: relacja to jeden z podzbiorów iloczynu kartezjańskiego  Istnieje DUŻO możliwych relacji na dwóch encjach 1 2 3 11 12 13 Relacja A (1-do-1): jaki język obowiązuje w kraju zamieszkania pracownika 1 2 3 11 12 13 Relacja B (1-do-  ): jakie są języki ojczyste pracowników 1 2 3 11 12 13 Relacja D (  -do-  ): jakimi językami mówią pracownicy 1 2 3 11 12 13 Relacja C (1-do-1): jakiego języka uczą się pracownicy

6 Relacje zaimplementowane w bazie danych  Implementacja relacji wymaga dodania kolumny ( zakładamy relację 1-do-  ) alter table pracownik add column id_jez int;  Oczywiście istnieje wiele możliwych relacji 1-do-  na tych encjach: 1 2 3 11 12 13 Relacja A (1-do-  ): jakie są języki ojczyste pracowników 1 2 3 11 12 13 Relacja B (1-do-  ): główny język projektów naszych pracowników

7 Wykorzystanie operatora JOIN  Operatory JOIN (binarne, czyli na dwóch encjach) dzielimy na:  operatory INNER JOIN (odnoszą się tylko do elementów będących w relacji): EQUI JOIN (klasyczny INNER, wymaga równości pomiędzy kolumnami) NATURAL JOIN (wymaga równości, budowany w oparciu o nazwy kolumn)  operatory OUTER JOIN (dopuszczają elementy niebędące w relacji) LEFT OUTER (wszystkie elementy z encji po lewej stronie operatora) RIGHT OUTER (wszystkie elementy z encji po prawej stronie operatora) FULL OUTER (złożenie LEFT i RIGHT) NATURAL OUTER JOIN (OUTER budowany w oparciu o nazwy kolumn)  operator THETA JOIN (opiera się na warunku innym niż równość; rzadki)  operator ANTI JOIN (opiera się na warunku różności; rzadki)  operator CROSS JOIN (pełny iloczyn kartezjański)  Operator JOIN może występować także w wersji unarnej:  Operator SELF JOIN (tabela joinowana sama z sobą; raczej rzadki) Najważniejszą rolę pełnią INNER JOIN oraz OUTER JOIN (LEFT i RIGHT)

8 Dane do analizy  Wprowadzamy dane relacji update pracownik set id_jez=11 where id=1; update pracownik set id_jez=11 where id=2; update pracownik set id_jez=12 where id=3; 1 2 3 11 12 13 Relacja (1-do-  ): główny język projektów naszych pracowników mysql> select * from pracownik; +----+------+----------+-------+--------+ | id | imie | nazwisko | placa | id_jez | +----+------+----------+-------+--------+ | 1 | Jan | Nowak | 3400 | 11 | | 2 | Ewa | Malina | 2100 | 11 | | 3 | Iza | Trus | 4000 | 12 | +----+------+----------+-------+--------+ 3 rows in set (0.00 sec) mysql> select * from jezyk; +----+-----------+ | id | nazwa | +----+-----------+ | 11 | polski | | 12 | angielski | | 13 | niemiecki | +----+-----------+ 3 rows in set (0.01 sec)

9 INNER JOIN  INNER JOIN:  wymaga klauzuli ON (opisującej kolumny używane w warunku złączenia)  warunek zawsze zbudowany jest na równości (stąd nazwa: EQUI JOIN)  zwraca tylko te pary, które należą do relacji (WAŻNE!) mysql> SELECT * from pracownik INNER JOIN jezyk ON (pracownik.id_jez=jezyk.id);  równość id_jez=id występuje tylko 3 przypadkach  operator INNER JOIN zwraca podzbiór iloczynu kartezjańskiego  element, który nie znajduje się w relacji (nie wychodzi z niego żaden łuk) NIE ZOSTANIE zawarty w wyniku INNER JOIN 1 2 3 11 12 13 +----+------+----------+-------+--------+----+-----------+ | id | imie | nazwisko | placa | id_jez | id | nazwa | +----+------+----------+-------+--------+----+-----------+ | 1 | Jan | Nowak | 3400 | 11 | 11 | polski | | 2 | Ewa | Malina | 2100 | 11 | 11 | polski | | 3 | Iza | Trus | 4000 | 12 | 12 | angielski | +----+------+----------+-------+--------+----+-----------+

10 OUTER JOIN  OUTER JOIN:  wymaga klauzuli ON (opisującej kolumny używane w warunku złączenia)  warunek równość LUB brak elementu po "drugiej" stronie  zwraca te pary, które należą do relacji ORAZ pary (element encji-NULL)(WAŻNE!) SELECT * from jezyk LEFT OUTER JOIN pracownik ON (jezyk.id=pracownik.id_jez);  warunek ( id=id_jez) lub (jezyk.id nie jest elementem relacji) występuje w 4 przypadkach  operator OUTER JOIN zwraca podzbiór ilocz. kart. ORAZ pary zbudowane "sztucznie" z elementu NULL  element, który nie znajduje się w relacji (nie wychodzi z niego żaden łuk) ZOSTANIE zawarty w wyniku OUTER JOIN (jeśli jest po "odpowiedniej stronie") 1 2 3 11 12 13 +----+-----------+------+------+----------+-------+--------+ | id | nazwa | id | imie | nazwisko | placa | id_jez | +----+-----------+------+------+----------+-------+--------+ | 11 | polski | 1 | Jan | Nowak | 3400 | 11 | | 11 | polski | 2 | Ewa | Malina | 2100 | 11 | | 12 | angielski | 3 | Iza | Trus | 4000 | 12 | | 13 | niemiecki | NULL | NULL | NULL | NULL | NULL | +----+-----------+------+------+----------+-------+--------+

11 LEFT vs RIGHT OUTER JOIN 1 2 3 11 12 13 4 Autorzy są "twórcami" książek KSIĄŻKAAUTOR +----+--------+--------+------+----------+ | id | tytul | id_aut | id | nazwisko | +----+--------+--------+------+----------+ | 1 | LOTR | 11 | 11 | Tolkien | | 2 | Hobbit | 11 | 11 | Tolkien | | 3 | Eden | 12 | 12 | Lem | | 4 | Dziady | NULL | NULL | NULL | +----+--------+--------+------+----------+ +------+--------+--------+----+----------+ | id | tytul | id_aut | id | nazwisko | +------+--------+--------+----+----------+ | 1 | LOTR | 11 | 11 | Tolkien | | 2 | Hobbit | 11 | 11 | Tolkien | | 3 | Eden | 12 | 12 | Lem | | NULL | NULL | NULL | 13 | Reymont | +------+--------+--------+----+----------+ select * from ksiazka RIGHT OUTER JOIN autor on (ksiazka.id_aut=autor.id); select * from ksiazka LEFT OUTER JOIN autor on (ksiazka.id_aut=autor.id); 1 2 3 11 12 13 4 KSIĄŻKAAUTOR 1 2 3 11 12 13 4 KSIĄŻKAAUTOR 1 2 3 11 12 13 4 LEFT OUTER JOIN RIGHT OUTER JOIN NULL

12 LEFT, RIGHT i FULL OUTER JOIN +----+--------+--------+------+----------+ | id | tytul | id_aut | id | nazwisko | +----+--------+--------+------+----------+ | 1 | LOTR | 11 | 11 | Tolkien | | 2 | Hobbit | 11 | 11 | Tolkien | | 3 | Eden | 12 | 12 | Lem | | 4 | Dziady | NULL | NULL | NULL | |NULL| NULL | NULL | 13 | Reymont | +----+--------+--------+------+----------+ +------+--------+--------+----+----------+ | id | tytul | id_aut | id | nazwisko | +------+--------+--------+----+----------+ | 1 | LOTR | 11 | 11 | Tolkien | | 2 | Hobbit | 11 | 11 | Tolkien | | 3 | Eden | 12 | 12 | Lem | | NULL | NULL | NULL | 13 | Reymont | +------+--------+--------+----+----------+ select * from ksiazka RIGHT OUTER JOIN autor on (ksiazka.id_aut=autor.id); select * from ksiazka FULL OUTER JOIN autor on (ksiazka.id_aut=autor.id); 1 2 3 11 12 13 4 LEFT OUTER NULL +----+--------+--------+------+----------+ | id | tytul | id_aut | id | nazwisko | +----+--------+--------+------+----------+ | 1 | LOTR | 11 | 11 | Tolkien | | 2 | Hobbit | 11 | 11 | Tolkien | | 3 | Eden | 12 | 12 | Lem | | 4 | Dziady | NULL | NULL | NULL | +----+--------+--------+------+----------+ select * from ksiazka LEFT OUTER JOIN autor on (ksiazka.id_aut=autor.id); 1 2 3 11 12 13 4 1 2 3 11 12 13 4 RIGHT OUTERFULL OUTER NULL

13 OUTER JOIN vs INNER JOIN +----+--------+--------+------+----------+ | id | tytul | id_aut | id | nazwisko | +----+--------+--------+------+----------+ | 1 | LOTR | 11 | 11 | Tolkien | | 2 | Hobbit | 11 | 11 | Tolkien | | 3 | Eden | 12 | 12 | Lem | | 4 | Dziady | NULL | NULL | NULL | |NULL| NULL | NULL | 13 | Reymont | +----+--------+--------+------+----------+ +------+--------+--------+----+----------+ | id | tytul | id_aut | id | nazwisko | +------+--------+--------+----+----------+ | 1 | LOTR | 11 | 11 | Tolkien | | 2 | Hobbit | 11 | 11 | Tolkien | | 3 | Eden | 12 | 12 | Lem | | NULL | NULL | NULL | 13 | Reymont | +------+--------+--------+----+----------+ 1 2 3 11 12 13 4 LEFT OUTER NULL +----+--------+--------+------+----------+ | id | tytul | id_aut | id | nazwisko | +----+--------+--------+------+----------+ | 1 | LOTR | 11 | 11 | Tolkien | | 2 | Hobbit | 11 | 11 | Tolkien | | 3 | Eden | 12 | 12 | Lem | | 4 | Dziady | NULL | NULL | NULL | +----+--------+--------+------+----------+ 1 2 3 11 12 13 4 1 2 3 11 12 13 4 RIGHT OUTERFULL OUTER NULL +----+--------+--------+------+----------+ | id | tytul | id_aut | id | nazwisko | +----+--------+--------+------+----------+ | 1 | LOTR | 11 | 11 | Tolkien | | 2 | Hobbit | 11 | 11 | Tolkien | | 3 | Eden | 12 | 12 | Lem | +----+--------+--------+------+----------+ INNER JOIN 1 2 3 11 12 13 4 INNER JOIN LEFT OUTER RIGHT OUTER FULL OUTER

14 NATURAL JOIN  NATURAL JOIN jest przykładem JOINA, w którym:  warunek ON nie jest podawany w zapytaniu,  jest automatycznie generowany na podstawie NAZW kolumn  jeśli używamy klauzuli USING, to specyfikujemy kolumnę (jeśli nie – brane są pod uwagę WSZYSTKIE pary o jednakowych nazwach)  istnieje NATURAL JOIN (inner) oraz NATURAL [LEFT|RIGHT|FULL] OUTER select * from pracownik NATURAL JOIN dzial USING (ID_dzial);  NATURAL JOIN wymaga odpowiedniego nazywania kolumn  (jest to potencjalnie niebezpieczne dla nieuważnego programisty) Create table pracownik ( id int auto_increment primary key, nazwisko char(30), ID_dzial int ); Create table dzial ( ID_dzial int auto_increment primary key, nazwa char(30) );

15 CROSS JOIN  CROSS JOIN zwraca iloczyn kartezjański select * from pracownik CROSS JOIN jezyk select * from pracownik, jezyk +----+------+----------+-------+--------+----+-----------+ | id | imie | nazwisko | placa | id_jez | id | nazwa | +----+------+----------+-------+--------+----+-----------+ | 1 | Jan | Nowak | 3400 | 11 | 11 | polski | | 2 | Ewa | Malina | 2100 | 11 | 11 | polski | | 3 | Iza | Trus | 4000 | 12 | 11 | polski | | 1 | Jan | Nowak | 3400 | 11 | 12 | angielski | | 2 | Ewa | Malina | 2100 | 11 | 12 | angielski | | 3 | Iza | Trus | 4000 | 12 | 12 | angielski | | 1 | Jan | Nowak | 3400 | 11 | 13 | niemiecki | | 2 | Ewa | Malina | 2100 | 11 | 13 | niemiecki | | 3 | Iza | Trus | 4000 | 12 | 13 | niemiecki | +----+------+----------+-------+--------+----+-----------+

16 GROUP BY  Rozważmy następującą bazę: create table paragon ( id int auto_increment primary key, numer char(10), wartosc numeric(5,2), data_zakupu date, id_kli int ); create table klient ( id int auto_increment primary key, nazwa char(15) );

17 GROUP BY  Dotychczas tworzyliśmy po prostu tablicę wynikową za pomocą JOIN: select nazwa, numer, wartosc from klient left outer join paragon on (klient.id=paragon.id_kli); +-----------------+-------+---------+ | nazwa | numer | wartosc | +-----------------+-------+---------+ | Alfa sp. z o.o. | P001 | 110.2 | | Alfa sp. z o.o. | P002 | 20.25 | | Alfa sp. z o.o. | P003 | 311.5 | | Alfa sp. z o.o. | P008 | 45 | | Beta SA | P004 | 100.25 | | Beta SA | P005 | 70 | | Beta SA | P006 | 19.2 | | Beta SA | P007 | 30 | | Gamma Inc. | NULL | NULL | +-----------------+-------+---------+  Teraz chcemy przeprowadzić operacje na grupach danych

18 GROUP BY select nazwa, wartosc from klient left outer join paragon on (klient.id=paragon.id_kli); +-----------------+---------+ | nazwa | wartosc | +-----------------+---------+ | Alfa sp. z o.o. | 110.2 | | Alfa sp. z o.o. | 20.25 | | Alfa sp. z o.o. | 311.5 | | Alfa sp. z o.o. | 45 | | Beta SA | 100.25 | | Beta SA | 70 | | Beta SA | 19.2 | | Beta SA | 30 | | Gamma Inc. | NULL | +-----------------+---------+ select klient.id, nazwa, sum(wartosc) from klient left outer join paragon on (klient.id=paragon.id_kli) GROUP BY klient.id; +----+-----------------+--------------+ | id | nazwa | sum(wartosc) | +----+-----------------+--------------+ | 1 | Alfa sp. z o.o. | 486.95 | | 2 | Beta SA | 219.45 | | 3 | Gamma Inc. | NULL | +----+-----------------+--------------+  GROUP BY pozwala na zastosowanie SUM do grup (a nie całości) select sum(wartosc) from klient left outer join paragon on (klient.id=paragon.id_kli); +--------------+ | sum(wartosc) | +--------------+ | 706.40 | +--------------+

19 GROUP  Klauzuli GROUP BY używamy ze wszystkimi funkcjami, które mają działać na grupach danych i wyliczać dla każdej grupy reprezentującą ją wartość  Wyliczoną wartość nazywamy agregatem, a funkcje – funkcjami agregującymi  Funkcje agregujące to m.in. COUNT, MAX, MIN, SUM i AVG # wylicz wartość zakupów # dla każdej z firm select nazwa, sum(wartosc) from klient left outer join paragon on (klient.id=paragon.id_kli) group by klient.id; # wylicz średni zakup # dla każdej z firm select nazwa, avg(wartosc) from klient left outer join paragon on (klient.id=paragon.id_kli) group by klient.id; # jaki jest największy zakup # każdej z firm select nazwa, max(wartosc) from klient left outer join paragon on (klient.id=paragon.id_kli) group by klient.id; # ile zakupów zrobiła # każda z firm select nazwa, count(wartosc) from klient left outer join paragon on (klient.id=paragon.id_kli) group by klient.id;

20 HAVING  Klauzula HAVING pozwala wyfiltrować krotki, dla których agregat spełnia określony warunek (agregat – czyli WARTOŚĆ REPREZENTUJĄCA KAŻDĄ Z GRUP) select nazwa, sum(wartosc) from klient left outer join paragon on (klient.id=paragon.id_kli) group by klient.id HAVING sum(wartosc)>300 +-----------------+--------------+ | nazwa | sum(wartosc) | +-----------------+--------------+ | Alfa sp. z o.o. | 486.95 | +-----------------+--------------+ +-----------------+---------+ | nazwa | wartosc | +-----------------+---------+ | Alfa sp. z o.o. | 110.2 | | Alfa sp. z o.o. | 20.25 | | Alfa sp. z o.o. | 311.5 | | Alfa sp. z o.o. | 45 | | Beta SA | 100.25 | | Beta SA | 70 | | Beta SA | 19.2 | | Beta SA | 30 | | Gamma Inc. | NULL | +-----------------+---------+ +-----------------+--------------+ | nazwa | sum(wartosc) | +-----------------+--------------+ | Alfa sp. z o.o. | 486.95 | | Beta SA | 219.45 | | Gamma Inc. | NULL | +-----------------+--------------+ HAVING GROUP + SUM

21 HAVING vs WHERE  WHERE jest filtrem dla danych PRZED agregacją,  HAVING jest filtrem dla agregatów (wyników PO agregacji) select nazwa, sum(wartosc) from klient left outer join paragon on (klient.id=paragon.id_kli) WHERE wartosc>50 group by klient.id HAVING sum(wartosc)>200; +-----------------+---------+ | nazwa | wartosc | +-----------------+---------+ | Alfa sp. z o.o. | 110.2 | | Alfa sp. z o.o. | 311.5 | | Beta SA | 100.25 | | Beta SA | 70 | +-----------------+---------+ WHERE +-----------------+---------+ | nazwa | wartosc | +-----------------+---------+ | Alfa sp. z o.o. | 421.70 | | Beta SA | 170.25 | +-----------------+---------+ | nazwa | wartosc | +-----------------+---------+ | Alfa sp. z o.o. | 110.2 | | Alfa sp. z o.o. | 20.25 | | Alfa sp. z o.o. | 311.5 | | Alfa sp. z o.o. | 45 | | Beta SA | 100.25 | | Beta SA | 70 | | Beta SA | 19.2 | | Beta SA | 30 | | Gamma Inc. | NULL | +-----------------+---------+ GROUP+SUM HAVING +-----------------+---------+ | Alfa sp. z o.o. | 421.70 | +-----------------+---------+

22 JOIN z użyciem aliasów  Użycie aliasów pozwala za skrócenie długich zapytań JOIN (ale czasem może zmniejszyć czytelność polecenia) select nazwa, sum(wartosc) from klient left outer join paragon on (klient.id=paragon.id_kli) group by klient.id HAVING sum(wartosc)>300 select nazwa, sum(wartosc) from klient as k left outer join paragon as p on (k.id=p.id_kli) group by k.id HAVING sum(wartosc)>300 select nazwa, sum(wartosc) as ile from klient as k left outer join paragon as p on (k.id=p.id_kli) group by k.id HAVING ile>300

23 JOIN przez kilka tabel REDUNDANCJA Ta kolumna jest niepotrzebna, dlatego należy ją usunąć!

24 JOIN przez kilka tabel  Gdzie sprzedajemy (ile faktur w poszczególnych miastach) select miasto.nazwa, count(faktura.id) from miasto left outer join kupujacy on (miasto.id=kupujacy.id_mia) left outer join faktura on (kupujacy.id=faktura.id_kup) group by miasto.id +----------+-------------------+ | nazwa | count(faktura.id) | +----------+-------------------+ | Poznan | 4 | | Krakow | 3 | | Gdansk | 2 | | Warszawa | 4 | | Szczecin | 2 | | Tczew | 2 | | Sanok | 2 | | Radom | 0 | +----------+-------------------+

25 JOIN przez kilka tabel  Jakie są wartości poszczególnych faktur? select faktura.numer, sum(linia.ilosc*towar.cena) as wartosc from faktura left outer join linia on (faktura.id=linia.id_fak) left outer join towar on (linia.id_tow=towar.id) group by faktura.id +-----------+----------+ | numer | wartosc | +-----------+----------+ | FV3434531 | 235.3960 | | FV3497971 | 160.7850 | | FV3543322 | 140.4060 | (...) | FV3908888 | 14.0000 | | FV1138881 | 384.0000 | | FV2333531 | 368.0000 | | FV3911188 | 42.5300 | +-----------+----------+

26 JOIN przez kilka tabel  Ile faktur wystawili sprzedawcy? select sprzedawca.nazwisko, count(faktura.numer) as ile from sprzedawca left outer join faktura on (sprzedawca.id=faktura.id_spr) group by sprzedawca.id +----------+-----+ | nazwisko | ile | +----------+-----+ | Nowak | 4 | | Kuna | 2 | | Trus | 2 | | Pokora | 2 | | Gisz | 4 | | Wist | 1 | | Kunera | 1 | | Pokora | 1 | +----------+-----+

27 Postaci normalne O dobrym i złym projektowaniu baz danych

28  Dobry diagram baz danych powinien:  umożliwiać szybkie wyszukiwanie danych  zapewniać łatwą modyfikowalność  minimalizować szanse na wprowadzenie niespójności  zapewniać brak redundancji

29  Problemy:  jak wyszukać pracowników z Gdańska: SELECT * from PRACOWNIK WHERE adres like '%gdańsk%'  jak wyszukać pracowników z Wydziału A SELECT * from PRACOWNIK WHERE dzial like '%A%'  Powyższy diagram nie jest BŁĘDNY – jest MARNEJ JAKOŚCI

30  Jak dobrze projektować ERD?  Jak oceniać jakość diagramu ERD?  POSTAĆ NORMALNA: to zbiór własności, którymi muszą się charakteryzować dane, aby mogły być uznane za znormalizowane do danej postaci. Mówimy: te dane są (lub nie) w pierwszej (drugiej, trzeciej...) postaci normalnej.

31 1NF  Pierwsza postać normalna (1NF) wg Ch. Date:  Zbiór danych jest w 1NF wtedy, gdy:  nie ma powtarzających się krotek  każdy atrybut jest jednowartościowy (czyli, że w danym polu można zapisać tylko jedną wartość z dopuszczalnego zbioru)  nie ma wartości pustych (NULL)  Wersja dla teoretyków:  „zbiór danych jest w pierwszej postaci normalnej wtedy i tylko wtedy, gdy istnieje taka relacja, z którą zbiór ten jest izomorficzny

32 1NF  1NF: nie ma powtarzających się krotek:  zapewniamy przez UNIQUE albo przez kolumnę ID:  1NF: jednowartościowość atrybutów i NULL: ?

33  postulat Codda do 1NF:  dane powinny być "atomowe" (niepodzielne)  1 NF w wersji Codda:  rekordy (krotki) są rozróżnialne  atrybuty są atomowe  UWAGA: czy DATE albo CHAR(50) jest atomem?

34 2NF  2NF odnosi się do wykluczenia redundancji ?  W jaki sposób opisać to zjawisko formalnie?  klucz kandydujący - jest to każdy atrybut (lub najmniejsza z możliwych grupa atrybutów), których wartość jest unikalna w danej tabeli  klucz główny – arbitralnie wybrany klucz kandydujący  Zależność funkcyjna pomiędzy dwoma atrybutami (kolumnami tabeli) A i B oznacza, że dla każdej wartości atrybutu A występuje zawsze jedna wartość B

35 Zależność funkcyjna atrybutów encji  Zależność funkcyjna pomiędzy dwoma atrybutami (kolumnami tabeli) A i B oznacza, że dla każdej wartości atrybutu A występuje zawsze jedna wartość B  B1 = f(A1) ale B2 nie jest f(A2)

36 2 NF  Jakie są klucze kandydujące tabeli:  Tabela jest w 2NF wtedy i tylko wtedy gdy: 1. jest w 1NF 2. żaden z atrybutów, które nie wchodzą w skład klucza kandydującego nie jest funkcjonalnie zależny od części tego klucza (inaczej: żaden z atrybutów nie jest w częściowej zależności funkcyjnej od klucza głównego)  Tabela jest w 2NF wtedy i tylko wtedy gdy (mniej formalnie): 1. jest w 1NF 2. jeżeli weźmiemy dowolny klucz kandydujący i dowolny atrybut nie będący jego częścią to atrybut ten nie może być funkcją części klucza kandydującego.

37 2 NF  Sprawdzenie:  klucz kandydujący: (imię, nazwisko, język)  atrybut spoza klucza: miasto  klucz kandydujący vs atrybut: pełna zależność funkcyjna – ZAWSZE (dlaczego?) częściowa zależność funkcyjna – TAK MIASTO=f(imie, nazwisko)  WNIOSEK: relacja nie jest w 2NF

38 1NF  2 NF  Normalizacja do 2NF powoduje powstanie dodatkowych tablic

39 3NF  Trzecia postać normalna jest "silniejszą wersją" 2NF  Tabela jest w 3NF wtedy i tylko wtedy gdy: 1. jest w 2NF 2. nie istnieją przechodnie zależności funkcyjne  Sprawdzenie częściowych zależności funkcyjnych 2NF:  klucz kandydujący: Tor-Rok, atrybuty zewnętrzne: nazwisko, kraj  nazwisko nie jest f(Rok), nazwisko nie jest f(Tor),  kraj nie jest f(Rok), kraj nie jest f(Tor)  2NF

40 3NF  Problem:  Zależność funkcyjna przechodnia:  Kraj = f(Nazwisko)  UWAGA: To nie jest złamanie 2NF, bo ani kraj, ani nazwisko nie są częściami klucza kandydującego  Tak wyglądać może problem wynikający z niespełnienia 3NF:

41 Postaci Normalne - podsumowanie  UWAGA:  postaci normalne można "łamać" – np. świadomie godzić się na wprowadzenie (potencjalnej) niespójności do bazy danych  przykład: utworzenie tabeli przechowującej wartości zagregowane, aktualizowanej po DELETE lub INSERT  przykład: dodanie kolumny kod_miasta obok kolumny miasto  WNIOSKI:  postaci normalne to formalny sposób oceny jakości diagramu  stosujemy je po to, aby sprawdzić jakość naszych danych  nie robimy tego tylko po to, aby robić – możliwe jest złamanie PN, byle ŚWIADOME


Pobierz ppt "Bazy Danych W04: JOIN (złączenia) Wojciech St. Mościbrodzki"

Podobne prezentacje


Reklamy Google