Is there a way to make an entire row unique no matter what value the column is in?
So, if 1
is in col a
, and 2
is in col b
, then if you were to insert 2
into col a
and 1
into col b
an error would be thrown.
+---+---+
| a | b |
+---+---+
| 1 | 2 |
| 2 | 1 | <- Would throw error on insert since this already exists above
+---+---+
Based on Justinas php answer I created a mysql trigger on the table:
BEGIN
DECLARE group_md5 CHAR(32);
SELECT MD5(GROUP_CONCAT(plant_id SEPARATOR ',')) INTO group_md5 FROM (
SELECT NEW.plant_a AS plant_id
UNION
SELECT NEW.plant_b AS plant_id
ORDER BY plant_id
) AS plant_list;
SET NEW.hash = group_md5;
END
CREATE TABLE `compliments` (
`plant_a` INT(10) NOT NULL,
`plant_b` INT(10) NOT NULL,
`hash` CHAR(32) NULL DEFAULT NULL COLLATE 'utf8mb4_0900_ai_ci',
UNIQUE INDEX `hash` (`hash`) USING BTREE
)
3
Answers
You could enforce it with a trigger. But I can’t think of a good way to do this with a UNIQUE KEY constraint.
It would be easier if you change the way you store values, so they are in a single column, on multiple rows of an additional table. Then you could easy use UNIQUE KEY to enforce uniqueness.
If you’re trying to represent related items:
If you need each member to appear in only one group:
Have third column
hash VARCHAR NOT NULL UNIQUE
, where you would place sorted hash.Sort it to always get same hash for values, no matter of their order:
1, 2, 2, 3
will have same hash as3, 2, 1, 2
E.g. in PHP:
When inserting data check for duplicates using before insert triggers like so:
A simpler solution is to add
CHECK
constraint along withUNIQUE
on your table:Now, you must store data so that
a < b
. If you try to insert2, 1
the check fails. If you insert1, 2
the unique constraint fails.