[英]Bi-directional unique key constraint for combination of two columns
I have the below table columns in MySQL. 我在MySQL中有以下表格列。
id
user_primary_email
user_secondary_email
I want to make the combination of columns user_primary_email
and user_secondary_email
unique which I can achieve by using UNIQUE KEY unique_key_name (user_primary_email, user_secondary_email)
我想通过使用
UNIQUE KEY unique_key_name (user_primary_email, user_secondary_email)
来实现user_primary_email
和user_secondary_email
列的唯一组合。
The above addition of unique key constraint will help me achieve the below scenario or rather just by adding a unique key to the individual column itself. 上面添加的唯一键约束将帮助我实现以下场景,或者仅通过向单个列本身添加唯一键。
user_primary_email = 'xyz@gmail.com' AND user_secondary_email = 'pqr@gmail.com'
user_primary_email = 'xyz@gmail.com' AND user_secondary_email = 'pqr@gmail.com' //This will not be allowed to enter due to unique key constraint
Now the problem which I am facing is the same combination should not be allowed to add in a reverse way as mentioned below. 现在我遇到的问题是不应该允许以相反的方式添加相同的组合,如下所述。
user_primary_email = 'pqr@gmail.com' AND user_secondary_email = 'xyz@gmail.com' //This should not be allowed to add since already same email id combination added once
id | user_primary_email | user_secondary_email
-------------------------------------------------------
1 | xyz@gmail.com | pqr@gmail.com
-------------------------------------------------------
2 | pqr@gmail.com | xyz@gmail.com
-------------------------------------------------------
In the above case during insert of row id 2 it should throw error as both the email id combination is already used in row id 1 . 在插入行id 2期间的上述情况中,它应该抛出错误,因为电子邮件ID组合已经在行id 1中使用 。
Any help would be great. 任何帮助都会很棒。
In any MariaDB: 在任何MariaDB中:
CREATE TABLE `t` (
`id` int(11) NOT NULL,
`user_primary_email` varchar(64) DEFAULT NULL,
`user_secondary_email` varchar(64) DEFAULT NULL,
`mycheck` varchar(128) AS (IF(user_primary_email<user_secondary_email,CONCAT(user_primary_email,user_secondary_email),CONCAT(user_secondary_email,user_primary_email))) PERSISTENT,
PRIMARY KEY (`id`),
UNIQUE KEY `mycheck` (`mycheck`)
);
MariaDB [test]> insert into t values (1,'a','b',null);
Query OK, 1 row affected (0.03 sec)
MariaDB [test]> insert into t values (2,'b','a',null);
ERROR 1062 (23000): Duplicate entry 'ab' for key 'mycheck'
There is no direct support for that, but you can use a workaround to create your bidirectional key: You need a unique key on an ordered version of your two columns. 没有直接支持,但您可以使用变通方法来创建双向密钥:您需要在两列的有序版本上使用唯一密钥。
Fortunately, you can very easily do that. 幸运的是,你可以很容易地做到这一点。 MySQL 5.7.6+ supports generated columns and unique indexes for them, which you can use to order your two values and to enforce uniqueness.
MySQL 5.7.6+支持为它们生成列和唯一索引,您可以使用它们来订购两个值并强制实现唯一性。
create table testBiDirKey (
a varchar(100),
b varchar(100),
a_ordered varchar(100) as (least(a, b)) STORED,
b_ordered varchar(100) as (greatest(a, b)) STORED,
unique key unqBi_test_ab (a_ordered, b_ordered)
);
insert into testBiDirKey(a,b) values('a', 'b');
insert into testBiDirKey(a,b) values('b', 'a');
Error Code: 1062. Duplicate entry 'a-b' for key 'unqBi_test_ab'
This will treat null
exactly as your current normal unique key, so 这将把
null
视为当前正常的唯一键,因此
insert into testBiDirKey(a,b) values('a', null);
insert into testBiDirKey(a,b) values('a', null);
insert into testBiDirKey(a,b) values(null, 'a');
are all allowed. 都是允许的。 You can add
coalesce(x,'')
to only allow one empty value (either null
OR ''
) if you want. 如果需要,可以添加
coalesce(x,'')
以仅允许一个空值( null
OR ''
)。 If you verify your values before you add them (eg if they don't contain a ,
), you can combine the two columns to just one, concatenated with an ,
- although with little benefit apart from just having 1 additional column. 如果在添加它们之前验证了它们的值(例如,如果它们不包含a
,
),您可以将两列合并为一列,与a连接,
但除了只有一个额外的列之外几乎没什么好处。
For 5.7.8+, you don't need the STORED
keyword anymore to be able to use these columns in an index. 对于5.7.8+,您不再需要
STORED
关键字才能在索引中使用这些列。 That keyword effects if the values are stored (using disk space) or calculated when required (default). 如果值存储(使用磁盘空间)或在需要时计算(默认),则该关键字会生效。
Before MySQL 5.7.6, you can use a trigger (on update
and insert
) to update the two columns with the these values, the same logic applies, it's just a little more code. 在MySQL 5.7.6之前,您可以使用触发器(在
update
和insert
)使用这些值更新两列,同样的逻辑适用,它只是一些代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.