MySQL unique key only where another key contains a specific value
Question
I have a table which contains meta data for users. There are 4 fields...
`ID`,`meta_name`,`meta_value`,`user_id`
I want to store emails in this table. Naturally these must be unique. However I want to store other data in this table as well, where the data does not need to be unique. Is there any way I can restrict 'meta_value'
to be unique, only if 'meta_name'
is equal to 'email'?
Solution
By means of MySQL's contraints - no.
However you can use insert/update trigger that verifies uniqueness of the data and forbids illegal operations.
Here is a draft of insert trigger (You can play with it here: http://sqlfiddle.com/#!2/5c9e3):
DELIMITER //
CREATE TRIGGER VerifyInsert BEFORE INSERT ON YourTestTable
FOR EACH ROW
BEGIN
IF (SELECT COUNT(1) FROM YourTestTable
WHERE YourTestTable.meta_name = 'EMail' AND YourTestTable.meta_value = NEW.meta_value
AND NEW.meta_name = YourTestTable.meta_name) > 0 THEN
SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'VerifyInsertFailed';
END IF;
END;
//
OTHER TIPS
With MySQL contraints it's impossible, without special tricks (like redundant column unique_helper
with constant value for meta_name
=email
and random for each other + UNIQUE
index for unique_helper
+meta_value
).
But you can use custom TRIGGER in innoDB tables: (rememeber to put yourTable
name)
CREATE TRIGGER triggerName
BEFORE INSERT ON yourTable
FOR EACH ROW
BEGIN
IF NEW.meta_name = 'email' AND EXISTS (SELECT 1 FROM yourTable WHERE meta_name='email' AND meta_value=NEW.meta_value)
THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Duplicate email';
END IF;
END;