整个mysql表上的唯一键?
假设我有一个包含两列的 mysql 表:A 和 B。是否可以有一个唯一键,以便我只能在 A 或 B 中插入一次值(在整个表中一次)?
因此,如果 A 列包含“qwe”而 B 包含“asd”,则这两个值不能再插入到任一列中。
这是行不通的:
UNIQUE KEY `A` (`A`,`B`),
UNIQUE KEY `A_2` (`A`),
UNIQUE KEY `B` (`B`),
UNIQUE KEY `B_2` (`B`,`A`)
谢谢。
编辑:我能够通过以下触发器来完成此操作:
delimiter |
create trigger unique_check before insert on mytable
for each row begin
declare alreadyexists integer;
select count(*) > 0 into alreadyexists from mytable
where A=NEW.B or B=NEW.A;
IF alreadyexists = 1 THEN begin
DECLARE dummy INT;
SELECT 'A OR B already exists' INTO dummy FROM mytable
WHERE nonexistent = 'value';
end;
END IF;
END;|
但是,我没有看到“A OR B 已存在”错误消息,但是:
错误 1054 (42S22):“where 子句”中未知列“不存在”
再次感谢!
Suppose I have a mysql table with two columns: A and B. Is it possible to have a unique key so that I can only insert a value only once in either A or B (once in the whole table)?
So if column A contains 'qwe' and B contains 'asd' then these two values cannot be inserted anymore in either column.
this will not work:
UNIQUE KEY `A` (`A`,`B`),
UNIQUE KEY `A_2` (`A`),
UNIQUE KEY `B` (`B`),
UNIQUE KEY `B_2` (`B`,`A`)
thanks.
edit: I was able to accomplish this with the following trigger:
delimiter |
create trigger unique_check before insert on mytable
for each row begin
declare alreadyexists integer;
select count(*) > 0 into alreadyexists from mytable
where A=NEW.B or B=NEW.A;
IF alreadyexists = 1 THEN begin
DECLARE dummy INT;
SELECT 'A OR B already exists' INTO dummy FROM mytable
WHERE nonexistent = 'value';
end;
END IF;
END;|
However, I do not see the 'A OR B already exists' error message, but:
ERROR 1054 (42S22): Unknown column 'nonexistent' in 'where clause'
Thanks again!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,这是可能的。
一种方法是
您需要创建一个
BEFORE INSERT
TRIGGER,如果该值已在其他列/表中找到,则返回错误。从这个 博客文章
另一种方式
您还可以使用
事务
使用带有事务的过程将数据插入事务表(InnoDB),
在触发器中写入错误条件:
在过程中类似这:
Yes it's possible.
1 way is
You need to create a
BEFORE INSERT
TRIGGER and return error if the value is already found in other columns/tables.From this blog post
Another way
You can also do with
Transactions
use a procedure with transaction to insert data into transactional table (InnoDB),
In the trigger write on error condition:
In the procedure something like this:
以关系方式执行此操作的正确(且简单)方法是创建两个表 T1 和 T2,其中 T2 具有与 T1 的外键关系(多对一)。唯一索引/约束在 T2.yourUniqueColumn 上声明,如果您必须区分该列中的值,请向 T2 添加另一列:
T2 中自动递增 PK):
您最初可以通过这种方式填充 T2(假设 根据经验,每当您发现自己在使用关系数据库时按程序做事时,就应该退后一步并考虑重构。
The proper (and simple) way to do this relationally is to create two tables, T1 and T2, where T2 has a foreign key relationship (many-to-one) back to T1. The unique index/constraint is declared on T2.yourUniqueColumn, and if you must differentiate between the values in that column, add another column to T2:
You could initially populate T2 in this way (assumes auto-incrementing PK in T2):
As a rule-of-thumb, whenever you find yourself doing things procedurally when working with a relational database, it's time to take a step back and consider refactoring.
您可以使用 COALESCE 从 A 或 B 获取第一个空值,前提是两者都没有设置
You could use COALESCE to get the first null value from A or B providing both do not get set http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce