Why do composite foreign keys need a separate unique constraint?
It's a limitation of the DBMS - in all of them as far as I know. And not only when adding a column but also when rearranging columns. If we have a UNIQUE
constraint on (a1, a2)
, we can't add a FOREIGN KEY
that REFERENCES (a2, a1)
unless there is a unique constraint on that (a2, a1)
that essentially is redundant.
It wouldn't be terrifically difficult to add this as a feature:
When there is a
UNIQUE
constraint on(a)
, then any(a, b, c, ..., z)
or(b,c, ...a, ...z)
combination is also guaranteedUNIQUE
.
or the generalization:
When there is a
UNIQUE
constraint on(a1, a2, ..., aN)
, then any(a1, a2, ..., aN, b1, b2, ..., bM)
combination or any rearrangement is also guaranteedUNIQUE
.
It seems that it hasn't been asked or it hasn't been considered high enough priority to be implemented.
You can always make a request - in the respective channel - for the feature to be implemented. Or even implement it yourself, if the DBMS is open source, like Postgres.
Foreign Keys in general (not just composite) MUST point to a UNIQUE KEY of some sort in another table. If they did not, there would be no relational data integrity.
This is complaining because, while you have a unique key on (id) .. you do NOT have a unique key on (id, num).. Thus, as far as the DB is concerned, the pair (id, num) is not GUARANTEED to be unique. Us, as humans, can figure out it will be unique, but I'm sure there would be a lot of additional code they would have to add to make Postgres smart enough to see that "oh hey .. id is supposed to be unique, so id,num should also be unique" ..
I would be highly surprised if they added that code when all you have to do is create another unique index on the two columns to fix the problem.
Just to be clear, the code they would have to add wouldn't be just this simple case... it would have to handle all cases, even ones where the foreign key is on 4+ columns, etc.. I'm sure the logic would be quite complex.