Przykłady / System biblioteczny
System biblioteczny
Schemat biblioteki opiera się na jednym rozróżnieniu. Książka to tytuł w katalogu, a egzemplarz to fizyczny tom na półce. Czytelnicy wypożyczają egzemplarze, nie książki, ale rezerwacja dotyczy książki. Autorzy są dołączeni przez tabelę pośrednią, bo książka może mieć kilku autorów.
Poniżej ErdDocs rysuje ten schemat z jego SQL, ze wszystkimi tabelami i relacjami. W karcie „Słownik danych” znajdziesz wersję do druku, w całości i za darmo na tej stronie. SQL jest jeszcze niżej.
Najedź na tabelę, żeby podświetlić jej relacje, i kliknij, żeby je przypiąć.
Do czego służy każda tabela
- books / copiesPozycja katalogu i egzemplarz z kodem kreskowym. Większość zadań o bibliotece sprowadza się do tego rozróżnienia.
- authors / book_authorsRelacja wiele do wielu. Książka z dwoma autorami od razu psuje bezpośrednie author_id.
- membersLudzie posługują się numerem karty czytelnika, card_no.
- loansWypożyczenie jest przypięte do egzemplarza, bo trzeba wiedzieć, który dokładnie tom jest wypożyczony i przetrzymany.
- reservationsRezerwacja jest przypięta do książki. Czytelnik chce tytułu i nieważne, który egzemplarz wróci pierwszy.
Decyzje projektowe warte przejęcia
- Wypożyczenia wskazują egzemplarze, a rezerwacje książki. Pomieszanie tych dwóch poziomów to klasyczny błąd. Wtedy schemat nie odpowie ani na pytanie „kto ma ten właśnie tom”, ani „kogo powiadomić jako następnego”.
- returned_on dopuszcza NULL. Zastępuje to flagę „zwrócono”, a data jest w tej samej kolumnie.
- ISBN jest unikalny, ale dopuszcza NULL. Stare i wewnętrzne wydania bez ISBN naprawdę istnieją. Przy NOT NULL prawdziwe dane naruszałyby ograniczenie.
SQL
Dialekt PostgreSQL. Ten SQL jest już wklejony w narzędzie powyżej. Możesz go swobodnie skopiować do swojej bazy albo do migracji.
CREATE TABLE authors (
id bigserial PRIMARY KEY,
full_name varchar(120) NOT NULL
);
CREATE TABLE books (
id bigserial PRIMARY KEY,
isbn varchar(17) UNIQUE,
title varchar(240) NOT NULL,
published smallint
);
COMMENT ON COLUMN books.isbn IS 'NULL dla wydań sprzed ISBN i materiałów wewnętrznych';
CREATE TABLE book_authors (
book_id bigint NOT NULL REFERENCES books(id),
author_id bigint NOT NULL REFERENCES authors(id),
PRIMARY KEY (book_id, author_id)
);
CREATE TABLE copies (
id bigserial PRIMARY KEY,
book_id bigint NOT NULL REFERENCES books(id),
barcode varchar(20) NOT NULL UNIQUE,
shelf varchar(20),
condition varchar(20) NOT NULL DEFAULT 'good'
);
COMMENT ON TABLE copies IS 'Fizyczny tom; popularna książka ma wiele egzemplarzy';
CREATE TABLE members (
id bigserial PRIMARY KEY,
card_no varchar(20) NOT NULL UNIQUE,
full_name varchar(120) NOT NULL,
joined_on date NOT NULL
);
CREATE TABLE loans (
id bigserial PRIMARY KEY,
copy_id bigint NOT NULL REFERENCES copies(id),
member_id bigint NOT NULL REFERENCES members(id),
loaned_on date NOT NULL,
due_on date NOT NULL,
returned_on date
);
COMMENT ON COLUMN loans.returned_on IS 'NULL, dopóki egzemplarz jest wypożyczony';
CREATE TABLE reservations (
id bigserial PRIMARY KEY,
book_id bigint NOT NULL REFERENCES books(id),
member_id bigint NOT NULL REFERENCES members(id),
placed_at timestamptz NOT NULL DEFAULT now(),
fulfilled boolean NOT NULL DEFAULT false
);
COMMENT ON TABLE reservations IS 'Rezerwacja na KSIĄŻKĘ – zaspokoi ją każdy zwrócony egzemplarz';Najczęstsze pytania
Gdzie umieścić kary za przetrzymanie?
W tabeli fines z odwołaniem do loans, bo karę nalicza się za przetrzymane wypożyczenie. Tabela zawiera kwotę, datę naliczenia i datę zapłaty. W projekcie na zajęcia wystarczy też liczenie na bieżąco z terminu zwrotu. Ważne, żeby uzasadnić wybór.
Co zmieniają e-booki?
E-book nie ma egzemplarzy, więc wypożyczenie staje się kwestią licencji. Można dodać tabelę licenses obok copies, z liczbą jednoczesnych wypożyczeń. Można też przypinać wypożyczenia prosto do książki i sprawdzać ich liczbę w aplikacji.