我有一个包含以下列的表:
(id, col_1, col_2)
其中“id”是主键(auto-inc)。
我想将col_1
和col_2
设为“唯一组合”。
对于示例,如果我插入数据......
(.., col_1, col_2 ) = (.., 'A', 'B')
...接下来,我不允许插入以下内容:
(.., col_1, col_2 ) = (.., 'A', 'B')
(.., col_1, col_2 ) = (.., 'B', 'A') #because it already exists, in another order:('A','B')
我使用UNIQUE(col_1, col_2)
...
但似乎允许“反向组合” (.., 'B', 'A')
。
我该怎么办?
答案 0 :(得分:1)
尝试之后,实际上并不像创建另一个独特的索引那么容易 这似乎是MySQL的一个奇怪的缺陷。解决方法虽然可以始终在col_1中存储较小的值,在col_2中存储较大的值(当您不喜欢触发器时):
INSERT INTO your_table (col_1, col_2) VALUES (LEAST('A', 'B'), GREATEST('A', 'B'));
您可以找到这些功能的文档here。
答案 1 :(得分:1)
正如fancyPants所说,解决方案是确保一列始终低于另一列。 MySQL不支持CHECK约束,但您可以使用触发器强制执行此操作,这将允许您捕获应用程序错误:
Can a MySQL trigger simulate a CHECK constraint?
注意:根据MySQL版本,使用触发器引发错误将使用不同的方法。
在较新的MySQL版本中,您还可以创建虚拟列并对其进行索引。也许你可以创造一个独特的(最少(a,b),最大(a,b))......但它会有点笨拙。
此外,知道< = b是约束将加速搜索。如果你需要搜索(x,y)或(y,x),那么你知道表中唯一的一个是正确的顺序,这简化了你的WHERE并使索引使用得更好。