Mysql 跨两个表强制执行唯一值

Mysql 跨两个表强制执行唯一值,mysql,indexing,Mysql,Indexing,是否可以在MySQL中跨两个表强制执行唯一性 我有两个表,都描述用户。这些表中的用户以前用于两个不同的系统,但是现在我们正在合并我们的身份验证系统,我需要确保这两个表中有唯一的用户名。(现在把它们放在一个表中太费事了。)显然,如果两个表中已经有重复项,那么您必须手动解决该问题。接下来,您可以编写一个触发器来检查这两个表是否已经存在该值,然后将其应用于这两个表。我不知道MySQL,但在Oracle中可以这样做,我相信MySQL也支持物化视图 您可以在这两个表上创建物化视图。然后在此视图上添加唯一的

是否可以在MySQL中跨两个表强制执行唯一性


我有两个表,都描述用户。这些表中的用户以前用于两个不同的系统,但是现在我们正在合并我们的身份验证系统,我需要确保这两个表中有唯一的用户名。(现在把它们放在一个表中太费事了。)

显然,如果两个表中已经有重复项,那么您必须手动解决该问题。接下来,您可以编写一个触发器来检查这两个表是否已经存在该值,然后将其应用于这两个表。

我不知道MySQL,但在Oracle中可以这样做,我相信MySQL也支持物化视图

您可以在这两个表上创建物化视图。然后在此视图上添加唯一的约束


每次提交对两个基表之一的更改时,都需要刷新此视图

您可以添加一个额外的表,其中一列作为主键。然后在每个旧用户表上创建一个触发器,将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;

也许不能直接回答您的问题,但是:

你应该考虑改写你的代码和重组你的数据库,把这两个表合并成一个。


您现在尝试实施的设计将使您的代码和数据库模式复杂化,并使对其他数据库软件或框架的任何进一步升级变得更加困难

更改ID列的类型是否合理?然后,您可以选择在任意多个表中都是唯一的guid。

您不能在多个表中声明唯一约束,MySQL根本不支持检查约束。但是您可以设计一个触发器来搜索另一个表中的匹配值。下面是一个测试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

每个表更新时也需要类似的触发器,但删除时不需要任何触发器。

最好的方法是声明另一个具有唯一列的表,并让多个表引用这些表,MySQL不支持物化视图。MySQL也不能正确执行外键完整性:(即使使用InnoDB也不行?我认为版本5可以。MySQL的默认MyISAM存储引擎不强制外键,但InnoDB很容易使用。InnoDB支持外键已经超过4年了。我认为这实际上没有帮助,因为没有任何东西可以阻止来自不同表的两条记录引用第三个表上的同一个唯一列。我可以这样做t可能与某种多态关联有关。