What's the proper / idiomatic way to express a foreign key constraint in PostgreSQL where part of the FK columns resides in another table?
I'll use an example to make this clear (omitting some obvious PKs and FKs to make this short). We wish to model the following associations between books, themes found in a book, reading events (in which a book is read) and themes discussed in a reading event (which should be a subset of a book's themes):
book ←———————————— reading_event
↑ ↑
theme ←———————————— themeDiscussed
In terms of SQL, we have a table used to hold books:
CREATE TABLE BOOK (name VARCHAR);
INSERT INTO BOOK(name) VALUES('game of thrones');
Then a table to hold the various themes we find in each book:
CREATE TABLE BOOK_THEME (bookName VARCHAR, themeName VARCHAR);
INSERT INTO BOOK_THEME(bookName, themeName) VALUES ('game of thrones', 'ambition'), ('game of thrones', 'power');
Then a table to record information about "reading events". Only one book is read in each reading event:
CREATE TABLE READING_EVENT(i SERIAL, venue VARCHAR, bookRead VARCHAR);
ALTER TABLE READING_EVENT ADD PRIMARY KEY (i);
INSERT INTO READING_EVENT(venue, bookRead) VALUES('Municipal Library', 'game of thrones');
And here, comes the tricky part. We also have a table to record the themes that were actively discussed during that reading event:
CREATE TABLE READING_EVENT_DISCUSSION(i INTEGER, themeDiscussed VARCHAR);
ALTER TABLE READING_EVENT_DISCUSSION ADD CONSTRAINT constr1 FOREIGN KEY (i) REFERENCES READING_EVENT(i);
Now, how do I express that the themeDiscussed
column has to obviously reference one of the themes actually found in the book that was read in that event? Column bookName
is present in the READING_EVENT
table, not in the READING_EVENT_DISCUSSION
where we want the FK to be declared.