Обеспечение уникальных значений по двум таблицам
Можно ли обеспечить уникальность двух таблиц в MySQL?
У меня есть две таблицы, описывающие пользователей. Пользователи этих таблиц ранее были для двух разных систем, однако теперь мы объединяем наши системы аутентификации, и мне нужно убедиться, что в этих двух таблицах есть уникальные имена пользователей. (слишком много работы, чтобы поместить их всех в один стол прямо сейчас).
Ответы
Ответ 1
Вы не можете объявить ограничение UNIQUE для нескольких таблиц, а MySQL не поддерживает ограничения CHECK вообще. Но вы можете создать триггер для поиска соответствующего значения в другой таблице. Здесь тестовый SQL script:
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.
Ответ 2
лучший способ сделать это - объявить другую таблицу с уникальными столбцами, а несколько таблиц ссылаются на эти таблицы
Ответ 3
Возможно, не прямой ответ на ваш вопрос, но:
Вы должны переписать код и перестроить свою базу данных, чтобы объединить эти две таблицы в один.
Дизайн, который вы пытаетесь применить сейчас, усложнит вашу схему кода и базы данных, и это сделает дальнейшее обновление для другого программного обеспечения или фреймворков базы данных более сложным.
Ответ 4
Вы можете добавить дополнительную таблицу с одним столбцом в качестве первичного ключа. Затем создайте триггер на каждой из ваших старых пользовательских таблиц, чтобы вставить идентификатор в эту дополнительную таблицу.
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;
Ответ 5
Очевидно, что если в обеих таблицах уже есть дубликаты, вам придется решить эту проблему вручную. Двигаясь вперед, вы можете написать триггер, который проверяет обе таблицы, чтобы увидеть, существует ли это значение, а затем применить это к обеим таблицам.
Ответ 6
Будет ли изменение типа столбца идентификатора доступным? Затем вы можете использовать идентификаторы GUID, которые будут уникальными для всех таблиц, которые вы хотите.
Ответ 7
Я не знаю MySQL, но так вы можете сделать это в Oracle, и я считаю, что MySQL также поддерживает материализованные представления.
Вы создаете материализованное представление для этих двух таблиц. И вы добавляете к этому представлению уникальное ограничение.
Это представление необходимо обновлять каждый раз, когда происходит переключение на одну из двух базовых таблиц.