PostgreSQL: Foreign key to a table with SCD 2

131 Views Asked by At

Using a foreign key to connect two simple tables is straight forward in PostgreSQL:

CREATE TABLE location (
    id UUID PRIMARY KEY,
    name TEXT
);

CREATE TABLE event (
    id UUID PRIMARY KEY,
    location_id UUID,
    title TEXT,
    FOREIGN KEY(location_id) REFERENCES location(id)
);

INSERT INTO location VALUES ('41af871f-a939-46d1-8cac-dd8489ca3248', 'Jupiter');
INSERT INTO event VALUES ('56ab1bf0-36bc-4380-a9d2-fccb88f5ca03', '41af871f-a939-46d1-8cac-dd8489ca3248', 'Success');
-- the next insert statement is supposed to fail
INSERT INTO event VALUES ('da5ecc5f-d63f-4803-883f-70cda9da7583', '529d1030-0db1-4299-8557-055471820b66', 'Failure');

The last statement fails as expected, since there is no location with id = 529d1030-0db1-4299-8557-055471820b66

Now my actual location table is slightly more complex, because it uses SCD Type 2 with date columns:

CREATE TABLE location (
    id UUID PRIMARY KEY,
    name TEXT
    checkin TIMESTAMP NOT NULL,
    checkout TIMESTAMP, -- is null for the latest/current version
);

CREATE UNIQUE INDEX "unique_location" ON location (id, (checkout IS NULL)) WHERE checkout IS NULL;

The location table can now contain multiple versions of a location with a certain id. Only 0 or 1 versions are valid for a given time. Outdated versions have a timerange in the checkin andcheckout fields, while the checkout field of the latest or current version is set to NULL.

Now I want to have a foreign key in the event table, that refers to the current version of a location. A bit like the following (non-working) pseudocode:

CREATE TABLE event (
    -- field definitions
    FOREIGN KEY(location_id) REFERENCES location(id) WHERE location(checkout) IS NULL
);

Is this possible somehow and how?

0

There are 0 best solutions below