Library management system data model
This example models a public library: the catalog of books, their authors and publishers, the physical copies held at each branch, library members, loans, holds and fines. It's a classic teaching example for entity-relationship modeling because it has a clear many-to-many relationship and the book-versus-copy distinction.
Design notes
- A book is not a copy.
bookis the title in the catalog (ISBN, title, publisher);book_copyis a physical item with a barcode at one branch. Loans are of copies; holds are on books, because a member wants any available copy. - Books and authors are many-to-many.
book_authorresolves it and keeps the order authors are credited in. - Loans keep their history.
returned_onis empty while a copy is out, so overdue loans are those pastdue_onwith no return date. - Membership type is a reference list with its loan limit, so rules live in data rather than code.
- Fines belong to loans, which ties every charge to the item and member involved.
To extend it: add reservation_queue positions, digital_item for e-books, event for library programs, or inter_library_loan.
Diagram
Library Management System: 10 entities, 3 reference lists and 11 relationships. Each box is an entity with its attributes (PK marks the primary key); solid lines are relationships in crow's foot notation, dashed lines point to reference lists.
Open this model in EntityModel.com to explore it, change it and export it. Nothing is uploaded: the model travels in the link. Or download model.json.
Entities
| Entity | Type | Description | Primary Key | Display Attribute | Attributes |
|---|---|---|---|---|---|
| Author | Entity | A person who wrote or edited books. | author_id | author_name | 3 |
| Book | Entity | A title in the catalog. Physical copies are separate. | book_id | title | 7 |
| Book Author | Entity | Links books to their authors, in credit order. | book_id | author_order | 3 |
| Branch | Entity | A library location that holds copies. | branch_id | branch_name | 4 |
| Copy | Entity | A physical copy of a book, with its own barcode, kept at one branch. | copy_id | barcode | 6 |
| Fine | Entity | A charge for a late or lost item. | fine_id | amount | 5 |
| Hold | Entity | A member's request to borrow a book when a copy becomes available. | hold_id | placed_at | 6 |
| Loan | Entity | A copy checked out to a member. | loan_id | loaned_on | 7 |
| Member | Entity | A person with a library card. | member_id | full_name | 7 |
| Publisher | Entity | A publishing house. | publisher_id | publisher_name | 2 |
| Genre | Reference | Subject classification for books. | genre_code | genre_name | 2 |
| Language | Reference | Languages, by ISO 639-1 code. | language_code | language_name | 2 |
| Membership Type | Reference | Kinds of library card, with their loan limits. | type_code | type_name | 3 |
Attributes
Author
A person who wrote or edited books.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| author_id | INT | PK, Required | 210 | ||
| author_name | STRING | Label, Required | Thomas H. Cormen | ||
| birth_year | INT | 1956 |
Book
A title in the catalog. Physical copies are separate.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| book_id | INT | PK, Required | 4410 | ||
| isbn | STRING | Required | 9780262033848 | ISBN-13. | |
| title | STRING | Label, Required | Introduction to Algorithms | ||
| publisher_id | INT | 17 | |||
| publication_year | INT | 2009 | |||
| language_code | REFERENCE | Required | → language.language_code | en | |
| genre_code | REFERENCE | → genre.genre_code | CS |
Book Author
Links books to their authors, in credit order.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| book_id | INT | PK, Required | 4410 | ||
| author_id | INT | PK, Required | 210 | ||
| author_order | INT | Label, Required | 1 | Position in the author list. |
Branch
A library location that holds copies.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| branch_id | INT | PK, Required | 3 | ||
| branch_name | STRING | Label, Required | Central Library | ||
| address | STRING | Required | 801 SW 10th Ave | ||
| phone | STRING | +1 555 0170 |
Copy
A physical copy of a book, with its own barcode, kept at one branch.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| copy_id | BIGINT | PK, Required | 1004410 | ||
| barcode | STRING | Label, Required | 31234001004410 | ||
| book_id | INT | Required | 4410 | ||
| branch_id | INT | Required | 3 | ||
| condition | STRING | Good | |||
| is_available | BOOLEAN | Required | true | Not on loan or held. |
Fine
A charge for a late or lost item.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| fine_id | BIGINT | PK, Required | 7701 | ||
| loan_id | BIGINT | Required | 902211 | ||
| amount | DECIMAL(12,2) | Label, Required | 2.50 | ||
| reason | STRING | Required | Overdue | ||
| paid_on | DATE |
Hold
A member's request to borrow a book when a copy becomes available.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| hold_id | BIGINT | PK, Required | 33019 | ||
| book_id | INT | Required | 4410 | ||
| member_id | INT | Required | 56002 | ||
| pickup_branch_id | INT | Required | 3 | ||
| placed_at | TIMESTAMP | Label, Required | 2026-10-28T12:00:00Z | ||
| status | STRING | Required | WAITING | Waiting, ready, fulfilled or cancelled. |
Loan
A copy checked out to a member.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| loan_id | BIGINT | PK, Required | 902211 | ||
| copy_id | BIGINT | Required | 1004410 | ||
| member_id | INT | Required | 56002 | ||
| loaned_on | DATE | Label, Required | 2026-10-20 | ||
| due_on | DATE | Required | 2026-11-10 | ||
| returned_on | DATE | Empty while on loan. | |||
| renewal_count | INT | Required | 0 |
Member
A person with a library card.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| member_id | INT | PK, Required | 56002 | ||
| card_number | STRING | Required, PII | 2900156002 | ||
| full_name | STRING | Label, Required, PII | Lee Chen | ||
| STRING | PII | lee.chen@example.com | |||
| membership_type_code | REFERENCE | Required | → membership_type.type_code | ADULT | |
| joined_on | DATE | Required | 2024-06-11 | ||
| expires_on | DATE | Required | 2027-06-11 |
Publisher
A publishing house.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| publisher_id | INT | PK, Required | 17 | ||
| publisher_name | STRING | Label, Required | MIT Press |
Genre
Subject classification for books.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| genre_code | STRING | PK, Required | CS | ||
| genre_name | STRING | Label, Required | Computer science |
Language
Languages, by ISO 639-1 code.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| language_code | STRING | PK, Required | en | ||
| language_name | STRING | Label, Required | English |
Membership Type
Kinds of library card, with their loan limits.
| Attribute | Data Type | Flags | Reference | Example | Description |
|---|---|---|---|---|---|
| type_code | STRING | PK, Required | ADULT | ||
| type_name | STRING | Label, Required | Adult | ||
| max_loans | INT | Required | 20 |
Relationships
| Relationship | Source | Target | Cardinality | Forward Label | Reverse Label | Key | Description |
|---|---|---|---|---|---|---|---|
| published_by | Book | Publisher | N:1 | Published By | Publishes | book.publisher_id | |
| credits_book | Book Author | Book | N:1 | Credits | Credited In | book_author.book_id | Books and authors are many-to-many; book_author resolves it and keeps the credit order. |
| credits_author | Book Author | Author | N:1 | Credits | Credited In | book_author.author_id | |
| copy_of | Copy | Book | N:1 | Copy Of | Has Copy | book_copy.book_id | |
| kept_at | Copy | Branch | N:1 | Kept At | Holds | book_copy.branch_id | |
| loan_of | Loan | Copy | N:1 | Of | Loaned In | loan.copy_id | |
| borrowed_by | Loan | Member | N:1 | Borrowed By | Borrows | loan.member_id | |
| hold_on | Hold | Book | N:1 | On | Has Hold | hold.book_id | Holds are on the title, not a specific copy. |
| placed_by | Hold | Member | N:1 | Placed By | Places | hold.member_id | |
| pickup_at | Hold | Branch | N:1 | Pick Up At | Pickup Point For | hold.pickup_branch_id | |
| charged_for | Fine | Loan | N:1 | Charged For | Incurs | fine.loan_id |
Reference data
Genre
6 values · Source: Example values
| genre_code | genre_name |
|---|---|
| FIC | Fiction |
| MYS | Mystery |
| SCI | Science |
| CS | Computer science |
| HIST | History |
| CHILD | Children |
Language
5 values · Source: ISO 639-1 (excerpt)
| language_code | language_name |
|---|---|
| en | English |
| es | Spanish |
| fr | French |
| de | German |
| zh | Chinese |
Membership Type
4 values · Source: Example values
| type_code | type_name | max_loans |
|---|---|---|
| ADULT | Adult | 20 |
| CHILD | Child | 10 |
| STUDENT | Student | 25 |
| SENIOR | Senior | 20 |
SQL DDL (PostgreSQL)
Generated from the model. In the app, Export → Code also writes MySQL, Snowflake and Databricks DDL, DBML, dbt schema.yml and data contracts.
-- Library Management System — data model
-- PostgreSQL DDL, generated 2026-11-03
-- Made with EntityModel.com
-- Reference list: Genre
CREATE TABLE genre (
genre_code TEXT NOT NULL,
genre_name TEXT NOT NULL,
PRIMARY KEY (genre_code)
);
COMMENT ON TABLE genre IS 'Subject classification for books.';
-- Reference list: Language
CREATE TABLE language (
language_code TEXT NOT NULL,
language_name TEXT NOT NULL,
PRIMARY KEY (language_code)
);
COMMENT ON TABLE language IS 'Languages, by ISO 639-1 code.';
-- Reference list: Membership Type
CREATE TABLE membership_type (
type_code TEXT NOT NULL,
type_name TEXT NOT NULL,
max_loans INTEGER NOT NULL,
PRIMARY KEY (type_code)
);
COMMENT ON TABLE membership_type IS 'Kinds of library card, with their loan limits.';
CREATE TABLE book (
book_id INTEGER NOT NULL,
isbn TEXT NOT NULL,
title TEXT NOT NULL,
publisher_id INTEGER,
publication_year INTEGER,
language_code TEXT NOT NULL,
genre_code TEXT,
PRIMARY KEY (book_id)
);
COMMENT ON TABLE book IS 'A title in the catalog. Physical copies are separate.';
COMMENT ON COLUMN book.isbn IS 'ISBN-13.';
CREATE TABLE author (
author_id INTEGER NOT NULL,
author_name TEXT NOT NULL,
birth_year INTEGER,
PRIMARY KEY (author_id)
);
COMMENT ON TABLE author IS 'A person who wrote or edited books.';
CREATE TABLE publisher (
publisher_id INTEGER NOT NULL,
publisher_name TEXT NOT NULL,
PRIMARY KEY (publisher_id)
);
COMMENT ON TABLE publisher IS 'A publishing house.';
CREATE TABLE library_branch (
branch_id INTEGER NOT NULL,
branch_name TEXT NOT NULL,
address TEXT NOT NULL,
phone TEXT,
PRIMARY KEY (branch_id)
);
COMMENT ON TABLE library_branch IS 'A library location that holds copies.';
CREATE TABLE book_copy (
copy_id BIGINT NOT NULL,
barcode TEXT NOT NULL,
book_id INTEGER NOT NULL,
branch_id INTEGER NOT NULL,
condition TEXT,
is_available BOOLEAN NOT NULL,
PRIMARY KEY (copy_id)
);
COMMENT ON TABLE book_copy IS 'A physical copy of a book, with its own barcode, kept at one branch.';
COMMENT ON COLUMN book_copy.is_available IS 'Not on loan or held.';
CREATE TABLE member (
member_id INTEGER NOT NULL,
card_number TEXT NOT NULL,
full_name TEXT NOT NULL,
email TEXT,
membership_type_code TEXT NOT NULL,
joined_on DATE NOT NULL,
expires_on DATE NOT NULL,
PRIMARY KEY (member_id)
);
COMMENT ON TABLE member IS 'A person with a library card.';
CREATE TABLE loan (
loan_id BIGINT NOT NULL,
copy_id BIGINT NOT NULL,
member_id INTEGER NOT NULL,
loaned_on DATE NOT NULL,
due_on DATE NOT NULL,
returned_on DATE,
renewal_count INTEGER NOT NULL,
PRIMARY KEY (loan_id)
);
COMMENT ON TABLE loan IS 'A copy checked out to a member.';
COMMENT ON COLUMN loan.returned_on IS 'Empty while on loan.';
CREATE TABLE hold (
hold_id BIGINT NOT NULL,
book_id INTEGER NOT NULL,
member_id INTEGER NOT NULL,
pickup_branch_id INTEGER NOT NULL,
placed_at TIMESTAMP NOT NULL,
status TEXT NOT NULL,
PRIMARY KEY (hold_id)
);
COMMENT ON TABLE hold IS 'A member''s request to borrow a book when a copy becomes available.';
COMMENT ON COLUMN hold.status IS 'Waiting, ready, fulfilled or cancelled.';
CREATE TABLE fine (
fine_id BIGINT NOT NULL,
loan_id BIGINT NOT NULL,
amount NUMERIC(12,2) NOT NULL,
reason TEXT NOT NULL,
paid_on DATE,
PRIMARY KEY (fine_id)
);
COMMENT ON TABLE fine IS 'A charge for a late or lost item.';
CREATE TABLE book_author (
book_id INTEGER NOT NULL,
author_id INTEGER NOT NULL,
author_order INTEGER NOT NULL,
PRIMARY KEY (book_id, author_id)
);
COMMENT ON TABLE book_author IS 'Links books to their authors, in credit order.';
COMMENT ON COLUMN book_author.author_order IS 'Position in the author list.';
-- Keys between tables
ALTER TABLE book ADD CONSTRAINT uq_book_isbn UNIQUE (isbn);
ALTER TABLE book_copy ADD CONSTRAINT uq_book_copy_barcode UNIQUE (barcode);
ALTER TABLE member ADD CONSTRAINT uq_member_card_number UNIQUE (card_number);
ALTER TABLE book ADD CONSTRAINT fk_book_language_code FOREIGN KEY (language_code) REFERENCES language (language_code);
ALTER TABLE book ADD CONSTRAINT fk_book_genre_code FOREIGN KEY (genre_code) REFERENCES genre (genre_code);
ALTER TABLE member ADD CONSTRAINT fk_member_membership_type_code FOREIGN KEY (membership_type_code) REFERENCES membership_type (type_code);
ALTER TABLE book ADD CONSTRAINT fk_published_by FOREIGN KEY (publisher_id) REFERENCES publisher (publisher_id);
ALTER TABLE book_author ADD CONSTRAINT fk_credits_book FOREIGN KEY (book_id) REFERENCES book (book_id);
ALTER TABLE book_author ADD CONSTRAINT fk_credits_author FOREIGN KEY (author_id) REFERENCES author (author_id);
ALTER TABLE book_copy ADD CONSTRAINT fk_copy_of FOREIGN KEY (book_id) REFERENCES book (book_id);
ALTER TABLE book_copy ADD CONSTRAINT fk_kept_at FOREIGN KEY (branch_id) REFERENCES library_branch (branch_id);
ALTER TABLE loan ADD CONSTRAINT fk_loan_of FOREIGN KEY (copy_id) REFERENCES book_copy (copy_id);
ALTER TABLE loan ADD CONSTRAINT fk_borrowed_by FOREIGN KEY (member_id) REFERENCES member (member_id);
ALTER TABLE hold ADD CONSTRAINT fk_hold_on FOREIGN KEY (book_id) REFERENCES book (book_id);
ALTER TABLE hold ADD CONSTRAINT fk_placed_by FOREIGN KEY (member_id) REFERENCES member (member_id);
ALTER TABLE hold ADD CONSTRAINT fk_pickup_at FOREIGN KEY (pickup_branch_id) REFERENCES library_branch (branch_id);
ALTER TABLE fine ADD CONSTRAINT fk_charged_for FOREIGN KEY (loan_id) REFERENCES loan (loan_id);
-- Reference values
INSERT INTO genre (genre_code, genre_name) VALUES
('FIC', 'Fiction'),
('MYS', 'Mystery'),
('SCI', 'Science'),
('CS', 'Computer science'),
('HIST', 'History'),
('CHILD', 'Children');
INSERT INTO language (language_code, language_name) VALUES
('en', 'English'),
('es', 'Spanish'),
('fr', 'French'),
('de', 'German'),
('zh', 'Chinese');
INSERT INTO membership_type (type_code, type_name, max_loans) VALUES
('ADULT', 'Adult', 20),
('CHILD', 'Child', 10),
('STUDENT', 'Student', 25),
('SENIOR', 'Senior', 20);
Mermaid
Paste into a mermaid code block on GitHub, GitLab or Notion to show the diagram there.
---
title: Library Management System
---
%% Made with EntityModel.com
erDiagram
book {
int book_id PK "Book ID"
string isbn "ISBN-13."
string title "Title"
int publisher_id FK "Publisher ID"
int publication_year "Publication Year"
string language_code FK "Language Code"
string genre_code FK "Genre Code"
}
author {
int author_id PK "Author ID"
string author_name "Author Name"
int birth_year "Birth Year"
}
publisher {
int publisher_id PK "Publisher ID"
string publisher_name "Publisher Name"
}
library_branch {
int branch_id PK "Branch ID"
string branch_name "Branch Name"
string address "Address"
string phone "Phone"
}
book_copy {
bigint copy_id PK "Copy ID"
string barcode "Barcode"
int book_id FK "Book ID"
int branch_id FK "Branch ID"
string condition "Condition"
boolean is_available "Not on loan or held."
}
member {
int member_id PK "Member ID"
string card_number "Card Number"
string full_name "Full Name"
string email "Email"
string membership_type_code FK "Membership Type Code"
date joined_on "Joined On"
date expires_on "Expires On"
}
loan {
bigint loan_id PK "Loan ID"
bigint copy_id FK "Copy ID"
int member_id FK "Member ID"
date loaned_on "Loaned On"
date due_on "Due On"
date returned_on "Empty while on loan."
int renewal_count "Renewal Count"
}
hold {
bigint hold_id PK "Hold ID"
int book_id FK "Book ID"
int member_id FK "Member ID"
int pickup_branch_id FK "Pickup Branch ID"
timestamp placed_at "Placed At"
string status "Waiting, ready, fulfilled or cancelled."
}
fine {
bigint fine_id PK "Fine ID"
bigint loan_id FK "Loan ID"
decimal amount "Amount"
string reason "Reason"
date paid_on "Paid On"
}
book_author {
int book_id PK, FK "Book ID"
int author_id PK, FK "Author ID"
int author_order "Position in the author list."
}
genre {
string genre_code PK "Genre Code"
string genre_name "Genre Name"
}
language {
string language_code PK "Language Code"
string language_name "Language Name"
}
membership_type {
string type_code PK "Type Code"
string type_name "Type Name"
int max_loans "Max Loans"
}
book }o--|| publisher : "Published By"
book_author }o--|| book : "Credits"
book_author }o--|| author : "Credits"
book_copy }o--|| book : "Copy Of"
book_copy }o--|| library_branch : "Kept At"
loan }o--|| book_copy : "Of"
loan }o--|| member : "Borrowed By"
hold }o--|| book : "On"
hold }o--|| member : "Placed By"
hold }o--|| library_branch : "Pick Up At"
fine }o--|| loan : "Charged For"
book }o..|| language : "Language Code"
book }o..|| genre : "Genre Code"
member }o..|| membership_type : "Membership Type Code"
Frequently asked questions
What are the entities in a library management system?
Book, author, publisher, book copy, branch, member, loan, hold and fine, with lookup tables for genre, language and membership type. Book and author are linked many-to-many through a book_author table.
Why separate books from book copies?
A library owns several physical copies of the same title. Catalog details (title, ISBN, authors) belong to the book; barcode, location, condition and availability belong to each copy, and loans are recorded against copies.