Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions task-1/README.MD

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid Readme.md.

Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
📘 Task 1 — Library Database (3NF Normalization)
This folder contains all files required to set up and run the database for Task 1, including the schema, seed data, ER diagram, and Docker Compose configuration.

📌 1. ER Diagram
The ER diagram is included in the repository: library_er_diagram.png
It shows all tables and relationships in the normalized database.

📌 2. Running PostgreSQL (Docker)
A docker-compose.yml file is included to start PostgreSQL quickly.
Start the database:

```bash
docker compose up -d
```

Check that the container is running:

```bash
docker ps
```

Connection details:
- Host: localhost
- Port: 5432
- Database: library
- User: postgres
- Password: postgres

📌 3. Apply the Schema
Run the schema file to create all tables and constraints:

```bash
psql -h localhost -p 5432 -U postgres -d library -f schema.sql
```

📌 4. Insert Seed Data
Load the initial dataset:

```bash
psql -h localhost -p 5432 -U postgres -d library -f seed.sql
```

This inserts:
- members
- cards
- publishers
- authors
- tags
- books
- shelves
- copies
- borrows
Sequences are synchronized using setval.

📌 5. Tables Included
- members
- cards
- publishers
- authors
- tags
- books
- shelves
- copies
- borrows
- book_authors (N:M)
- book_tags (N:M)

📌 6. Relationship Types
1:1 — members ↔ cards
1:N — publishers → books
1:N — books → copies
1:N — members → borrows
N:M — books ↔ authors
N:M — books ↔ tags

📌 7. Constraints
PRIMARY KEY on every table
FOREIGN KEY relationships
UNIQUE constraints (email, ISBN, barcode, tag name, etc.)
CHECK constraints (fine ≥ 0, valid dates, etc.)

📌 8. Notes
The schema and seed data are ready to be used in Task 2 (Java JDBC).
The ER diagram reflects the final normalized structure.
The database can be recreated at any time using the steps above.
18 changes: 18 additions & 0 deletions task-1/docker-compose.yml

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bonus points for this docker compose file. It helps a lot to be able to validate the work in this PR.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: '3.9'

services:
postgres:
image: postgres:16
container_name: library-db
restart: unless-stopped
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: library
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data

volumes:
postgres_data:
Binary file added task-1/library_er_diagram.png

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DBeaver is a very good tool choice.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 0 additions & 101 deletions task-1/library_loans.csv

This file was deleted.

126 changes: 125 additions & 1 deletion task-1/schema.sql
Original file line number Diff line number Diff line change
@@ -1 +1,125 @@
-- Write here your DDL statements to create the tables for the database.
-- Write here your DDL statements to create the tables for the database.




-

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This - makes that some tables are missing after running this script due to a syntax error. Deleting the - fixed the problem, so not really a big deal. Running it second time was a bit of a challenge using CREATE TABLE IF NOT EXISTS to make the script a bit more idempotent.

CREATE TABLE cards
(
card_id SERIAL PRIMARY KEY,
card_number TEXT UNIQUE NOT NULL,
card_issued_on DATE NOT NULL,
card_expires_on DATE NOT NULL,
CHECK (card_expires_on > card_issued_on)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice date check!

);


CREATE TABLE members
(
member_id SERIAL PRIMARY KEY,
card_id INTEGER UNIQUE,
member_email TEXT UNIQUE NOT NULL,
member_name TEXT NOT NULL,
member_phone TEXT NOT NULL,
member_address TEXT NOT NULL,
CONSTRAINT fk_card_id
FOREIGN KEY (card_id)
REFERENCES cards (card_id) ON DELETE CASCADE

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should members whose card is deleted be deleted as well? Or is using ON DELETE SET NULL also an option?

);


CREATE TABLE publishers
(
publisher_id SERIAL PRIMARY KEY,
publisher_name TEXT UNIQUE NOT NULL
);


CREATE TABLE authors
(
author_id SERIAL PRIMARY KEY,
author_name TEXT NOT NULL
);


CREATE TABLE tags
(
tag_id SERIAL PRIMARY KEY,
tag_name VARCHAR(25) UNIQUE NOT NULL
);


CREATE TABLE books
(
book_id SERIAL PRIMARY KEY,
book_isbn VARCHAR(13) UNIQUE NOT NULL,
book_title TEXT NOT NULL,
publisher_id INTEGER NOT NULL,
CONSTRAINT fk_publisher_id
FOREIGN KEY(publisher_id)
REFERENCES publishers (publisher_id)
);


CREATE TABLE book_authors
(
book_id INTEGER NOT NULL,
author_id INTEGER NOT NULL,
PRIMARY KEY (book_id, author_id),
FOREIGN KEY(book_id) REFERENCES books (book_id) ON DELETE CASCADE,
FOREIGN KEY(author_id) REFERENCES authors(author_id) ON DELETE CASCADE

);

CREATE TABLE book_tags
(
book_id INTEGER NOT NULL,
tag_id INTEGER NOT NULL,
PRIMARY KEY (book_id, tag_id),
FOREIGN KEY(book_id) REFERENCES books(book_id) ON DELETE CASCADE,
FOREIGN KEY(tag_id) REFERENCES tags(tag_id) ON DELETE CASCADE
);


CREATE TABLE shelves
(
shelf_id SERIAL PRIMARY KEY,
shelf_code TEXT UNIQUE NOT NULL
);


CREATE TABLE copies
(
copy_id SERIAL PRIMARY KEY,
copy_barcode TEXT UNIQUE NOT NULL,
book_id INTEGER NOT NULL,
shelf_id INTEGER,
CONSTRAINT fk_book_id
FOREIGN KEY (book_id)
REFERENCES books(book_id) ON DELETE CASCADE,
CONSTRAINT fk_shelf_id
FOREIGN KEY (shelf_id)
REFERENCES shelves(shelf_id)
);

CREATE TABLE borrows
(
borrow_id SERIAL PRIMARY KEY,
member_id INTEGER NOT NULL,
copy_id INTEGER NOT NULL,
borrowed_at TIMESTAMP NOT NULL,
due_date TIMESTAMP NOT NULL,
returned_at TIMESTAMP,
fine_eur NUMERIC(8,2) NOT NULL DEFAULT 0.00,

CHECK (due_date >= borrowed_at ),
CHECK (returned_at IS NULL OR returned_at >= borrowed_at),
CHECK (fine_eur >= 0.00),
CONSTRAINT fk_member_id
FOREIGN KEY (member_id)
REFERENCES members(member_id),
CONSTRAINT fk_copy_id
FOREIGN KEY (copy_id)
REFERENCES copies(copy_id)
);

Loading