Problem Statement
I have five tables, a parent, child, options, child_sections, and child_options table (parent-child in the programming sense). For the Problem Statement, I'm going to name them toy_type, model, color, model_part and model_color.
CREATE TABLE "toy_type" (
"type_id" int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
"type_name" text NOT NULL
);
CREATE TABLE "model" (
"model_id" int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
"type_id" int REFERENCES "toy_type"("type_id")
);
CREATE TABLE "color" (
"type_id" int REFERENCES "toy_type"("type_id"),
"color_name" text,
PRIMARY_KEY ("type_id", "color_name")
);
The color
table uses a compound primary key since the blue on the plane toy isn't the same as the blue on the boat toy.
CREATE TABLE "model_part" (
"model_id" int REFERENCES "model"("model_id"),
"part_id" int NOT NULL,
PRIMARY KEY("model_id", "part_id")
);
CREATE TABLE "model_color" (
"model_id" int,
"part_id" int,
"color_name" text,
PRIMARY KEY ("model_id", "part_id", "color_name"),
CONSTRAINT "FK_model_part.model_part_id"
FOREIGN KEY ("model_id", "part_id")
REFERENCES "model_part"("model_id","part_id"),
...
);
A part can have more than one color on it.
The ellipses are where my problem is occurring. How can I get a foreign reference to color_name
?
Considered Solutions
- The easiest by far is just to add a
type_id
column tomodel_color
and reference the whole compound key which would be fine and functional but I'm not a fan of the unnecessary information. If I'm painting a part I need to know what colors to get I don't really need to know what type of toy it is just the model and the part. Also, I am asking this question to learn if there's a different way. - The other easy solution would be to assign some sort of UUID to the colors(like a HEX code) and reference that UUID instead. But for my actual data set, there isn't some nice UUID analogy like hex codes, and I would like human readable select statements without having to join to a
color_codes
table.
Sought-after Solution
As a human, it is pretty easy for me to reason that if I need to make sure the foreign key is unique then I would need to make sure that the type_id
associated with a given model_id
is part of the unique set with my color name. Is there a way to communicate this to the database through a foreign key constraint?
My thought would be a constraint that looks something along the lines of
CONSTRAINT "FK_model.type_id"
FOREIGN KEY "type_id"
REFERENCES "model("model_id","type_id"),
CONSTRAINT "FK_color.color_name"
FOREIGN KEY "color_name"
REFERENCES (SELECT "color_name" FROM color WHERE type_id="FK_model.type_id")
Where type_id
wouldn't be a column in model color, just a reference to the type_id
referenced by the model
table.
How to do this? It a bad choice?