Exemplos / Sistema de biblioteca
Sistema de biblioteca
O schema de uma biblioteca se apoia numa única separação. O livro é um título do catálogo, e o exemplar é o objeto físico na estante. Os sócios levam exemplares, não livros, mas as reservas são feitas no livro. Os autores se ligam por uma tabela associativa, porque há livros com vários autores.
Abaixo, o ErdDocs desenha este schema a partir do SQL, com todas as tabelas e relacionamentos. Na aba «Dicionário de dados» está a versão para imprimir, completa e grátis nesta página. O SQL fica mais abaixo.
Passe o mouse sobre uma tabela para destacar os relacionamentos e clique para fixá-los.
O que cada tabela faz
- books / copiesO registro do catálogo e o exemplar com código de barras. A maioria dos exercícios de biblioteca se resume a essa separação.
- authors / book_authorsMuitos para muitos. Um livro com dois autores quebra na hora um author_id direto.
- membersAs pessoas usam o número da carteirinha, card_no.
- loansO empréstimo se liga ao exemplar, porque é preciso saber qual objeto físico está fora e atrasado.
- reservationsA reserva se liga ao livro. O sócio quer o título, qualquer que seja o exemplar que voltar primeiro.
Decisões de modelagem que vale copiar
- Empréstimos apontam para exemplares e reservas para livros. Misturar os dois níveis é o erro clássico. Aí o schema não responde «quem está com este exemplar» nem «quem avisar em seguida».
- returned_on aceita nulo. Faz o papel de um indicador «devolvido» e ainda guarda a data na mesma coluna.
- O ISBN é único, mas aceita nulo. Existe material antigo e interno sem ISBN, e com NOT NULL esses dados reais violariam a restrição.
O SQL
Dialeto PostgreSQL. Este SQL já está na ferramenta acima, e você pode copiá-lo à vontade para o seu banco ou para uma migration.
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 para material anterior ao ISBN ou interno';
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 'O objeto físico; um livro popular tem vários exemplares';
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 enquanto o exemplar está emprestado';
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 'A reserva é no LIVRO: qualquer exemplar devolvido a atende';Perguntas frequentes
Onde ficam as multas?
Numa tabela fines que referencia loans, porque a multa vem de um empréstimo atrasado. Ela guarda o valor, a data e a data de pagamento. Para um trabalho de faculdade, também serve calcular na hora a partir da data de devolução. O importante é explicar qual você escolheu e por quê.
Como e-books mudam o schema?
E-book não tem exemplar, então o empréstimo vira uma questão de licença. Dá para criar uma tabela licenses paralela a copies, com o número de empréstimos simultâneos. Ou dá para emprestar o livro direto e controlar a concorrência na aplicação.