Bazy danych - Politechnika Gdańska

Transkrypt

Bazy danych - Politechnika Gdańska
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
Instrukcja do laboratorium z przedmiotu:
Bazy danych
Laboratorium nr 2.
Projektowanie relacyjnych struktur w bazach danych
Opracował A. Bujnowski
2010-03-08
Projekt „Przygotowanie i realizacja kierunku inżynieria biomedyczna – studia międzywydziałowe”
współfinansowany ze środków Unii Europejskiej w ramach Europejskiego Funduszu Społecznego.
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
UWAGA ! Zanim rozpoczniesz pracę zapoznaj się dokładnie z niniejszą instrukcją. Do punktu 6 nie
potrzebujesz komputera !
1. Cele laboratorium – zapoznanie się z technologiami konstruowania baz danych opartych o
wiele tabel. Zapis relacji w systemie zarządzania bazą danych. Utrwalanie relacji. Algebra
relacyjna, zapytania złożone.
2. Przykładowa baza danych:
Przykład bazy danych: Wypożyczalnia płyt DVD. W zbiorach wypożyczalni znajduje się wiele
pozycji płytowych. Każda pozycja ma swój tytuł, rok wydania, wydawcę oraz numer płyty –
w razie gdyby w wypożyczalni istniało wiele egzemplarzy takiej płyty. Płyty mogą być
płytami z filmami lub muzyką. Do takiej wypożyczalni przychodzą klienci, którzy muszą być
zarejestrowani, żeby mogli wypożyczać takie płyty.
Gdyby takie dane gromadzone były w formie tabeli prezentacyjnej , to przy każdej
akcji wypożyczenia w takiej tabeli musi pojawić się wiersz, w którym jednoznacznie
zidentyfikujemy kto wypożyczył płytę, którą płytę oraz kiedy. Drugim działaniem w takiej
bazie danych jest akcja zwrotu płyty. W tym momencie w wierszu dla odpowiedniego
wypożyczenia pojawia się data zwrotu. Przykładowa tabela takich zdarzeń podana jest
poniżej:
Imię
Nazwisko
Nr dowodu
Tytuł płyty
Nr płyty
Data
wypożyczenia
Jan
Nowak
DB 12345
Shrek
1
'2010-03-08'
Adam
Kowalski
DD 12945
Pinokio
3
'2010-03-09'
Zenon
Kwinto
DV 13345
Constantine 4
'2010-03-10'
Bruno
Data
zwrotu
'2010-03-10'
Szulc
DO 12314
Shrek
2
'2010-03-11'
'2010-03-15'
Znaczenie tej tabeli jest następujące: dnia 2010-03-08 pan Jan Nowak wypożyczył płytę
'Shrek' I jak dotąd jej nie zwrócił. Podobnie należy odczytywać następne wiersze, z tym, że
np. Pan Kowalski i Szulc zwrócili swoje płyty.
W takim zbiorze danych w jednej tabeli występują zarówno dane osoby, płyty jak I
akcji związane z wypożyczeniem tej płyty. W terminologii bazodanowej mówi się, że jest to
zbiór danych nieznormalizowany. Zauważmy również, że jest to jedyne miejsce
przechowywania danych, więc jeśli będziemy chcieli umieścić dodatkowe dane na temat
naszej płyty, czy też klienta – dane te muszą się pojawić jako nowe kolumny takiej tabeli.
Mało tego – jeżeli ten sam klient przyjdzie drugi raz do naszej wypożyczalni, to musimy
dodatkowo skopiować wszystkie jego dane w nowym wierszu tabeli. Czyni to taką tabelę
bardzo nieekonomiczną. Po pewnym czasie dane w niej zawarte będą zajmowały bardzo
dużo miejsca. Sensowne staje się zatem tzw. Znormalizowanie tego zbioru danych do
postaci kilku tabel. Prześledzimy ten proces w ramach pierwszej części tego laboratorium.
2
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
3. Diagram związków encji.
W tym miejscu dokonajmy podziału naszego problemu na podstawowe zbiory – encje. W
powyższym przykładzie na pewno da się wydzielić zbiór klientów. Wybierz zatem z tabeli
wszystkie atrybuty dotyczące klienta. Są to: imię, nazwisko I numer dowodu tożsamości.
Możliwe jest zatem stworzenie tabeli, która będzie zawierała tylko dane klientów. Podobnie
uczynimy z płytami. W tym przypadku w tabeli płyty użyjemy atrybutów tytuł I numer płyty.
Jeśli przyjrzymy się encjom klient I płyta, to możemy stwierdzić, że występuje pomiędzy
nimi związek wiele-do-wielu bo wielu klientów może wypożyczyć wiele płyt, oraz wiele płyt
może być wypożyczona przez wielu klientów. Zapiszmy ten związek na diagramie związków
encji:
Encja klient:
oraz płyta:
Jak zauważyłeś nazwę encji w diagramie związków encji (DZE) umieszcza się w prostokącie,
atrybuty w owalach, łącząc je z nazwą encji linią (bez kierunku ani strzałki). Przyjrzymy się
zatem notacji krotności na tych diagramach:
Wiemy również, że płyta w tym schemacie jest w krotności wiele-do-wielu z klientem:
3
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
Powyższy zapis na diagramie związków encji jest jak najbardziej poprawny, z tym, że w
systemach relacyjnych związek wiele-do wielu realizuje się z użyciem dodatkowej tabeli
powiązanej z istniejącymi encjami związkami jeden-do wielu i wiele-do-jednego. Trochę
również celowo na potrzeby wyjaśnienia tego związku pominięto do tej pory pozostałe
kolumny pierwszej tabeli w naszym schemacie bazy danych. Relacją, która powiąże encje
klient z płytą w sposób pozwalający na zapis tech schematu w diagramie relacyjnym będzie
relacja wypożyczenia. W schemacie projektowanej bazy danych ten związek jest wręcz
niezbędny, ale można wyobrazić sobie takie zależności, w których nie jest to już takie
oczywiste. Zatem relacja wypożyczenie będzie musiała posiadać dwie własności – datę
wypożyczenia oraz datę zwrotu i informację o powiązaniach z klientem i płytą:
Powyższy diagram pozwala na bezpośrednie przejście do diagramu relacyjnego – czyli
kolejnej postaci graficznej notacji struktury relacyjnej bazy danych – tym razem
bezpośrednio przenaszalnej do postaci kodu tworzącego bazę danych.
Zanim jednak przejdziemy do tworzenia diagramu relacyjnego zmodyfikujmy nieco nasz
DZE tak, aby powalał na nieco bardziej elastyczne operacje na klientach i płytach. W tabeli
klient występują atrybuty imię, nazwisko oraz nr dowodu. Niekiedy problemy stworzyć
może nr dowodu – gdyż np. osoby nieletnie nie będą takiej informacji posiadały,
jednocześnie samo imię i nazwisko nie wystarczy do rozróżnienia osób. Poza tym jeżeli
zbieramy takie dane osobowe jak numer dowodu, to nie powinniśmy narażać ich na
„wycieki” - czyli starajmy się tych informacji nie używać. Znacznie wygodniej jest zatem
wprowadzić dodatkowy element numerujący klientów. Jeżeli każdy klient otrzyma w naszej
bazie nowy, unikalny identyfikator – będzie to dobry kandydat na tzw klucz podstawowy w
tej tabeli. Dodajmy zatem do encji klient nowy atrybut o nazwie klient_id i zaznaczmy
podkreślając go, że będzie on kluczem głównym dla tej encji.
4
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
Podobnie postąpimy z płytami – z tym, że mamy już atrybut o nazwie numer, który użyjemy
jako klucz główny w tej tabeli. Zatem nowy DZE dla tej bazy może wyglądać następująco:
Zwróć również uwagę, że element pełniący rolę klucza głównego w relacji wypożyczenie
może być kombinacją wartości kto_wypożyczył, co_wypożyczył i daty wypożyczenia, jeżeli
przyjmiemy tzw. regułę biznesową, że ta sama osoba nie wypożyczy tej samej płyty drugi
raz tego samego dnia. Atrybuty kto_wypożyczył, co_wypożyczył i data_wypożyczenia
stanowią klucz złożony dla relacji wypożyczenie.
Dodatkowo, wartości atrybutu kto_wypożyczył dla relacji wypożyczenie powinny
przyjmować istniejące wartości atrybutu id_klienta z encji klient. Podobnie co_wypożyczył z
relacji wypożyczenie mogą przybierać jedynie wartości istniejące jako numer w encji płyta.
W następnym kroku przekształcimy nasz DZE w diagram relacyjny DR.
4. Diagram relacyjny.
Przekształcenie istniejącego DZE w diagram relacyjny jest dość proste. Encje i relacje
zastępujemy tabelami. Dostosowujemy nazewnictwo tabel do ograniczeń SZBD
(pozbawiamy znaków narodowych, zastępujemy spacje znakiem '_' itd. ..). Dla powyższego
DZE odpowiadający mu DR może wyglądać następująco:
Dodatkowo, zastąpmy krotności znakiem zależności funkcyjnych – czyli strzałka łączy tabele
5
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
w taki sposób, że można wyróżnić atrybuty, które się ze sobą łączą, grot strzałki powinien
wskazywać na element determinowany, który powinien być kluczem głównym. Wtedy
notacja strzałki oznaczać będzie zależność funkcyjną.
5. Data Definition Language (DDL)
Mając zdefiniowany DR łatwo jest przejść do tworzenia tabel w języku SQL. Wystarczy
przepisać definicję tabel, opuszczając ramki i dodając dyrektywę CREATE TABLE, oraz
zastanowić się w jaki sposób opisać działanie strzałek.
Przyjrzyjmy się zatem następującemu fragmentowi kodu:
CREATE TABLE klient (
imie varchar(20),
nazwisko varchar(40),
nr_dowodu char(10),
id_klienta serial primary key);
CREATE TABLE plyta(
tytul varchar(40),
numer serial primary key);
CREATE TABLE wypozyczenie(
kto_wypozyczyl int,
co_wypozyczyl int,
data_wypozyczenia date,
data_zwrotu date
primary key(kto_wypozyczyl, co_wypozyczyl,
data_wypozyczenia) );
Zauważmy, że tak zdefiniowane tabele nie są ze sobą powiązane, oraz występuje tutaj
szereg
niedogodności:
- możliwe jest wpisanie klienta, który ma puste imię i nazwisko,
możliwe
jest
wpisanie
płyty,
która
nie
ma
tytułu,
- możliwe jest wpisanie nowej akcji wypożyczenia z wartościami NULL jako kto_wypozyczyl i
co-wypozyczyl.
Przy pomocy dyrektywy not null możliwe jest zabezpieczenie bazy danych przed
występowaniem takich anomalii. Mając zdefiniowane poprzednie tabele można posłużyć
się poleceniem ALTER TABLE aby wprowadzić stosowne modyfikacje:
6
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
ALTER TABLE klient ALTER imie
SET not null;
ALTER TABLE klient ALTER nazwisko SET not null;
ALTER TABLE plyta ALTER tytul
SET not null;
Gdybyśmy chcieli od razu wprowadzić poprawny kod wyglądałoby to mniej więcej tak:
CREATE TABLE klient (
imie varchar(20) not null,
nazwisko varchar(40) not null,
nr_dowodu char(10),
id_klienta serial primary key);
CREATE TABLE plyta(
tytul varchar(40) not null,
numer serial primary key);
CREATE TABLE wypozyczenie(
kto_wypozyczyl int not null,
co_wypozyczyl int not null,
data_wypozyczenia date,
data_zwrotu date,
primary key(kto_wypozyczyl, co_wypozyczyl,
data_wypozyczenia) );
Zapiszmy teraz związki pomiędzy tabelami (najpierw posłużmy się poleceniem ALTER
TABLE), później pokażemy jak to zapisać od razu w CREATE TABLE.
ATLER TABLE wypozycenie ADD FOREIGN KEY (kto_wypozyczyl)
REFERENCES klient ON DELETE RESTRICT ON UPDATE RESTRICT;
ATLER TABLE wypozycenie ADD FOREIGN KEY (co_wypozyczyl)
REFERENCES plyta ON DELETE RESTRICT ON UPDATE CASCADE;
Przy pomocy takich poleceń zdefiniowano powiązania tabeli wypozycenie z klient i plyta.
Powiązane to polega na zdefiniowaniu klucza obcego, który odwołuje się do wartości klucza
głównego w innej tabeli (tak jak to opisują strzałki na DR). Dodatkowo mówimy tutaj o
sposobie zachowania się bazy danych w przypadku próby skasowania lub zmiany wartości
klucza głównego. Za chwilę zostanie to bliżej przedstawione praktycznie. Dla porządku
podany zostanie kod bazy danych, który nie wymaga modyfikacji przy pomocy ALTER TABLE:
CREATE TABLE klient (
imie varchar(20) not null,
nazwisko varchar(40) not null,
nr_dowodu char(10),
id_klienta serial primary key);
7
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
CREATE TABLE plyta(
tytul varchar(40) not null,
numer serial primary key);
CREATE TABLE wypozyczenie(
kto_wypozyczyl int not null REFERENCES klient ON DELETE
RESTRICT ON UPDATE RESTRICT,
co_wypozyczyl int not null REFERENCES plyta ON DELETE
RESTRICT ON UPDATE CASCADE,
data_wypozyczenia date,
data_zwrotu date
primary key(kto_wypozyczyl, co_wypozyczyl,
data_wypozyczenia) );
Zauważ, że tak przygotowany kod bazy danych z jednej strony zabezpiecza ją przed
pewnymi anomaliami w poszczególnych tabelach oraz pozwala na zapis i przestrzeganie
reguł integralności bazy danych.
Dodatkowo, zmieńmy jeszcze format daty, tak aby uwzględniał zarówno datę jak i godzinę w
naszej bazie danych. Taka wartość jest zdecydowanie częściej wykorzystywana w praktyce i
pozwala wyłuskać zarówno datę jak i godzinę zdarzenia. Zmiana dotyczy w jednej tabeli :
wypozyczenia ale powtórzymy całą definicję danych:
CREATE TABLE klient (
imie varchar(20) not null,
nazwisko varchar(40) not null,
nr_dowodu char(10),
id_klienta serial primary key);
CREATE TABLE plyta(
tytul varchar(40) not null,
numer serial primary key);
CREATE TABLE wypozyczenie(
kto_wypozyczyl int not null REFERENCES klient ON DELETE
RESTRICT ON UPDATE RESTRICT,
co_wypozyczyl int not null REFERENCES plyta ON DELETE
RESTRICT ON UPDATE CASCADE,
d_wypozyczenia timestamp default now(),
d_zwrotu timestamp,
primary key(kto_wypozyczyl, co_wypozyczyl,d_wypozyczenia) );
6. Ćwiczenia praktyczne
Mając zaprojektowaną wstępną wersję bazy danych sprawdźmy, jak działają obie wersje
bazy danych. Aby nieco usprawnić pracę z bazami danych, a jednocześnie zaprezentować
inny sposób pracy z bazą danych posłużmy się pomocniczymi plikami tekstowymi.
8
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
Oczywiście nic nie stoi na przeszkodzie, żebyś wpisał wszystkie podane poniżej polecenia
ręcznie, ale możliwość definiowania struktury bazy poza SZBD zdecydowanie tę czynność
usprawni.
Po zalogowaniu się do bazy przygotuj dwa pliki tekstowe: baza1.sql i baza2.sql
W tym celu wpisz polecenie : mcedit
baza1.sql. Pojawi się ekran, w którym
będziesz mógł wpisywać tekst. Po zakończeniu wpisywania wciśnij klawisz F2 w celu
zapisania zmian.
Treść pliku baza1.sql:
CREATE TABLE klient (
imie varchar(20),
nazwisko varchar(40),
nr_dowodu char(10),
id_klienta serial primary key);
CREATE TABLE plyta(
tytul varchar(40),
numer serial primary key);
CREATE TABLE wypozyczenie(
kto_wypozyczyl int,
co_wypozyczyl int,
data_wypozyczenia date,
data_zwrotu date,
primary key(kto_wypozyczyl, co_wypozyczyl,
data_wypozyczenia) );
Podobnie w pliku baza2.sql umieść tekst:
CREATE TABLE klient (
imie varchar(20) not null,
nazwisko varchar(40) not null,
nr_dowodu char(10),
id_klienta serial primary key);
CREATE TABLE plyta(
tytul varchar(40) not null,
numer serial primary key);
CREATE TABLE wypozyczenie(
kto_wypozyczyl int not null REFERENCES klient ON DELETE
RESTRICT ON UPDATE RESTRICT,
co_wypozyczyl int not null REFERENCES plyta ON DELETE
RESTRICT ON UPDATE CASCADE,
d_wypozyczenia timestamp default now(),
d_zwrotu timestamp,
9
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
primary key(kto_wypozyczyl, co_wypozyczyl,d_wypozyczenia) );
Utwórz teraz bazę danych o nazwie lab2_login gdzie login to twój własny login do systemu.
Wejdź do swojej bazy danych poprzez polecenie :
psql lab2_login
Wczytaj instrukcje z pliku baza1.sql:
\i baza1.sql
UWAGA ! - jeżeli pracujesz w innym katalogu niż Twój katalog domowy być może będziesz
musiał podać pełną nazwę tego pliku.
Wykonaj, i sprawdź działanie następujących poleceń:
INSERT INTO klient(imie) VALUES ('Jan');
INSERT INTO klient(nazwisko) VALUES ('Kowalski');
INSERT INTO klient DEFAULT VALUES;
INSERT INTO plyta DEFAULT VALUES;
INSERT INTO plyta DEFAULT VALUES;
INSERT INTO wypozyczenie DEFAULT VALUES;
INSERT INTO wypozyczenie (kto_wypozyczyl,co_wypozyczyl)
VALUES (3,1);
INSERT INTO wypozyczenie (kto_wypozyczyl,co_wypozyczyl)
VALUES (1,2);
Ostatnie 3 polecenia nie mogły się wykonać poprawnie, sprawdź proszę dlaczego ?
\d wypozyczenie
Popraw zapytanie dopisując datę wypożyczenia:
INSERT INTO wypozyczenie
(kto_wypozyczyl,co_wypozyczyl,data_wypozyczenia) VALUES
(3,1,'2010-03-11');
Jak dotąd, o ile nie popełniłeś błędu przy wpisywaniu danych nie powinien pojawić się błąd.
Ale sprawdź postać danych:
SELECT * FROM klient;
SELECT * FROM plyta;
SELECT * FROM wypozyczenie;
SELECT klient.imie, klient.nazwisko, plyta.tytul,
wypozyczenie.data_wypozyczenia, wypozyczenie.data_zwrotu
FROM
klient, wypozyczenie, plyta
10
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
WHERE
klient.id_klienta = wypozyczenie.kto_wypozyczyl AND
plyta.numer = wypozyczenie.co_wypozyczyl;
Zastanów się, czy rzeczywiście chcesz aby Twoja baza danych przechowywała takie
wartości? Zaprezentuj wynik działania prowadzącemu.
Usuń wszystkie założone tabele w swojej bazie danych:
DROP TABLE wypozyczenie;
DROP TABLE plyta;
DROP TABLE klient;
Załóż te same tabele, ale już z uwzględnieniem warunków integralności bazy danych:
\i baza2.sql
Spróbuj powtórzyć poprzednie polecenia:
INSERT INTO klient(imie) VALUES ('Jan');
INSERT INTO klient(nazwisko) VALUES ('Kowalski');
INSERT INTO klient DEFAULT VALUES;
INSERT INTO plyta DEFAULT VALUES;
INSERT INTO plyta DEFAULT VALUES;
INSERT INTO wypozyczenie DEFAULT VALUES;
INSERT INTO wypozyczenie (kto_wypozyczyl,co_wypozyczyl)
VALUES (2,2);
INSERT INTO wypozyczenie
(kto_wypozyczyl,co_wypozyczyl,data_wypozyczenia) VALUES
(3,2,'2010-03-11');
INSERT INTO wypozyczenie
(kto_wypozyczyl,co_wypozyczyl,data_wypozyczenia) VALUES
(2,2,now());
Co się stało z bazą danych ?
SELECT * FROM klient;
SELECT * FROM plyta;
SELECT * FROM wypozyczenie;
SELECT klient.imie, klient.nazwisko, plyta.tytul,
wypozyczenie.d_wypozyczenia, wypozyczenie.d_zwrotu
FROM
klient, wypozyczenie, plyta
11
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
WHERE
klient.id_klienta = wypozyczenie.kto_wypozyczyl AND
plyta.numer = wypozyczenie.co_wypozyczyl;
Dodaj 5 przykładowych płyt i pięciu przykładowych klientów do bazy danych – tym razem
tak, aby polecenia wykonały się poprawnie. Teraz wypróbuj wypożyczanie (zauważ, że data
wypożyczenia może już być nie wpisywana, pomimo że jest not null (ma bowiem default):
INSERT INTO wypozyczenie (kto_wypozyczyl,co_wypozyczyl)
VALUES (3,1);
INSERT INTO wypozyczenie (kto_wypozyczyl,co_wypozyczyl)
VALUES (2,4);
INSERT INTO wypozyczenie
(kto_wypozyczyl,co_wypozyczyl,data_wypozyczenia) VALUES
(3,2,'2010-03-11');
INSERT INTO wypozyczenie
(kto_wypozyczyl,co_wypozyczyl,data_wypozyczenia) VALUES
(2,2,now());
Sprawdź również czy wykonają się następujące polecenia:
INSERT
VALUES
INSERT
VALUES
INTO wypozyczenie (kto_wypozyczyl,co_wypozyczyl)
(3,200);
INTO wypozyczenie (kto_wypozyczyl,co_wypozyczyl)
(300,2);
Jak myślisz, dlaczego się nie wykonały ?
Spróbuj teraz wykonać następujące polecenia
DELETE FROM klient WHERE id_klienta =2;
DELETE FROM klient WHERE id_klienta =1;
DELETE FROM plyta WHERE numer=5;
DELETE FROM plyta WHERE numer=2;
Jaka jest różnica, co się stało z bazą (SELECT * FROM wypozyczenie);
W podobny sposób sprawdzić zachowanie się funkcji :
UPDATE klient SET id_klienta = 10 where id_klienta = 1;
UPDATE plyta SET numer = 10 where numer = 1;
Zapytania z wielu tabel.
Tabela wypozyczenie jest bardzo wygodną formą zapisu informacji, ale jest mało czytelna.
Możliwe jest przygotowanie raportu z bazy danych tak, aby był on bardziej czytelny:
12
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
Każde zapytanie z więcej niż jednej tabeli generuje iloczyn kartezjański poszczególnych
zbiorów:
SELECT * FROM klient, wypozyczenie, plyta;
Jaki jest wynik takiej operacji ? Jakie są wymiary tabeli wynikowej ? Co zawierają
poszczególne wiersze ? Czy te dane mają sens ?
Poprawmy to zapytanie, tak aby pokazało tylko te wiersze, dla których :
wypozyczenie.kto_wypozyczyl=klient.id_klient oraz plyta.numer
= wypozyczenie.co_wypozyczyl :
SELECT * FROM klient, wypozyczenie, plyta
WHERE
klient.id_klienta = wypozyczenie.kto_wypozyczyl AND
plyta.numer = wypozyczenie.co_wypozyczyl;
W wyniku tego zapytania ilość wierszy już odzwierciedla faktyczną liczbę wypożyczeń ale
pojawiają się kolumny, których do niczego nie potrzebujemy. Spróbujmy zatem wyświetlić
tylko te kolumny, które powinny znaleźć się w tabeli prezentacyjnej.
SELECT klient.imie, klient.nazwisko, plyta.tytul,
wypozyczenie.d_wypozyczenia, wypozyczenie.d_zwrotu
FROM
klient, wypozyczenie, plyta
WHERE
klient.id_klienta = wypozyczenie.kto_wypozyczyl AND
plyta.numer = wypozyczenie.co_wypozyczyl;
To samo zapytanie, w formie nieco skróconej:
SELECT k.imie, k.nazwisko, p.tytul,w.d_wypozyczenia,
w.d_zwrotu
FROM
klient k, wypozyczenie w, plyta p
WHERE
k.id_klienta = w.kto_wypozyczyl AND p.numer =
w.co_wypozyczyl;
Systemy zarządzania bazą danych niejednokrotnie umożliwiają utrwalenie raz
przygotowanego zapytania w systemie baz danych. Formą takiego utrwalenia jest widok
(perspektywa). Widok jest to inaczej definicja zapytania utrwalona w specjalnej tabeli w
bazie danych. Każde odwołanie się do widoku powoduje wykonanie zapisanego w nim
zapytania na aktualnym obrazie (stanie) bazy danych. Zatem utrwalmy powyższe zapytanie
13
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
w formie widoku:
CREATE VIEW pokwypoz AS SELECT k.imie, k.nazwisko,
p.tytul,w.data_wypozyczenia, w.data_zwrotu
FROM
klient k, wypozyczenie w, plyta p
WHERE
k.id_klienta = w.kto_wypozyczyl AND p.numer =
w.co_wypozyczyl;
Z widoku korzysta się dokładne tak samo jak z każdej tabeli lub grupy tabel:
Sprawdź co się nowego pojawiło w bazie danych:
\d
i sprawdź definicję tego widoku
\d pokwypoz
SELECT * FROM pokwypoz;
Spróbujmy stworzyć to samo zapytanie korzystając z klauzuli JOIN:
SELECT k.imie, k.nazwisko, p.tytul,w.d_wypozyczenia,
w.d_zwrotu
FROM klient k JOIN wypozyczenie w ON k.id_klienta =
w.kto_wypozyczyl JOIN plyta p ON p.numer = w.co_wypozyczyl;
Sprawdźmy zastosowanie LEFT i RIGHT JOIN:
SELECT k.imie, k.nazwisko, p.tytul,w.d_wypozyczenia,
w.d_zwrotu
FROM klient k LEFT JOIN wypozyczenie w ON k.id_klienta =
w.kto_wypozyczyl LEFT JOIN plyta p ON p.numer =
w.co_wypozyczyl;
oraz
SELECT k.imie, k.nazwisko, p.tytul,w.d_wypozyczenia,
w.d_zwrotu
FROM klient k JOIN wypozyczenie w ON k.id_klienta =
w.kto_wypozyczyl RIGHT JOIN plyta p ON p.numer =
w.co_wypozyczyl;
14
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
7. Hierarchia
Niejednokrotnie zachodzi potrzeba spośród grupy encji wyróżnienia określonej grupy
krotek. Np. spośród grona klientów można wyróżnić grono pracowników danej
wypożyczalni, którzy mają uprawnienia do wypożyczania z rabatem. Pierwszym
rozwiązaniem jest umieszczenie atrybutu rabat w zbiorze klientów. Natomiast gdy takich
wyróżnionych osób jest kilka procent to bardziej opłacalne stanie się wykorzystanie tabeli
pozostającej w hierarchii z istniejącą tabelą.
Przykładowy zapis dla DZE:
I zapis w SQL:
odpowiadający mu DR:
CREATE TABLE jest_pracownikiem(
rabat int,
id_klienta int primary key references klient);
8. Podsumowanie
- Relacyjna baza danych składa się z wielu tabel połączonych związkami
- Każda encja lub zależność w takiej bazie danych opisuje tabela
- Normalizacja bazy danych jest procesem odwracalnym, w którym bazę w postaci płaskiej
przekształca się do kilku table tak, aby nie występowały anomalie korzystania z plików.
- widok jest utrwaloną postacią zapytania a wykonanie zapytania z widoku zawsze działa na
aktualnym stanie bazy danych
- Zapytania złożone MUSZĄ odzwierciedlać założone związki w bazie. Możliwe jest takie
zaprojektowanie bazy danych aby te związki nie były przestrzegane, tym niemniej dzięki
zapytaniom złożonym możliwe jest korzystanie z takiej struktury
- Zapytania złożone wykorzystujące klauzulę JOIN pozwalają na ręczną optymalizację
kolejności
łączenia
tabel
–
a
co
idzie
czasu
wykonania
zapytania
- Klauzule RIGH i LEFT JOIN pozwalają na ochronę określonych fragmentów kolumn, lub
związków kolumn, przez co analiza danych może być wykonana sprawniej
15
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski
Politechnika Gdańska, międzywydziałowy kierunek „INŻYNIERIA BIOMEDYCZNA”
9. Zadania i pytania kontrolne:
•W
omawianej na laboratorium bazie danych uzupełnij pole płyta o jej dobową cenę
wypożyczenia. Narysuj DZE i DR dla tak zmodyfikowanej bazy danych.
•Korzystając z widoków wyświetl listę wypożyczeń bez daty zwrotu.
•Uzupełnij tabelę płyt o możliwość przechowywania ceny wypożyczenia płyty
•Korzystając z widoków wyświetl zestawienie wypożyczonych i zwróconych płyt w zadanym przez
prowadzącego przedziale czasu
•Utrwal dwa ostatnie zapytania w formie widoku
•Zmodyfikuj strukturę bazy w taki sposób, żeby każda płyta mogła należeć do kilku gatunków
jednocześnie (relacja wiele-do-wielu).
Zaprojektuj bazę danych – zadaną przez prowadzącego. Przykładowe zadania na końcu skryptu.
Zaprojektowana baza powinna być min. w trzeciej postaci normalnej i projekt powinien skończyć
się implementacją struktury danych w SZBD
10.Przykładowe bazy danych:
•Baza danych dla hoteliku – hotel ma pokoje, pokoje mają wyposażenie, klient wynajmuje pokoje
•Baza danych dla wypożyczalni jachtów, każdy jacht ma wyposażenie, klient może należeć lub nie
do klubu (jeśli należy – to ma zniżki), klient wypożycza jacht wraz z wyposażeniem, cena jest
wyliczana na podstawie sumy ceny wynajmu jachtu i wszystkich składników wyposażenia
•Baza danych dla apteki – klient kupuje lek, który dostarcza do apteki hurtownia
•Baza danych dla firmy transportowej – kierowca jest w związki 1-1 z samochodem i realizuje wiele
usług transportowych pomiędzy adresami, na zlecenie klienta
•Baza danych zbiorów bibliotecznych i wypożyczeń, każda książka należy do kategorii
•Baza danych małej firmy jubilerskiej – z gotowych składników wykonywana jest biżuteria, którą
sprzedaje się klientom. Cena biżuterii to suma ceny składników + koszt wykonania
•Baza danych sklepu z materiałami budowlanymi
•Wirtualny dziennik: uczeń należy do klasy, opiekunem klasy jest nauczyciel, który równocześnie
naucza przedmiotu. Uczeń otrzymuje oceny z przedmiotów.
•Baza danych utworów muzycznych nadawanych w rozgłośni – w bazie są utwory, należące do
albumów, albumy należą do wydawców, pracownik ustala harmonogram emisji utworów w radiu.
•Baza danych rozpraw sądowych – rozprawa odbywa się określonego dnia, rozprawie przewodniczy
sędzia, istnieje oskarżony, oskarżyciel, obrońca i powód.
•Itp. ...
16
BAZY DANYCH, laboratorium nr 2 , A. Bujnowski

Podobne dokumenty