Changes between Initial Version and Version 1 of DatabaseCreation


Ignore:
Timestamp:
06/07/26 15:37:00 (10 days ago)
Author:
231062
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • DatabaseCreation

    v1 v1  
     1**DDL**
     2
     3
     4Enums
     5
     6{{{
     7CREATE TYPE GENDER AS ENUM ('male', 'female', 'other');
     8CREATE TYPE COVER AS ENUM ('hardcover', 'paperback', 'ebook');
     9}}}
     10
     11Location
     12{{{
     13CREATE TABLE Location (
     14id BIGSERIAL PRIMARY KEY,
     15address VARCHAR(128) NOT NULL,
     16city VARCHAR(128) NOT NULL
     17);
     18}}}
     19
     20Library
     21{{{
     22CREATE TABLE Library (
     23id BIGSERIAL PRIMARY KEY,
     24name VARCHAR(64) NOT NULL,
     25location_id BIGINT,
     26CONSTRAINT FKLibrary_Location FOREIGN KEY (location_id)
     27REFERENCES Location(id)
     28ON DELETE SET NULL ON UPDATE CASCADE
     29);
     30}}}
     31
     32User
     33{{{
     34CREATE TABLE "User" (
     35id BIGSERIAL PRIMARY KEY,
     36first_name VARCHAR(128) NOT NULL DEFAULT '[deleted_user]',
     37last_name VARCHAR(128) NOT NULL DEFAULT '[deleted_user]',
     38password VARCHAR(255) NOT NULL DEFAULT '[deleted]',
     39email VARCHAR(128) NOT NULL DEFAULT '[deleted_user@example.com]',
     40date_of_birth DATE,
     41verified BOOLEAN,
     42gender GENDER DEFAULT 'other',
     43deleted BOOLEAN NOT NULL DEFAULT FALSE,
     44deleted_at TIMESTAMP,
     45created_at TIMESTAMP NOT NULL DEFAULT now(),
     46updated_at TIMESTAMP NOT NULL DEFAULT now(),
     47CONSTRAINT chk_user_dob CHECK (date_of_birth <= CURRENT_DATE),
     48CONSTRAINT chk_user_email CHECK (email LIKE '%@%')
     49);
     50}}}
     51
     52Employee
     53{{{
     54CREATE TABLE Employee (
     55id BIGINT PRIMARY KEY,
     56start_date TIMESTAMP NOT NULL,
     57salary NUMERIC NOT NULL,
     58manager_id BIGINT,
     59library_id BIGINT NOT NULL,
     60CONSTRAINT FKEmployee_User FOREIGN KEY (id)
     61REFERENCES "User"(id) ON DELETE CASCADE ON UPDATE CASCADE,
     62CONSTRAINT FKEmployee_Manager FOREIGN KEY (manager_id)
     63REFERENCES Employee(id) ON DELETE SET NULL ON UPDATE CASCADE,
     64CONSTRAINT FKEmployee_Library FOREIGN KEY (library_id)
     65REFERENCES Library(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     66CONSTRAINT chk_employee_salary CHECK (salary > 0)
     67);
     68}}}
     69
     70MembershipPlan
     71{{{
     72CREATE TABLE MembershipPlan (
     73id BIGSERIAL PRIMARY KEY,
     74name VARCHAR(64) NOT NULL,
     75max_rent_period_days INT4 NOT NULL,
     76max_concurrent_rentals INT4 NOT NULL,
     77price NUMERIC(8, 2) NOT NULL,
     78duration_days INT NOT NULL,
     79CONSTRAINT chk_plan_limits CHECK (max_rent_period_days > 0 AND max_concurrent_rentals > 0 AND duration_days > 0),
     80CONSTRAINT chk_plan_price CHECK (price >= 0)
     81);
     82}}}
     83
     84Membership
     85{{{
     86CREATE TABLE Membership (
     87id BIGSERIAL PRIMARY KEY,
     88user_id BIGINT NOT NULL,
     89membership_plan_id BIGINT,
     90started_at TIMESTAMP NOT NULL,
     91expires_at TIMESTAMP NOT NULL,
     92cancelled_at TIMESTAMP,
     93created_at TIMESTAMP NOT NULL,
     94CONSTRAINT FKMembership_User FOREIGN KEY (user_id)
     95REFERENCES "User"(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     96CONSTRAINT FKMembership_Plan FOREIGN KEY (membership_plan_id)
     97REFERENCES MembershipPlan(id) ON DELETE SET NULL ON UPDATE CASCADE,
     98CONSTRAINT chk_membership_dates CHECK (expires_at > started_at),
     99CONSTRAINT chk_membership_cancelled CHECK (cancelled_at >= started_at)
     100);
     101}}}
     102
     103AttributeType
     104{{{
     105CREATE TABLE AttributeType (
     106id BIGSERIAL PRIMARY KEY,
     107name VARCHAR(64) NOT NULL
     108);
     109}}}
     110
     111AttributeValue
     112{{{
     113CREATE TABLE AttributeValue (
     114id BIGSERIAL PRIMARY KEY,
     115value VARCHAR(64) NOT NULL
     116);
     117}}}
     118
     119AttributePair
     120{{{
     121CREATE TABLE AttributePair (
     122id BIGSERIAL PRIMARY KEY,
     123type_id BIGINT NOT NULL,
     124value_id BIGINT NOT NULL,
     125CONSTRAINT FKAttributePair_Type FOREIGN KEY (type_id)
     126REFERENCES AttributeType(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     127CONSTRAINT FKAttributePair_Value FOREIGN KEY (value_id)
     128REFERENCES AttributeValue(id) ON DELETE RESTRICT ON UPDATE CASCADE
     129);
     130}}}
     131
     132ResourceType
     133{{{
     134CREATE TABLE ResourceType (
     135id BIGSERIAL PRIMARY KEY,
     136name VARCHAR(64) NOT NULL
     137);
     138}}}
     139
     140Genre
     141{{{
     142CREATE TABLE Genre (
     143id BIGSERIAL PRIMARY KEY,
     144name VARCHAR(64) NOT NULL
     145);
     146}}}
     147
     148Resource
     149{{{
     150CREATE TABLE Resource (
     151id BIGSERIAL PRIMARY KEY,
     152title VARCHAR(256) NOT NULL,
     153description TEXT ,
     154resource_type_id BIGINT NOT NULL,
     155CONSTRAINT FKResource_Type FOREIGN KEY (resource_type_id)
     156REFERENCES ResourceType(id) ON DELETE RESTRICT ON UPDATE CASCADE
     157);
     158}}}
     159
     160Edition
     161{{{
     162CREATE TABLE Edition (
     163isbn VARCHAR(20) PRIMARY KEY,
     164name VARCHAR(512) NOT NULL,
     165resource_id BIGINT NOT NULL,
     166publisher VARCHAR(128) NOT NULL,
     167publish_year INT4 NOT NULL,
     168format VARCHAR(32) NOT NULL,
     169language VARCHAR(32) NOT NULL,
     170num_pages INT NOT NULL,
     171cover_type COVER NOT NULL DEFAULT 'paperback',
     172CONSTRAINT FKEdition_Resource FOREIGN KEY (resource_id)
     173REFERENCES Resource(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     174CONSTRAINT chk_publish_year CHECK (publish_year <= EXTRACT(YEAR FROM CURRENT_DATE))
     175);
     176}}}
     177
     178ResourceCopy
     179{{{
     180CREATE TABLE ResourceCopy (
     181id BIGSERIAL PRIMARY KEY,
     182edition_isbn VARCHAR(20) NOT NULL,
     183library_id BIGINT NOT NULL,
     184status INT4 NOT NULL,
     185barcode VARCHAR(64) NOT NULL,
     186created_at TIMESTAMP NOT NULL,
     187updated_at TIMESTAMP NOT NULL,
     188CONSTRAINT FKResourceCopy_Edition FOREIGN KEY (edition_isbn)
     189REFERENCES Edition(isbn) ON DELETE CASCADE ON UPDATE CASCADE,
     190CONSTRAINT FKResourceCopy_Library FOREIGN KEY (library_id)
     191REFERENCES Library(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     192CONSTRAINT chk_copy_status CHECK (status IN (1,2,3,4))
     193);
     194}}}
     195
     196Rental
     197{{{
     198CREATE TABLE Rental (
     199id BIGSERIAL PRIMARY KEY,
     200resource_copy_id BIGINT NOT NULL,
     201rented_at TIMESTAMP NOT NULL,
     202due_at TIMESTAMP NOT NULL,
     203returned_at TIMESTAMP,
     204membership_id BIGINT NOT NULL,
     205penalty NUMERIC(19, 0),
     206employee_id BIGINT,
     207CONSTRAINT FKRental_Copy FOREIGN KEY (resource_copy_id)
     208REFERENCES ResourceCopy(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     209CONSTRAINT FKRental_Membership FOREIGN KEY (membership_id)
     210REFERENCES Membership(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     211CONSTRAINT FKRental_Employee FOREIGN KEY (employee_id)
     212REFERENCES Employee(id) ON DELETE SET NULL ON UPDATE CASCADE,
     213CONSTRAINT chk_rental_due_date CHECK (due_at > rented_at),
     214CONSTRAINT chk_rental_returned_date CHECK (returned_at >= rented_at),
     215CONSTRAINT chk_rental_penalty CHECK (penalty >= 0)
     216);
     217}}}
     218
     219EventType
     220{{{
     221CREATE TABLE EventType (
     222id BIGSERIAL PRIMARY KEY,
     223name VARCHAR(128) NOT NULL
     224);
     225}}}
     226
     227Room
     228{{{
     229CREATE TABLE Room (
     230id BIGSERIAL PRIMARY KEY,
     231name VARCHAR(128),
     232library_id BIGINT NOT NULL,
     233CONSTRAINT FKRoom_Library FOREIGN KEY (library_id)
     234REFERENCES Library(id) ON DELETE RESTRICT ON UPDATE CASCADE
     235);
     236}}}
     237
     238Event
     239{{{
     240CREATE TABLE Event (
     241id BIGSERIAL PRIMARY KEY,
     242name VARCHAR(128) NOT NULL,
     243description TEXT NOT NULL,
     244library_id BIGINT NOT NULL,
     245event_type_id BIGINT NOT NULL,
     246capacity INT4 NOT NULL,
     247start_time TIMESTAMP NOT NULL,
     248duration INT4 NOT NULL,
     249event_room_id BIGINT NOT NULL,
     250CONSTRAINT FKEvent_Type FOREIGN KEY (event_type_id)
     251REFERENCES EventType(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     252CONSTRAINT FKEvent_Library FOREIGN KEY (library_id)
     253REFERENCES Library(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     254CONSTRAINT FKEvent_Room FOREIGN KEY (event_room_id)
     255REFERENCES Room(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     256CONSTRAINT chk_event_capacity CHECK (capacity > 0),
     257CONSTRAINT chk_event_duration CHECK (duration > 0)
     258);
     259}}}
     260
     261EventRegistration
     262{{{
     263CREATE TABLE EventRegistration (
     264id BIGSERIAL PRIMARY KEY,
     265user_id BIGINT NOT NULL,
     266event_id BIGINT NOT NULL,
     267registered_at TIMESTAMP NOT NULL,
     268CONSTRAINT FKEventReg_User FOREIGN KEY (user_id)
     269REFERENCES "User"(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     270CONSTRAINT FKEventReg_Event FOREIGN KEY (event_id)
     271REFERENCES Event(id) ON DELETE RESTRICT ON UPDATE CASCADE
     272);
     273}}}
     274
     275Review
     276{{{
     277CREATE TABLE Review (
     278id BIGSERIAL PRIMARY KEY,
     279user_id BIGINT NOT NULL,
     280resource_edition_isbn VARCHAR(20) NOT NULL,
     281rating INT4 NOT NULL,
     282review_text TEXT NOT NULL,
     283created_at TIMESTAMP NOT NULL,
     284updated_at TIMESTAMP NOT NULL,
     285CONSTRAINT FKReview_User FOREIGN KEY (user_id)
     286REFERENCES "User"(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     287CONSTRAINT FKReview_Edition FOREIGN KEY (resource_edition_isbn)
     288REFERENCES Edition(isbn) ON DELETE RESTRICT ON UPDATE CASCADE,
     289CONSTRAINT chk_review_rating CHECK (rating BETWEEN 1 AND 5)
     290);
     291}}}
     292
     293Reply
     294{{{
     295CREATE TABLE Reply (
     296id BIGSERIAL PRIMARY KEY,
     297user_id BIGINT NOT NULL,
     298review_id BIGINT NOT NULL,
     299text TEXT NOT NULL,
     300create_at TIMESTAMP NOT NULL,
     301updated_at TIMESTAMP NOT NULL,
     302deleted BOOLEAN NOT NULL,
     303parent_id BIGINT,
     304CONSTRAINT FKReply_User FOREIGN KEY (user_id)
     305REFERENCES "User"(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     306CONSTRAINT FKReply_Review FOREIGN KEY (review_id)
     307REFERENCES Review(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     308CONSTRAINT FKReply_Parent FOREIGN KEY (parent_id)
     309REFERENCES Reply(id) ON DELETE SET NULL ON UPDATE CASCADE
     310);
     311}}}
     312
     313Author
     314{{{
     315CREATE TABLE Author (
     316id BIGSERIAL PRIMARY KEY,
     317name VARCHAR(64),
     318surname VARCHAR(64),
     319artistic_name VARCHAR(64),
     320date_of_birth DATE,
     321CONSTRAINT chk_author_dob CHECK (date_of_birth <= CURRENT_DATE)
     322);
     323}}}
     324
     325Wishlist
     326{{{
     327CREATE TABLE Wishlist (
     328id BIGSERIAL PRIMARY KEY,
     329user_id BIGINT NOT NULL,
     330CONSTRAINT FKWishlist_User FOREIGN KEY (user_id)
     331REFERENCES "User"(id) ON DELETE RESTRICT ON UPDATE CASCADE
     332);
     333}}}
     334
     335Shelf
     336{{{
     337CREATE TABLE Shelf (
     338id BIGSERIAL PRIMARY KEY,
     339room_id BIGINT NOT NULL,
     340genre_id BIGINT NOT NULL,
     341CONSTRAINT FKShelf_Room FOREIGN KEY (room_id)
     342REFERENCES Room(id) ON DELETE RESTRICT ON UPDATE CASCADE,
     343CONSTRAINT FKShelf_Genre FOREIGN KEY (genre_id)
     344REFERENCES Genre(id) ON DELETE RESTRICT ON UPDATE CASCADE
     345);
     346}}}
     347
     348Chapter
     349{{{
     350CREATE TABLE Chapter (
     351id BIGSERIAL PRIMARY KEY,
     352edition_isbn VARCHAR(20) NOT NULL,
     353name VARCHAR(128),
     354number INT4,
     355CONSTRAINT FKChapter_Edition FOREIGN KEY (edition_isbn)
     356REFERENCES Edition(isbn) ON DELETE RESTRICT ON UPDATE CASCADE
     357);
     358}}}
     359
     360Resource_Genres
     361{{{
     362CREATE TABLE Resource_Genres (
     363ResourceId BIGINT NOT NULL,
     364GenreId BIGINT NOT NULL,
     365PRIMARY KEY (ResourceId, GenreId),
     366FOREIGN KEY (ResourceId) REFERENCES Resource(id) ON DELETE CASCADE ON UPDATE CASCADE,
     367FOREIGN KEY (GenreId) REFERENCES Genre(id) ON DELETE CASCADE ON UPDATE CASCADE
     368);
     369}}}
     370
     371Edition_Attributes
     372{{{
     373CREATE TABLE Edition_Attributes (
     374edition_id VARCHAR(20) NOT NULL,
     375attribute_pair_id BIGINT NOT NULL,
     376PRIMARY KEY (edition_id, attribute_pair_id),
     377FOREIGN KEY (edition_id) REFERENCES Edition(isbn) ON DELETE CASCADE ON UPDATE CASCADE,
     378FOREIGN KEY (attribute_pair_id) REFERENCES AttributePair(id) ON DELETE CASCADE ON UPDATE CASCADE
     379);
     380}}}
     381
     382Wishlist_entry
     383{{{
     384CREATE TABLE Wishlist_entry (
     385edition_isbn VARCHAR(20) NOT NULL,
     386wishlist_id BIGINT NOT NULL,
     387PRIMARY KEY (edition_isbn, wishlist_id),
     388FOREIGN KEY (edition_isbn) REFERENCES Edition(isbn) ON DELETE CASCADE ON UPDATE CASCADE,
     389FOREIGN KEY (wishlist_id) REFERENCES Wishlist(id) ON DELETE CASCADE ON UPDATE CASCADE
     390);
     391}}}
     392
     393Chapter_authors
     394{{{
     395CREATE TABLE Chapter_authors (
     396chapter_id BIGINT NOT NULL,
     397author_id BIGINT NOT NULL,
     398PRIMARY KEY (chapter_id, author_id),
     399FOREIGN KEY (chapter_id) REFERENCES Chapter(id) ON DELETE CASCADE ON UPDATE CASCADE,
     400FOREIGN KEY (author_id) REFERENCES Author(id) ON DELETE CASCADE ON UPDATE CASCADE
     401);
     402}}}
     403
     404Edition_authors
     405{{{
     406CREATE TABLE Edition_authors (
     407edition_id VARCHAR(20) NOT NULL,
     408author_id BIGINT NOT NULL,
     409PRIMARY KEY (edition_id, author_id),
     410FOREIGN KEY (edition_id) REFERENCES Edition(isbn) ON DELETE CASCADE ON UPDATE CASCADE,
     411FOREIGN KEY (author_id) REFERENCES Author(id) ON DELETE CASCADE ON UPDATE CASCADE
     412);
     413}}}
     414
     415**Views**
     416
     417vw_edition_copy_count
     418{{{
     419CREATE VIEW vw_edition_copy_count AS
     420SELECT
     421e.isbn,
     422e.name,
     423COUNT(rc.id) AS total_copies
     424FROM Edition e
     425LEFT JOIN ResourceCopy rc
     426ON rc.edition_isbn = e.isbn
     427GROUP BY e.isbn, e.name;
     428}}}
     429
     430vw_active_memberships
     431{{{
     432CREATE VIEW vw_active_memberships AS
     433SELECT
     434m.id,
     435m.user_id,
     436u.first_name,
     437u.last_name,
     438u.email,
     439m.membership_plan_id,
     440mp.name AS membership_name,
     441m.started_at,
     442m.expires_at
     443FROM Membership m
     444JOIN "User" u ON m.user_id = u.id
     445JOIN membershipplan mp ON mp.id = m.membership_plan_id
     446WHERE m.cancelled_at IS NULL
     447AND m.expires_at > NOW();
     448}}}
     449
     450vw_active_rentals
     451{{{
     452CREATE VIEW vw_active_rentals AS
     453SELECT
     454r.id,
     455r.resource_copy_id,
     456e.name,
     457r.membership_id,
     458u.email,
     459r.rented_at,
     460r.due_at
     461FROM Rental r
     462JOIN resourcecopy rc ON r.resource_copy_id = rc.id
     463JOIN edition e ON e.isbn = rc.edition_isbn
     464JOIN membership m ON m.id = r.membership_id
     465JOIN "User" u ON u.id = m.user_id
     466WHERE r.returned_at IS NULL;
     467}}}
     468
     469vw_sorted_by_rentals_rented_editions
     470{{{
     471CREATE VIEW vw_sorted_by_rentals_rented_editions AS
     472SELECT
     473e.isbn,
     474e.name,
     475COUNT(r.id) AS rental_count
     476FROM Rental r
     477JOIN ResourceCopy rc
     478ON r.resource_copy_id = rc.id
     479JOIN Edition e
     480ON rc.edition_isbn = e.isbn
     481GROUP BY e.isbn, e.name;
     482}}}
     483
     484vw_edition_ratings
     485{{{
     486CREATE VIEW vw_edition_ratings AS
     487SELECT
     488e.isbn,
     489e.name,
     490AVG(r.rating) AS avg_rating,
     491COUNT(r.id) AS review_count
     492FROM Edition e
     493LEFT JOIN Review r
     494ON r.resource_edition_isbn = e.isbn
     495GROUP BY e.isbn, e.name;
     496}}}
     497
     498vw_user_activity
     499{{{
     500CREATE VIEW vw_user_activity AS
     501SELECT
     502u.id AS user_id,
     503u.email,
     504COUNT(DISTINCT r.id) AS total_rentals,
     505COUNT(DISTINCT rev.id) AS total_reviews,
     506COUNT(DISTINCT er.id) AS total_event_registrations
     507FROM "User" u
     508LEFT JOIN Membership m
     509ON m.user_id = u.id
     510LEFT JOIN Rental r
     511ON r.membership_id = m.id
     512LEFT JOIN Review rev
     513ON rev.user_id = u.id
     514LEFT JOIN EventRegistration er
     515ON er.user_id = u.id
     516GROUP BY u.id;
     517}}}
     518
     519vw_overdue_rentals
     520{{{
     521CREATE VIEW vw_overdue_rentals AS
     522SELECT
     523r.id,
     524r.resource_copy_id,
     525e.name,
     526r.membership_id,
     527u.email,
     528r.due_at
     529FROM Rental r
     530JOIN resourcecopy rc ON rc.id = r.resource_copy_id
     531JOIN edition e ON e.isbn = rc.edition_isbn
     532JOIN membership m ON m.id = r.membership_id
     533JOIN "User" u ON u.id = m.user_id
     534WHERE r.returned_at IS NULL
     535AND r.due_at < NOW();
     536}}}
     537
     538vw_available_editions_for_rent
     539{{{
     540CREATE VIEW vw_available_editions_for_rent AS
     541SELECT
     542e.isbn,
     543e.name,
     544COUNT(rc.id) AS total_copies,
     545COUNT(ar.id) AS currently_rented_copies,
     546(COUNT(rc.id) - COUNT(ar.id)) AS available_copies
     547FROM Edition e
     548LEFT JOIN ResourceCopy rc
     549ON rc.edition_isbn = e.isbn
     550LEFT JOIN Rental r
     551ON r.resource_copy_id = rc.id
     552AND r.returned_at IS NULL
     553LEFT JOIN vw_active_rentals ar
     554ON ar.resource_copy_id = rc.id
     555GROUP BY e.isbn, e.name
     556HAVING (COUNT(rc.id) - COUNT(ar.id)) > 0;
     557}}}
     558
     559vw_future_events_for_lib
     560{{{
     561CREATE VIEW vw_future_events_for_lib AS
     562SELECT e.name AS event_name,
     563e.description AS event_description,
     564et.name AS type_of_event,
     565l.name AS library_name,
     566e.capacity AS event_capacity,
     567e.start_time AS start_date_time,
     568r.name AS room_name
     569FROM event AS e
     570JOIN library AS l ON e.library_id = l.id
     571JOIN room AS r ON r.id = e.event_room_id
     572JOIN eventtype AS et ON et.id = e.event_type_id
     573WHERE e.start_time >= now()
     574ORDER BY start_time;
     575}}}