Okay i know i can do this in the application layer, which is probably the easiest thing to do, but just to make sure that no errors water down to the DB, i have a serious question
I have two columns X and Y, each to store two integers (either A or B in any of the columns). Is it possible to have a unique index constraint such that, in no instance should we have
- Column X with A and Column Y with B
- Column X with B and Column Y with A
I’ll give a scenario
I have two users, userA has id 678498 and userB has id 679879. Both users are about to play a 2 player game which requires that a new record for this session be stored in a table (tbl_chalenger). To do so, i have a table with columns “host” and “challenger”.
I have a unique constrain added to tbl_challenger as
UNIQUE KEY `UNIQUE_PARTICIPANTS` (`host`,`challenger`)
Branding users a host or challenger is basically dependent on who initiated the game. So if userA initiates the game we have an query as follows
INSERT INTO `tbl_challenger` VALUES(678498 , 679879);
which creates a new record, Sadly though, if at the same time userB attempts to initiate a game with user A, we get
INSERT INTO `tbl_challenger` VALUES(679879, 678498 );
Which creates a new unwanted row, of the same participants. This irrespective of the UNIQUE key constraint.
So my question is how to have a constraint that is bidirectional?, such that “host-challenger” as well as “challenger-host” cannot have the same data pair
In mysql the only way I can think of is to add a couple of utility columns like
and add a couple of triggers that set
u0andu1to the least and greatest of the two:then you add a unique index on
(u0,u1)And now you will get an error trying to insert duplicate pair regardless of the order.
On a decent RDBMS like
PostgreSQLyou would be able to use index on expression:So, switch before it’s too late 😉