Search code examples
postgresqlconstraintspostgresql-9.3

Constraint to avoid combination of foreign keys


I've here a problem that I couldn't find a proper solution on my researches, maybe it's because I couldn't find out the exact terms to search for it, so if this is a duplicate I will delete it.

My problem is I want to know if it is possible to avoid a combination of data between two fields. I will show the structure and the kind of data I want to avoid. It will be easier to understand.

Table_A                         Table_B
------------------------        -------------------------------               
id integer (PK)                 id integer (PK) 
description varchar(50)         title varchar(50)
                                id1_fromA  (FK A->id)
                                id2_fromA  (FK A->id)

I'm trying to validate the following data on table Table_B (combination is between id1_fromA and id2_fromA)

id   title          id1_fromA  id2_fromA  
1    Some Title         1         2 --It will be permmited
2    Some other         1         2 --It is a duplicate NOT ALLOWED
3    One more           1         1 --It is equals NOT ALLOWED
4    Another            2         1 --It is same as registry id 1 so NOT ALLOWED
5    Sample data        3         2 --It is ok

With above data I can easily solve the problem for registry ID=2 with

ALTER TABLE table_B ADD CONSTRAINT UK_TO_A_FKS UNIQUE (id1_fromA, id2_fromA);

And the problem for registry ID=3 with

ALTER TABLE table_B ADD CONSTRAINT CHK_TO_A_FKS CHECK (id1_fromA != id2_fromA);

My Problem is with the registry ID=4 I want to avoid such duplicate of combination as 1,2=2,1. Is it possible to do it with a CONSTRAINT or an INDEX or an UNIQUE or I will need to create a trigger or a procedure to do so?

Thanks in advance.


Solution

  • You can't do this with a unique constraint, but you can do this with a unique index.

    create unique index UK_TO_A_FKS 
       on table_b (least(id1_froma, id2_froma), greatest(id1_froma, id2_froma));