Принудительно использовать уникальные значения в двух таблицах - PullRequest
14 голосов
/ 03 января 2009

Возможно ли обеспечить уникальность для двух таблиц в MySQL?

У меня есть две таблицы, обе описывают пользователей. Пользователи в этих таблицах ранее были для двух разных систем, однако сейчас мы объединяем наши системы аутентификации, и мне нужно убедиться, что в этих двух таблицах есть уникальные имена пользователей. (сейчас слишком много работы, чтобы поместить их все в один стол).

Ответы [ 7 ]

16 голосов
/ 03 января 2009

Вы не можете объявить ограничение 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.

4 голосов
/ 10 февраля 2012

лучший способ сделать это - объявить другую таблицу с уникальными столбцами и сделать так, чтобы несколько таблиц ссылались на эти таблицы

2 голосов
/ 03 января 2009

Возможно не прямой ответ на ваш вопрос, но:

Вам следует подумать о переписывании своего кода и реструктуризации базы данных, чтобы объединить эти две таблицы в одну.

Дизайн, который вы пытаетесь применить сейчас, усложнит ваш код и схему базы данных, а также затруднит дальнейшее обновление до другого программного обеспечения или платформ баз данных.

1 голос
/ 03 января 2009

Вы можете добавить дополнительную таблицу с одним столбцом в качестве первичного ключа. Затем создайте триггер для каждой из ваших старых пользовательских таблиц, чтобы вставить идентификатор в эту дополнительную таблицу.

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;
0 голосов
/ 03 января 2009

Будет ли возможным изменение типа столбца идентификатора? Тогда вы можете использовать GUID, который будет уникальным для любого количества таблиц.

0 голосов
/ 03 января 2009

Я не знаю MySQL, но именно так вы можете сделать это в Oracle, и я считаю, что MySQL поддерживает материализованные представления.

Вы создаете материализованное представление для этих двух таблиц. И вы добавляете уникальное ограничение на это представление.

Это представление необходимо обновлять каждый раз, когда вносится изменение в одну из двух базовых таблиц.

0 голосов
/ 03 января 2009

Очевидно, что если в двух таблицах уже есть дубликаты, вам придется решить эту проблему вручную. Двигаясь вперед, вы можете написать триггер, который проверяет обе таблицы, чтобы узнать, существует ли уже значение, а затем применить его к обеим таблицам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...