Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Bazy Danych W03: Spójność relacji i JOINy Wojciech St. Mościbrodzki

Podobne prezentacje


Prezentacja na temat: "Bazy Danych W03: Spójność relacji i JOINy Wojciech St. Mościbrodzki"— Zapis prezentacji:

1 Bazy Danych W03: Spójność relacji i JOINy Wojciech St. Mościbrodzki

2 Podstawy SQL - przypomnienie  SQL jest językiem stosunkowo prostym (i archaicznym)  Założeniem SQL była realizacja podstawowych operacji bazodanowych:  wyszukiwanie rekordów - SELECT  dodawanie rekordów - INSERT  usuwanie rekordów - DELETE  modyfikacja rekordów - UPDATE  Poza „wielką czwórką” istnieją polecenia do zarządzania tabelami, bazami, tworzące indeksy, itp.  Polecenia wydawane w SQL nazywamy zapytaniami SQL (a nie – kwerendami; terminologia Microsoft)

3 SQL jako język zapytań  Typowy podział poleceń (zapytań) SQL:  SQL DML (ang. Data Manipulation Language – „język manipulacji danymi”), SELECT, INSERT, UPDATE, DELETE  SQL DDL (ang. Data Definition Language – „język definicji danych”), CREATE, DROP, ALTER, …  SQL DCL (ang. Data Control Language – „język kontroli nad danymi”). GRANT, REVOKE, …  Inny podział:  polecenia standardowego (lub dialektowego) SQL (wykonuje je serwer)  polecenia typowe dla serwera konkretnego producenta (wykonuje je serwer)  polecenia dla klienta (oprogramowanie klienckie) – np. DELIMITER (mysql)  UWAGA: średnik (;) nie jest elementem zapytania, tylko znakiem terminalnym (po jego odebraniu klient przesyła zapytanie do serwera)

4 Podstawy SQL  Typy danych:  Numeryczne (mogą być SIGNED lub UNSIGNED): Całkowite: TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT Rzeczywiste: FLOAT, DOUBLE, DECIMAL, NUMERIC Bitowe: BIT Logiczne: BOOL lub BOOLEAN (implementowane w Mysql jako TINYINT(1))  Tekstowe: CHAR – znaków, przy przechowywaniu uzupełniane spacjami do podanego rozmiaru VARCHAR – znaków, zajmują długość łańcucha + informacja o dłougości (1 lub 2 bajty) BINARY i VARBINARY – przechowują łańcuchy w postaci binarnej TEXT – duży obiekt tekstowy (BLOB – wersja binarna) ENUM – typ wyliczeniowy, elementami są napisy SET – typ specjalny, może zawierać dowolną liczbę (!!!) wartości ze zbioru

5  Typy danych:  Typy związane z czasem: DATETIME – data (domyślnie) w formacie: YYYY-MM-DD HH:MM:SS DATE – data w formacie: YYYY-MM-DD TIME – czas w formacie: HH:MM:SS  Typy specjalne: BLOB – duże obiekty binarne (np. obrazki, pliki mp3) TIMESTAMP – specjalny typ (znacznik czasowy, w formacie DATETIME)

6 Spójność relacyjna  Spójność relacyjna (relational integrity) – sytuacja, w której dane są w takiej postaci, która jest "wysokiej jakości":  Spójność encji (entity integrity) – każde dwa elementy danych (obiekty) są rozróżnialne. Innymi słowy: istnieje klucz główny, a wartości tego klucza są ustalone (nie występuje NULL, czyli wartość nieustalona)  Spójność wartości nieustalonych (null integrity) – dla określonych danych wartość NULL jest nieakceptowalna  Spójność dziedzinowa (domain integrity) – wartości atrybutów są w dopuszczalnym zakresie (np. wiek nie może być ujemny, liczba pracowników – wyrażona ułamkiem itp.). Spójność domenowa sugeruje, że dane z różnych dziedzin nie powinny być porównywane "wprost".  Spójność referencyjna (referential integrity) – odnosi się do relacji pomiędzy dwoma tabelami; wymaga aby wartości klucza obcego odpowiadały istniejącym wartościom tabeli wskazywanej (klucz główny)

