是否可以在MySQL中的两个表中强制实现唯一性?
我有两个表,都描述了用户。这些表中的用户以前用于两个不同的系统,但是现在我们正在合并我们的身份验证系统,我需要确保这两个表中有唯一的用户名。 (现在将它们全部放入一个表中是太多的工作了。)
答案 0 :(得分:16)
您不能在多个表之间声明UNIQUE约束,并且MySQL根本不支持CHECK约束。但是您可以设计一个触发器来搜索另一个表中的匹配值。这是一个测试SQL脚本:
DROP TABLE IF EXISTS foo;
CREATE TABLE FOO (username VARCHAR(10) NOT NULL);
DROP TABLE IF EXISTS bar;
CREATE TABLE BAR (username VARCHAR(10) NOT NULL);
DROP TRIGGER IF EXISTS unique_foo;
DROP TRIGGER IF EXISTS unique_bar;
DELIMITER //
CREATE TRIGGER unique_foo BEFORE INSERT ON foo
FOR EACH ROW BEGIN
DECLARE c INT;
SELECT COUNT(*) INTO c FROM bar WHERE username = NEW.username;
IF (c > 0) THEN
-- abort insert, because foo.username should be NOT NULL
SET NEW.username = NULL;
END IF;
END//
CREATE TRIGGER unique_bar BEFORE INSERT ON bar
FOR EACH ROW BEGIN
DECLARE c INT;
SELECT COUNT(*) INTO c FROM foo WHERE username = NEW.username;
IF (c > 0) THEN
-- abort insert, because bar.username should be NOT NULL
SET NEW.username = NULL;
END IF;
END//
DELIMITER ;
INSERT INTO foo VALUES ('bill'); -- OK
INSERT INTO bar VALUES ('bill'); -- Column 'username' cannot be null
对于每个表,您还需要类似的触发器ON UPDATE,但是您不需要任何触发器ON DELETE。
答案 1 :(得分:4)
执行此操作的最佳方法是使用唯一列声明另一个表,并让多个表引用这些表
答案 2 :(得分:2)
也许不能直接回答你的问题,但是:
您应该考虑重写代码并重构数据库,将这两个表合并为一个。
您现在要强制执行的设计会使代码和数据库架构复杂化,并且会进一步升级到其他数据库软件或框架。
答案 3 :(得分:1)
您可以添加一个包含单个列的额外表作为主键。然后在每个旧用户表上创建一个触发器,将id插入到这个额外的表中。
create table users1 (
user_id integer primary key,
username varchar(8) not null unique
);
create table users2 (
user_id integer primary key,
username varchar(8) not null unique
);
create table all_usernames (
username varchar(8) primary key
);
create trigger users1_insert before insert on users1 for each row
insert into all_usernames values(new.username);
create trigger users2_insert before insert on users2 for each row
insert into all_usernames values(new.username);
create trigger users1_update before update on users1 for each row
update all_usernames set username = new.username
where username = old.username;
create trigger users2_update before update on users2 for each row
update all_usernames set username = new.username
where username = old.username;
create trigger users1_delete before delete on users1 for each row
delete from all_usernames where username = old.username;
create trigger users2_delete before delete on users2 for each row
delete from all_usernames where username = old.username;
然后,您可以使用
填充表格insert into all_usernames select username from users1;
insert into all_usernames select username from users2;
答案 4 :(得分:0)
显然,如果两个表中已经存在重复,则必须手动解决该问题。接下来,您可以编写一个触发器来检查两个表以查看该值是否已存在,然后将其应用于两个表。
答案 5 :(得分:0)
更改ID列的类型是否可以负担得起?然后,您可以选择GUID,这些GUID在您想要的任意数量的表中都是唯一的。
答案 6 :(得分:-1)
我不知道MySQL,但这是你在Oracle中可以做到的,我相信MySQL也支持物化视图。
您可以在这两个表上创建物化视图。并在此视图上添加唯一约束。
每次提交对两个基表之一的更改时,都需要刷新此视图。