1. Dostęp do bazy danych(powłoka psql)
2. Literatura: PostgreSQL 8.0.3 Documentation (wersja angielska dla obecnie zainstalowanego Postgresa)istnieje też tłumaczenie polskie trochę starszej wersji Postgresa: PostgreSQL 7.1.3 Tutorial
o Od diagramu związków encji do tabel w bazie
W języku SQL tabele bazy danych tworzymy za pomocą polecenia CREATE TABLE. Jego argumentem jest lista par: nazwa atrybutu i jego typ. Nazwy atrybutów są "nagłówkami" w tabeli, w której zapisujemy dane. Atrybut można dodatkowo ustanowić kluczem głównym tabeli, można też zastrzec, że nie może on mieć niezdefiniowanej wartości (domyślnie może).
Zasada zamiany diagramu związków encji na zestaw definicji tabel jest następująca:
· Każdemu zbiorowi encji diagramu (prostokątne pudełko) odpowiada jedna tabela o atrybutach równych wyróżnionym własnościom encji. Typy atrybutów zazwyczaj są jasne. Na ogół warto zadbać,by w tabeli był atrybut będący kluczem głównym (czasami może zajść potrzeba dodania takiego atrybutu).
· Związek jednoznaczny na ogół wyrażany jest w postaci klucza obcego.
· Związek wieloznaczny wyrażany jest w postaci odrębnej tabeli odwóch kluczach obcych wskazujących na obie związane encje. W takiej tabeli nie występuje pojedynczy atrybut będący kluczem głównym. Kluczem głównym jest para kluczy obcych.
· W przypadku związku jedno-jednoznacznego należy zastanowić się, czy warto utrzymywać dwie odrębne tabele. Powodem do takiej decyzji może być chęć dopuszczenia, że poszczególne encje nie są związane z niczym, może być też silne przekonanie, że są to encje ważne i odrębne i nie chcemy mieszać ich w jednej tabeli.
Jeśli definicje tabel odpowiadających diagramowi zawarte są w pliku - powiedzmy o nazwie "tabele.sql", to plik ten należy przetworzyć w trybie "wsadowym". Oznacza to, że np. używając interfejsu znakowego psql, należy wywołać instrukcję "\i tabele.sql" (zakładamy, że jest on dostępny w bieżącym katalogu na naszym dysku).
o Pierwszy przykład - "Faktury"
Jako pierwszy przykład, ilustrujący zamianę diagramu związków encji na definicje tabel, rozważmy problem reprezentacji w bazie faktur. W omówionym wcześniej diagramie mamy do czynienia z dwoma zbiorami encji - reprezentującymi odpowiednio: nagłówki oraz pozycje faktur. Pomiędzy tymi zbiorami zachodzi związek jednoznaczny "bycia pozycją faktury". Odzwierciedla on fakt, że każda faktura ma jeden i tylko jeden nagłówek (zawierający między innymi jej numer) oraz pewną liczbę pozycji. Każda pozycja (odpowiadająca faktowi nabycia danego towaru lub usługi) jest z kolei jednoznacznie przyporządkowana do konkretnego nagłówka.
Związek "bycia pozycją" reprezentujemy za pomocą klucza obcego w tabeli odpowiadającej zbiorowi encji "pozycje". Definicje stosownych tabel zawarte są w pliku F-tabele.sql.
SET client_encoding='utf-8';
-- W taki sposĂłb piszemy komentarz
-- a teraz definicje tabel
CREATE TABLE naglowek
(
numer int PRIMARY KEY,
imie varchar(32) not null,
nazwisko varchar(32) not null,
adres varchar(100) not null,
data date
);
CREATE TABLE pozycja
numer int not null,
nazwa varchar(32) not null,
cena int not null,
ilosc int not null,
nr_fakt int REFERENCES naglowek(numer)
ON DELETE CASCADE
Naturalnym wydaje się założenie, że w momencie, gdy zechcemy usunąć z bazy nagłówek jakiejś faktury, to automatycznie usunięciu powinny ulec wszystkie pozycje na niej występujące. Temu właśnie celowi służy klauzula "ON DELETE CASCADE" skojarzona z atrybutem "nr_fakt" w tabeli "pozycje".
Aby wczytać definicje zawarte w pliku "F-tabele.sql" za pomocą narzędzia psql, należy wydać polecenie "\i F-tabele.sql". Oczywiście plik "F-tabele.sql" musi być dostępny na dysku w bieżącym katalogu.
o Dane dla przykładu "Faktury"
Po zdefiniowaniu tabel należy wypełnić je treścią. W "prawdziwej" bazie danych będzie to oczywiście dokonywane stopniowo, w trakcie jej używania. Dla naszych celów, gdy bazy chcemy używać w celach testowych i dydaktycznych, nie będzie żadnych "prawdziwych" danych - trzeba je wprowadzić sztucznie w rozsądnej liczbie. Używamy w tym celu operacji INSERT. Dla naszego przykładu Faktur przykładowe dane zawarte są w pliku F-dane.sql.
INSERT INTO naglowek VALUES (1,'Jan','Kowalski','ul. Dudka 5, Sopot','2008-04-01');
INSERT INTO pozycja VALUES (1,'narty',120,1,1);
INSERT INTO pozycja VALUES (2,'czapka',23,1,1);
INSERT INTO pozycja VALUES (3,'rękawiczki',45,2,1);
INSERT INTO naglowek VALUES (2,'Grzegorz','Trek','ul Mały Dwór 12/3, Gdynia','2008-03-28');
INSERT INTO pozycja VALUES (1,'namiot',250,1,2);
INSERT INTO pozycja VALUES (2,'czapka',23,3,2);
INSERT INTO pozycja VALUES (3,'rękawiczki',45,2,2);
Tak jak poprzednio (w wypadku definicji tabel) plik ten należy załadować w trybie wsadowym. Np. używając narzędzia znakowego psql, należy wywołać instrukcję "\i F-dane.sql". Oczywiście, jak już mówiliśmy, plik ten musi być dostępny na naszym dysku.
Po załadowaniu danych do bazy wyświetl zawartość tabeli "pozycja". W tym celu, używając programu psql wydaj polecenie:
SELECT * FROM pozycja;
W odpowiedzi otrzymasz listę wszystkich znajdujących się w bazie pozycji fakturowych. Spróbuj teraz usunąć któryś z nagłówków faktur – używając narzędzia psql wykonaj polecenie:
DELETE FROM naglowek WHERE nr_fakt=1;
Następnie sprawdź efekt wykonując ponownie polecenie
Czy widzisz efekt zastosowania w definicji tabeli "pozycja" klauzuli "ON DELETE CASCADE"?
o Definicje tabel dla przykładu "Szkoła Wyższa"
Definicje tabel odpowiadające diagramowi związków encji opisującemu "Szkołę Wyższą" znajdują się w pliku SW-tabele.sql.
-- definicje tabel odpowiadajÄ…cych zbiorom encji nauczyciel i student
CREATE TABLE nauczyciel
nr_leg char(7) PRIMARY KEY,
nazwisko varchar(32) not null
CREATE TABLE student
nr_ind char(7) PRIMARY KEY,
-- Ĺ‚Ä…czymy encje przedmiot i termin
-- w diagramie był to związek jednojednoznaczny
-- pomiędzy dwoma zbiorami encji
CREATE TABLE przedmiot_termin
kod serial PRIMARY KEY,
rodzaj varchar(20) not null,
nazwa varchar(50) not null,
godziny int not null,
-- nr legitymacji nauczyciela prowadzÄ…cego
nr_leg char(7) not null,
-- teraz atrybuty terminu
dzien_tyg int ,
godzina int ,
sala varchar(5) ,
-- atrybuty encji termin muszą być unikatowe w ramach tej tabeli
CONSTRAINT przedmiot_un UNIQUE(dzien_tyg,godzina,sala),
-- klucz obcy - powiÄ…zanie przedmiotu z nauczycielem
CONSTRAINT przedmiot_fk FOREIGN KEY(nr_leg)
REFERENCES nauczyciel(nr_leg)
-- poniższa tabela jest realizacją związku między
-- zbiorami encji przedmioty i student
CREATE TABLE jest_sluchaczem
nr_ind char(7) ,
kod int ,
CONSTRAINT jest_sluchaczem_nr_ind_fk FOREIGN KEY(nr_ind)
REFERENCES student(nr_ind)
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT jest_sluchaczem_kod_fk FOREIGN KEY(kod)
REFERENCES przedmiot_termin(kod)
ON UPDATE CASCADE ON DELETE CASCADE
Aby je wczytać za pomocą narzędzia psql należy wydać polecenie "\i SW-tabele.sql".
o Dane dla przykładu "Szkoła Wyższa"
Przykładowe dane dla naszego przykładu Szkoły Wyższej zawarte są w pliku SW-dane.sql.
-- wypełnienie tabeli nauczyciel
INSERT INTO nauczyciel (nr_leg, imie, nazwisko)
VALUES ('L 00001', 'Jan', 'Kowalski');
VALUES ('L 00002', 'Michał', 'Michalski');
VALUES ('L 00003', 'Anna', 'Nowak');
VALUES ('L 00004', 'Zuzanna', 'PrzepiĂłrkowska');
VALUES ('L 00005', 'Eleonora', 'Plichta');
-- wypełnienie tabeli student
INSERT INTO student (nr_ind, imie, nazwisko)
VALUES ('S 00001', 'Aleksander', 'Cyra');
VALUES ('S 00002', 'Hermenegilda', 'Kociubińska');
VALUES ('S 00003', 'Krzysztof', 'Kulikowski');
VALUES ('S 00004', 'Jerzy', 'Samp');
VALUES ('S 00005', 'Bronisław', 'Wstęp');
-- wypełnienie tabeli przedmiot_termin
INSERT INTO przedmiot_termin (rodzaj, nazwa, godziny, nr_leg,
dzien_tyg, godzina, sala)
VALUES ('wyklad', 'Matematyka', 2, 'L 00004', 1, 10, 'DB25');
VALUES ('wyklad', 'Programowanie', 2, 'L 00002', 2, 8, 'UN109');
VALUES ('laboratorium', 'Programowanie', 2, 'L 00001', 3, 12, 'DB37A');
VALUES ('ćwiczenia', 'Matematyka', 2, 'L 00004', 2, 12, 'DB31');
VALUES ('wykład', 'Filozofia', 2, 'L 00003', 4, 13, 'UN109');
-- wypełnienie tabeli jest_sluchaczem kodującej związek studenta i przedmiotu
INSERT INTO jest_sluchaczem (nr_ind, kod) VALUES ('S 00001', 1);
INSERT INTO jest_sluchaczem (nr_ind, kod) VALUES ('S 00001', 4);
INSERT INTO jest_sluchaczem (nr_ind, kod) VALUES ('S 00001', 2);
INSERT INTO jest_sluchaczem (nr_ind, kod) VALUES ('S 00001', 3);
INSERT INTO jest_sluchaczem (nr_ind, kod) VALUES ('S 00002', 5);
INSERT INTO jest_sluchaczem (nr_ind, kod) VALUES ('S 00003', 3);
INSERT INTO jest_sluchaczem (nr_ind, kod) VALUES ('S 00003', 4);
INSERT INTO jest_sluchaczem (nr_ind, kod) VALUES ('S 00004', 1);
INSERT INTO jest_sluchaczem (nr_ind, kod) VALUES ('S 00004', 5);
INSERT INTO jest_sluchaczem (nr_ind, kod) VALUES ('S 00005', 3);
Plik ten należy załadować w trybie wsadowym. Np. używając terminala znakowego psql, należy wywołać instrukcję "\i SW-dane.sql".
W bazie danych dotyczącej szkoły wyższej z poprzedniego przykładu próbujemy wykonać komendy znajdujące się w pliku SW-fail.sql.
VALUES ('wyklad', 'Socjologia', 2, 'L 00004', 1, 10, 'DB25');
VALUES ('wyklad', 'Prawo', 2, 'L 00006', 5, 11, 'DB42');
INSERT INTO jest_sluchaczem (nr_ind, kod) VALUES ('S 00001', 6);
DROP TABLE student;
DROP TABLE nauczyciel;
DELETE FROM nauczyciel WHERE nr_leg='L 00001';
DROP TABLE jest_sluchaczem;
Wyjaśnij działanie poszczególnych komend, nawet gdy próba ich wykonania kończy się niepowodzeniem.
W przypadku błędów i konieczności rozpoczęcia pracy od nowa należy użyć instrukcji SQL postaci DROP TABLE nazwa, być może we wzmocnionej wersji DROP TABLE nazwa CASCADE. Usuwanie tabel można łatwo wykonać przy pomocy narzędzi graficznych: programu pgadmin3 i przeglądarki. W pliku SW-tabele_drop.sql znajdują się komendy usuwające poszczególne tabele z bazy. Zwróć uwagę na kolejność usuwania tabel. Czy kolejność ta może być dowolna?
-- usuwanie wszystkich tabel przykłady ze szkołą wyższą
DROP TABLE przedmiot_termin;
-- UWAGA: kolejność usuwania tabel jest ważna. Dlaczego?
o inne definicje tabel dla przykładu "Szkoła Wyższa"
W pliku SW2-tabele.sql znajduje się inna realizacja diagramu związków encji niż w punkcie: Dane dla przykładu "Szkoła Wyższa".
CONSTRAINT nauczyciel_pk PRIMARY KEY(nr_leg)
nr_ind char(7) not null,
CONSTRAINT student_pk PRIMARY KEY(nr_ind)
CREATE TABLE przedmiot
kod char(6) ,
ile_godzin int not null,
-- nr legitymacji nauczyciela prowadzacego
CONSTRAINT przedmiot_pk PRIMARY KEY(kod),
-- klucz obcy - powiazanie przedmiotu z nauczycielem
REFERENCES nauczyciel(nr_leg)...
beziak