7 Spójność referencyjna  Przypomnienie:  Klucz kandydujący – jeden z zestawów atrybutów, który może pełnić rolę klucza  Klucz główny – wybrany arbitralnie klucz spośród kluczy kandydujących  Klucz obcy – zestaw atrybutów, który odpowiada kluczowi głównemu innej tabeli

8 Naruszenie spójności referencyjnej  Naruszenia spójności  DELETE: usunięcie rekordu, do którego ID jest wartością klucza obcego  UPDATE: zmiana wartości klucza obcego na nieistniejący (brak wartości klucza głównego) lub zmiana wartości klucza głównego, któremu odpowiada klucz obcy  INSERT: wstawienie rekordu, którego klucz obcy odpowiada nieistniejącej wartości klucza głównego

9 Więzy integralności  Obsługa więzów integralności w mysql (UWAGA: tylko InnoDB): [CONSTRAINT] FOREIGN KEY (index_col_name,...) REFERENCES tbl_name (index_col_name,...) [ON DELETE reference_option] [ON UPDATE reference_option] reference_option: RESTRICT | CASCADE | SET NULL | NO ACTION create table dzial ( id int auto_increment primary key, nazwa char(10) ) ENGINE=InnoDB; create table pracownik ( id int auto_increment primary key, imie char(10), nazwisko char(15), id_dzi int, CONSTRAINT FOREIGN KEY (id_dzi) REFERENCES dzial(id) ) ENGINE=InnoDB;  Tabela "główna" musi istnieć podczas tworzenia tabeli "potomnej":  Usuwanie tabel również wymaga odpowiedniej kolejności!

10 Spójność referencyjna  Więzy typu RESTRICT (w MySQL = NO ACTION) zabraniają wykonania operacji create table pracownik ( id int auto_increment primary key, nazwisko char(15), id_dzi int, CONSTRAINT FOREIGN KEY (id_dzi) REFERENCES dzial(id) ) ENGINE=InnoDB; insert into pracownik values (1,'Jan','Nowak',1); ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`rbd3/pracownik`, CONSTRAINT `pracownik_ibfk_1` FOREIGN KEY (`id_dzi`) REFERENCES `dzial` (`id`)) mysql> delete from dzial where id=1; ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`rbd3/pracownik`, CONSTRAINT `pracownik_ibfk_1` FOREIGN KEY (`id_dzi`) REFERENCES `dzial` (`id`))

11 Spójność referencyjna  Więzy typu CASCADE przenoszą operacje (DELETE lub CASCADE) z rekordów tabeli "rodzica" na tabelę "potomną" create table pracownik ( id int auto_increment primary key, nazwisko char(15), id_dzi int, CONSTRAINT FOREIGN KEY (id_dzi) REFERENCES dzial(id) ON DELETE CASCADE ) ENGINE=InnoDB; mysql> select count(id) from pracownik; delete from dzial where id=1; select count(id) from pracownik; | count(id) | | 4 | | count(id) | | 2 |

12 Spójność referencyjna  Więzy typu SET NULL po operacji DELETE/UPDATE na rekordach tabeli "rodzica" ustawiają wartości klucza obcego na NULL create table pracownik ( id int auto_increment primary key, nazwisko char(15), id_dzi int, CONSTRAINT FOREIGN KEY (id_dzi) REFERENCES dzial(id) ON DELETE CASCADE ) ENGINE=InnoDB; | id | serial | id_pra | | 1 | NP3451 | 1 | | 2 | ED2221 | 2 | | 3 | AP1111 | 3 | | 4 | AP1311 | 3 | | 5 | AS8751 | 4 | | 6 | SU9458 | 3 | select * from telefon; delete from pracownik where id=3; | id | serial | id_pra | | 1 | NP3451 | 1 | | 2 | ED2221 | 2 | | 3 | AP1111 | NULL | | 4 | AP1311 | NULL | | 5 | AS8751 | 4 | | 6 | SU9458 | NULL |

13 Spójność dziedzinowa - CHECK  CHECK zapewnia ochronę przed wstawieniem danych nie spełniających określonego warunku CREATE TABLE user( id auto_increment PRIMARY KEY, login VARCHAR(16), password VARCHAR(20), CONSTRAINT CHECK(LENGTH(password) BETWEEN 8 AND 16) ) CREATE TABLE Person( P_Id int NOT NULL, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255), CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes') )

14 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)

15 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 |

16 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 Relacja A (1-do-1): jaki język obowiązuje w kraju zamieszkania pracownika Relacja B (1-do-  ): jakie są języki ojczyste pracowników Relacja D (  -do-  ): jakimi językami mówią pracownicy Relacja C (1-do-1): jakiego języka uczą się pracownicy

17 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: Relacja A (1-do-  ): jakie są języki ojczyste pracowników Relacja B (1-do-  ): główny język projektów naszych pracowników

18 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)

19 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; 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 | rows in set (0.00 sec) mysql> select * from jezyk; | id | nazwa | | 11 | polski | | 12 | angielski | | 13 | niemiecki | rows in set (0.01 sec)

20 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 | 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 |

21 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") | 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 |

22 LEFT vs RIGHT OUTER JOIN 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); KSIĄŻKAAUTOR KSIĄŻKAAUTOR LEFT OUTER JOIN RIGHT OUTER JOIN NULL

23 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); 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); RIGHT OUTERFULL OUTER NULL

24 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 | 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 | 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 INNER JOIN LEFT OUTER RIGHT OUTER FULL OUTER

25 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) );

26 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 |

27 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) );

28 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 | | | Alfa sp. z o.o. | P002 | | | Alfa sp. z o.o. | P003 | | | Alfa sp. z o.o. | P008 | 45 | | Beta SA | P004 | | | Beta SA | P005 | 70 | | Beta SA | P006 | 19.2 | | Beta SA | P007 | 30 | | Gamma Inc. | NULL | NULL |  Teraz chcemy przeprowadzić operacje na grupach danych

29 GROUP BY select nazwa, wartosc from klient left outer join paragon on (klient.id=paragon.id_kli); | nazwa | wartosc | | Alfa sp. z o.o. | | | Alfa sp. z o.o. | | | Alfa sp. z o.o. | | | Alfa sp. z o.o. | 45 | | Beta SA | | | 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. | | | 2 | Beta SA | | | 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) | | |

30 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;

31 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)> | nazwa | sum(wartosc) | | Alfa sp. z o.o. | | | nazwa | wartosc | | Alfa sp. z o.o. | | | Alfa sp. z o.o. | | | Alfa sp. z o.o. | | | Alfa sp. z o.o. | 45 | | Beta SA | | | Beta SA | 70 | | Beta SA | 19.2 | | Beta SA | 30 | | Gamma Inc. | NULL | | nazwa | sum(wartosc) | | Alfa sp. z o.o. | | | Beta SA | | | Gamma Inc. | NULL | HAVING GROUP + SUM

32 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. | | | Alfa sp. z o.o. | | | Beta SA | | | Beta SA | 70 | WHERE | nazwa | wartosc | | Alfa sp. z o.o. | | | Beta SA | | | nazwa | wartosc | | Alfa sp. z o.o. | | | Alfa sp. z o.o. | | | Alfa sp. z o.o. | | | Alfa sp. z o.o. | 45 | | Beta SA | | | Beta SA | 70 | | Beta SA | 19.2 | | Beta SA | 30 | | Gamma Inc. | NULL | GROUP+SUM HAVING | Alfa sp. z o.o. | |

33 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

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

35 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 |

36 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 | | FV | | | FV | | | FV | | (...) | FV | | | FV | | | FV | | | FV | |

37 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 |

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

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

40  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

41  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.

42 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

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

44  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?

45 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

46 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)

47 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.

48 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

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

50 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

51 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:

52 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 W03: Spójność relacji i JOINy Wojciech St. Mościbrodzki"

Podobne prezentacje


Reklamy Google