Last active
March 19, 2026 20:05
-
-
Save blambeau/18c711c38bc6a425e3b0dfad3233b946 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ⏺ Here's a Tutorial D/Rel design for tracking book loans with a max 5 books per client constraint: | |
| // Base relvars | |
| VAR Client REAL RELATION {client_id INT, name CHAR} KEY {client_id}; | |
| VAR Book REAL RELATION {book_id INT, title CHAR} KEY {book_id}; | |
| VAR Loan REAL RELATION {client_id INT, book_id INT, loan_date DATE} | |
| KEY {book_id} // A book can only be loaned to one client at a time | |
| ; | |
| // Foreign key constraints | |
| CONSTRAINT Loan_Client_FK | |
| Loan {client_id} ⊆ Client {client_id}; | |
| CONSTRAINT Loan_Book_FK | |
| Loan {book_id} ⊆ Book {book_id}; | |
| // Max 5 books per client constraint | |
| CONSTRAINT Max5BooksPerClient | |
| IS_EMPTY( | |
| (SUMMARIZE Loan BY {client_id} ADD (COUNT() AS loan_count)) | |
| WHERE loan_count > 5 | |
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| CREATE TABLE clients ( | |
| id SERIAL PRIMARY KEY, | |
| name VARCHAR(255) NOT NULL | |
| ); | |
| CREATE TABLE books ( | |
| id SERIAL PRIMARY KEY, | |
| title VARCHAR(255) NOT NULL | |
| ); | |
| CREATE TABLE borrowings ( | |
| id SERIAL PRIMARY KEY, | |
| client_id INT NOT NULL REFERENCES clients(id), | |
| book_id INT NOT NULL REFERENCES books(id), | |
| borrowed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| returned_at TIMESTAMP, | |
| UNIQUE(book_id, returned_at) -- prevent double-borrowing active books | |
| ); | |
| CREATE OR REPLACE FUNCTION active_borrow_count(p_client_id INT) | |
| RETURNS INT AS $$ | |
| SELECT COUNT(*)::INT FROM borrowings | |
| WHERE client_id = p_client_id AND returned_at IS NULL; | |
| $$ LANGUAGE sql STABLE; | |
| ALTER TABLE borrowings | |
| ADD CONSTRAINT max_5_books | |
| CHECK (active_borrow_count(client_id) < 5); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment