I have a question about design part of my db I have 3 tables like these:
CREATE TABLTE projects (
uuid uuid
name text
)
CREATE TABLTE invoices (
uuid uuid
cost text
)
CREATE TABLTE fields (
uuid uuid
parent uuid REFERENCES (???) ON DELETE CASCADE ON UPDATE CASCADE,
type varchar(255) (project or invoice)
)
is possible somehow to create one foreign key that look on more then one table and based on 2 columns (parent, type)? or do I need to do something like this?
CREATE TABLTE filds (
uuid uuid
project_uuid uuid REFERENCES projects(uuid) ON DELETE CASCADE ON UPDATE CASCADE,
invoice_uuid uuid REFERENCES invoices(uuid) ON DELETE CASCADE ON UPDATE CASCADE,
)
1 Answer 1
There are three ways:
If
projects
andinvoices
have almost the same columns and are ofhen used together like "get all projects or invoices that fulfill a certain condition" or "there must be a project or invoice that...", then it is natural to model these two objects with a single table, introducing a columntype
to tell them apart.Then you can have a regular foreign key.
If they should be modeled as different tables and have different columns, introduce two foreign key columns in
fields
, ideally with a check constraint:CHECK (parent_invoice IS NULL AND parent_project IS NOT NULL OR parent_invoice IS NOT NULL AND parent_project IS NULL)
A hybrid solution would be
CREATE TYPE p_or_i AS ENUM ( 'project', 'invoice' ); CREATE TABLE project_or_invoice ( id bigint GENERATED ALWAYS AS IDENTITY NOT NULL, type p_or_i NOT NULL, /* other common columns */, PRIMARY KEY (id, type) ); CREATE TABLE project ( id bigint NOT NULL, type p_or_i GENERATED ALWAYS AS ('project') STORED NOT NULL, /* specific columns */, PRIMARY KEY (id, type), FOREIGN KEY (id, type) REFERENCES project_or_invoice ); CREATE TABLE invoice ( id bigint NOT NULL, type p_or_i GENERATED ALWAYS AS ('invoice') STORED NOT NULL, /* specific columns */, PRIMARY KEY (id, type), FOREIGN KEY (id, type) REFERENCES project_or_invoice );
Then you would reference
project_or_invoice
in your foreign key.
-
thanks for the answer, I have a just a question about solution 2, is this acting like a foreign key? If I delete the parent row, will these row deleted too? thanksfrancesco.venica– francesco.venica2020年06月26日 14:25:36 +00:00Commented Jun 26, 2020 at 14:25
-
That's not how a foreign key works unless you define it with
ON DELETE CASCADE
. But sure, if you define both foreign keys like that, that's how it will work. I didn't spell out the foreign keys in my second solution; I though that part was obvious.Laurenz Albe– Laurenz Albe2020年06月26日 14:27:53 +00:00Commented Jun 26, 2020 at 14:27
projects
andinvoices
, or a single table with atype
in it. The decision often depends on whether they have similar attributes or not.