What is the correct / idiomatic way of expressing a foreign key constraint in PostgreSQL, where some of the FK columns are in another table?
I use an example to make this clear (excluding some obvious PCs and FCs to make it short). We want to model the following associations between books, topics found in a book, reading events (in which a book is read) and topics discussed in a reading event (which should be a subset of book topics):
book βββββββββββββ reading_event β β theme βββββββββββββ themeDiscussed
In terms of SQL, we have a table used to store books:
CREATE TABLE BOOK (name VARCHAR); INSERT INTO BOOK(name) VALUES('game of thrones');
Then a table to store the various topics that 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 will appear to record information about the βevent readsβ. Only one book is read in each reading:
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 hard part. We also have a table for recording topics that were actively discussed during this 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 can I express that the themeDiscussed column should explicitly refer to one of the topics actually found in the book that was read in this case? The column bookName is in the READING_EVENT table, and not in READING_EVENT_DISCUSSION , where we want to declare FK.