Aleksandra Kobusińska nr indeksu: 218366 Hurtownia Świętego Mikołaja projekt bazy danych Zaprezentowana poniżej baza jest częścią większego projektu bazy danych wykorzystywanej w krajowych oddziałach wiosek Świętego Mikołaja. Baza ta składa się z 8 tabel zawierających niezbędne dane, aby co roku otrzymać informacje o wszystkich dzieciach oczekujących na prezenty (tabela DZIECI), ich opiekunach i adresach, na które należy dostarczyć paczki (tabela OPIEKUN), dostępnych zabawkach produkowanych przez elfy (tabela ZABAWKI), wymarzonych przez każde z dzieci prezentach (tabela LISTA ŻYCZEŃ), kategoriach prezentów (tabela TYPY), pracujących w oddziale elfach (tabela ELFY), odpowiednich zamówieniach (tabela PAKOWANIE) i ich dostawie (tabela DOSTAWA). System działa w następujący sposób. Każde dziecko posiada opiekuna. W hurtowni produkowane są zabawki tylko określonych typów i z nich dziecko wybiera swoje wymarzone prezenty. Dla każdego dziecka prezenty te składane są w paczkę i dostarczane na adres opiekuna. Elfy mogą zajmować następujące stanowiska: przy produkcji zabawek (każda zabawka ma przypisanego elfa), przy składaniu zamówienia oraz przy dostawie. Baza posiada następujące właściwości: Dziecko nie może być starsze niż 16 lat Elf, który nie ma renifera nie może pracować przy dostawie (to oczywiste) Paczki nie może dostarczać elf, który pracuje przy produkcji zabawek Dziecko musi posiadać opiekuna Na liście życzeń znajdują się tylko prezenty produkowane w hurtowni oraz tylko te dzieci, które znajdują się w bazie
Oraz następujące funkcjonalności: Możliwość sprawdzenia, ile prezentów z kategorii elektronika zamówiło każde z dzieci (wynikająca z troski św. Mikołaja, aby żadne z dzieci nie spędzało całych dni przed komputerem ) Możliwość sprawdzenia, ile w każdym zamówieniu powinno znajdować się elementów Możliwość zliczenia wszystkich zamówień, znajdujących się w danej chwili w bazie Wyświetlanie prezentów zamówionych przez konkretne dziecko Wyświetlenie wszystkich prezentów, które powinny znaleźć się w paczce o podanym numerze Wyświetlenie adresu dla podanego numeru dostawy SCHEMAT:
KOD: DROP TABLE dzieci CASCADE; DROP TABLE opiekun CASCADE; DROP TABLE typy CASCADE; DROP TABLE elfy CASCADE; DROP TABLE zabawki CASCADE; DROP TABLE lista_zyczen CASCADE; DROP TABLE pakowanie CASCADE; DROP TABLE dostawa CASCADE; CREATE TABLE dzieci( id_dziecka SERIAL PRIMARY KEY, imie VARCHAR(30) NOT NULL, wiek NUMERIC(2) NOT NULL, opiekun INTEGER); CREATE TABLE opiekun( id_opiekuna SERIAL PRIMARY KEY, imie VARCHAR(30) NOT NULL, nazwisko VARCHAR(40) NOT NULL, ulica VARCHAR(30), nr_domu VARCHAR(30), miasto VARCHAR(40) NOT NULL, kod_pocztowy VARCHAR(6) NOT NULL CHECK (kod_pocztowy ~ '^[0-9]{2}-[0-9]{3}$') ); ALTER TABLE dzieci ADD FOREIGN KEY(opiekun) REFERENCES opiekun(id_opiekuna) ON UPDATE CASCADE ON DELETE CASCADE; CREATE TABLE elfy( id_elfa SERIAL PRIMARY KEY, imie VARCHAR(30), renifer BOOLEAN); CREATE TABLE typy( typ VARCHAR(50) PRIMARY KEY); CREATE TABLE zabawki( id_zabawki SERIAL PRIMARY KEY, typ TEXT REFERENCES typy(typ) ON UPDATE CASCADE ON DELETE SET NULL, nazwa VARCHAR(50) NOT NULL, wielkosc VARCHAR(50), kolor VARCHAR(30), id_elfa INTEGER); ALTER TABLE zabawki ADD FOREIGN KEY(id_elfa) REFERENCES elfy(id_elfa) ON UPDATE CASCADE ON DELETE CASCADE; CREATE TABLE lista_zyczen( id_dziecka INTEGER REFERENCES dzieci(id_dziecka) ON UPDATE CASCADE ON DELETE CASCADE, id_zabawki INTEGER REFERENCES zabawki(id_zabawki) ON UPDATE CASCADE ON DELETE CASCADE
); ALTER TABLE lista_zyczen ADD PRIMARY KEY (id_dziecka, id_zabawki); CREATE TABLE pakowanie( nr_zamowienia SERIAL PRIMARY KEY, id_dziecka INTEGER REFERENCES dzieci(id_dziecka) ON UPDATE CASCADE ON DELETE CASCADE, id_elfa INTEGER REFERENCES elfy(id_elfa) ON UPDATE CASCADE ON DELETE CASCADE ); CREATE TABLE dostawa( id_dostawy SERIAL PRIMARY KEY, id_elfa INTEGER REFERENCES elfy(id_elfa) ON UPDATE CASCADE ON DELETE CASCADE, nr_zamowienia INTEGER REFERENCES pakowanie(nr_zamowienia) ON UPDATE CASCADE ON DELETE CASCADE ); -- widok - ile dzieci zamówiły prezentów z kategorii elektronika Drop view dziecko_elektro; Create view dziecko_elektro AS select id_dziecka, count(*) from lista_zyczen, zabawki where zabawki.id_zabawki=lista_zyczen.id_zabawki AND zabawki.typ LIKE 'elektronika' group by id_dziecka; -- widok - pokazuje ile w każdym zamówieniu powinno być elementów drop view ile_elem; Create view ile_elem AS select nr_zamowienia, count(*) from pakowanie, lista_zyczen where pakowanie.id_dziecka=lista_zyczen.id_dziecka group by nr_zamowienia; -- widok - zlicza ilość zamówień drop view ile_zam; Create view ile_zam AS select count(*) from (select count(*) from pakowanie group by nr_zamowienia) AS ile group by ile; -- wyzwalacz: dziecko nie może mieć więcej niż 16 lat DROP FUNCTION sprawdz_wiek(); CREATE OR REPLACE FUNCTION sprawdz_wiek() RETURNS TRIGGER AS ' IF (NEW.wiek>16) THEN RAISE EXCEPTION ''To już nie jest dziecko!''; END IF; RETURN NEW; CREATE TRIGGER sprawdz_wiek_trigger BEFORE INSERT OR UPDATE ON dzieci FOR EACH ROW EXECUTE PROCEDURE sprawdz_wiek(); -- wyzwalacz: w dostawie nie może uczestniczyć elf, który nie posiada własnego renifera DROP FUNCTION zwierzak() CASCADE;
CREATE OR REPLACE FUNCTION zwierzak() RETURNS TRIGGER AS ' IF (select elfy.renifer from elfy where new.id_elfa=elfy.id_elfa) IS false THEN RAISE EXCEPTION ''Ten elf nie ma renifera!''; END IF; RETURN NEW; CREATE TRIGGER zwierzak_trigger BEFORE INSERT OR UPDATE ON dostawa FOR EACH ROW EXECUTE PROCEDURE zwierzak(); -- wyzwalacz: paczki nie może dostarcza elf, który jednocześnie pracuje przy produkcji zabawek DROP FUNCTION elf() CASCADE; CREATE OR REPLACE FUNCTION elf() RETURNS TRIGGER AS ' IF (select distinct id_elfa from zabawki where new.id_elfa=zabawki.id_elfa) IS NOT NULL THEN RAISE EXCEPTION ''Ten elf nie może uczestniczyć w dostawie - pracuje przy produkcji!''; END IF; RETURN NEW; CREATE TRIGGER elf_trigger BEFORE INSERT OR UPDATE ON dostawa FOR EACH ROW EXECUTE PROCEDURE elf(); -- funkcja -- wyświetla zamówione prezenty przez konkretne dziecko DROP FUNCTION lista(integer); CREATE OR REPLACE FUNCTION lista(numer int) RETURNS table(id_zabawki int, typ text, nazwa varchar(50), wielkosc varchar(50), kolor varchar(50)) AS ' return query select zabawki.id_zabawki, zabawki.typ, zabawki.nazwa, zabawki.wielkosc, zabawki.kolor from zabawki, lista_zyczen where numer=lista_zyczen.id_dziecka AND lista_zyczen.id_zabawki=zabawki.id_zabawki; return; -- funkcja -- wyświetla wszystkie prezenty, które powinny się znaleźć w określonej paczce DROP FUNCTION paczka(integer); CREATE OR REPLACE FUNCTION paczka(numer int) RETURNS table(id_zabawki int, typ text, nazwa varchar(50), wielkosc varchar(50), kolor varchar(50)) AS '
return query select zabawki.id_zabawki, zabawki.typ, zabawki.nazwa, zabawki.wielkosc, zabawki.kolor from zabawki, lista_zyczen, pakowanie where numer=pakowanie.nr_zamowienia AND pakowanie.id_dziecka=lista_zyczen.id_dziecka AND lista_zyczen.id_zabawki=zabawki.id_zabawki; return; -- funkcja -- wyświetla cały adres dla danego numeru dostawy DROP FUNCTION adres(integer); CREATE OR REPLACE FUNCTION adres(numer int) RETURNS table(numer_dostawy INT, imie VARCHAR(30), nazwisko VARCHAR(40), ulica VARCHAR(30), nr_domu VARCHAR(30), miasto VARCHAR(40), kod_pocztowy VARCHAR(6)) AS ' return query select dostawa.id_dostawy, opiekun.imie, opiekun.nazwisko, opiekun.ulica, opiekun.nr_domu, opiekun.miasto, opiekun.kod_pocztowy from opiekun, dostawa, pakowanie, dzieci where numer=dostawa.id_dostawy AND dostawa.nr_zamowienia=pakowanie.nr_zamowienia AND pakowanie.id_dziecka=dzieci.id_dziecka AND dzieci.opiekun=opiekun.id_opiekuna; return; INSERT INTO opiekun(imie, nazwisko, ulica, nr_domu, miasto, kod_pocztowy) values('jan','kowalski','pulawskiego','14','wroclaw','45-400'); INSERT INTO opiekun(imie, nazwisko, ulica, nr_domu, miasto, kod_pocztowy) values('adam','nowak','mickiewicza','12','wroclaw','40-230'); INSERT INTO opiekun(imie, nazwisko, ulica, nr_domu, miasto, kod_pocztowy) values('maria','zielinska','padarewskiego','30a','warszawa','20-120'); INSERT INTO dzieci(imie, wiek, opiekun) VALUES('Janek', 10, 1); INSERT INTO dzieci(imie, wiek, opiekun) VALUES('Marta', 12, 2); INSERT INTO dzieci(imie, wiek, opiekun) VALUES('Wojtek', 6, 2); INSERT INTO dzieci(imie, wiek, opiekun) VALUES('Krzysiu', 7,3); INSERT INTO elfy(imie, renifer) values('fionnaghal', false); INSERT INTO elfy(imie, renifer) values('magaidh', true); INSERT INTO elfy(imie, renifer) values('falibhe', false); INSERT INTO elfy(imie, renifer) values('eoin', false); INSERT INTO elfy(imie, renifer) values('niallghas', true); INSERT INTO elfy(imie, renifer) values('torcadall', true); INSERT INTO typy VALUES('elektronika'); INSERT INTO typy VALUES('pluszaki'); INSERT INTO typy VALUES('gry planszowe'); INSERT INTO zabawki(typ, nazwa, id_elfa) values('elektronika','ipod',1); INSERT INTO zabawki(typ, nazwa, id_elfa) values('elektronika','odtwarzacz mp3',1); INSERT INTO zabawki(typ, nazwa, id_elfa) values('elektronika','laptop',1); INSERT INTO zabawki(typ, nazwa, wielkosc, kolor, id_elfa) values('pluszaki','pies','duzy','bialy',2); INSERT INTO zabawki(typ, nazwa, wielkosc, kolor, id_elfa) values('pluszaki','krowa','duzy','bialo-czarny',2); INSERT INTO zabawki(typ, nazwa, wielkosc, kolor, id_elfa) values('pluszaki','kot','maly','czarny',2); INSERT INTO zabawki(typ, nazwa, id_elfa) values('gry planszowe','scrabble',3);
INSERT INTO zabawki(typ, nazwa, id_elfa) values('gry planszowe','puzzle',3); INSERT INTO lista_zyczen(id_dziecka, id_zabawki) values(1,1); INSERT INTO lista_zyczen(id_dziecka, id_zabawki) values(1,3); INSERT INTO lista_zyczen(id_dziecka, id_zabawki) values(1,4); INSERT INTO lista_zyczen(id_dziecka, id_zabawki) values(2,2); INSERT INTO lista_zyczen(id_dziecka, id_zabawki) values(2,6); INSERT INTO lista_zyczen(id_dziecka, id_zabawki) values(3,8); INSERT INTO lista_zyczen(id_dziecka, id_zabawki) values(3,7); INSERT INTO lista_zyczen(id_dziecka, id_zabawki) values(4,4); INSERT INTO lista_zyczen(id_dziecka, id_zabawki) values(4,2); INSERT INTO pakowanie(id_dziecka, id_elfa) values(1, 4); INSERT INTO pakowanie(id_dziecka, id_elfa) values(2, 4); INSERT INTO pakowanie(id_dziecka, id_elfa) values(3, 5); INSERT INTO pakowanie(id_dziecka, id_elfa) values(4, 5); INSERT INTO dostawa(id_elfa, nr_zamowienia) values(5, 1); INSERT INTO dostawa(id_elfa, nr_zamowienia) values(5, 2); INSERT INTO dostawa(id_elfa, nr_zamowienia) values(6, 3); INSERT INTO dostawa(id_elfa, nr_zamowienia) values(6, 4); -- sprawdzanie: --widoki: SELECT * FROM dziecko_elektro; select * from ile_elem; select * from ile_zam; -- check: INSERT INTO opiekun(imie, nazwisko, ulica, nr_domu, miasto, kod_pocztowy) values('jan','kowalski','pulawskiego','14','wroclaw','45400'); -- funkcje: select lista(1); select adres(2); select paczka(2); -- wyzwalacze: INSERT INTO dzieci(imie, wiek, opiekun) VALUES('Janek', 19, 1); INSERT INTO dostawa(id_elfa, nr_zamowienia) values(4, 1); INSERT INTO dostawa(id_elfa, nr_zamowienia) values(2, 1);
Przykład zastosowania interfejsu graficznego (LibreOffice Base): Wyzwalacz: dziecko nie może mieć więcej niż 16 lat: Więz check: kod pocztowy musi być w formacie KK-KKK (gdzie K to dowolne cyfry):
Formularz dodawania nowych zabawek i ich typów do bazy: Formularz dodawania nowych wierszy do listy życzeń: