Применение уникальных значений в двух таблицах

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

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

Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
16
0
11 535
7

Ответы 7

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

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

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

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

К сожалению, MySQL не поддерживает материализованные представления.

Bill Karwin 03.01.2009 10:36

MySQL также не обеспечивает должного соблюдения целостности внешнего ключа. :(

Matthew Schinckel 03.01.2009 10:56

Даже с InnoDB? Я думал, что версия 5 подходит.

duffymo 03.01.2009 15:54

Механизм хранения MyISAM по умолчанию в MySQL не применяет внешние ключи, но InnoDB прост в использовании. InnoDB поддерживает внешние ключи более 4 лет.

Bill Karwin 03.01.2009 22:13

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

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;

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

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

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

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

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

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

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

Tomeh 14.10.2016 18:32

Другие вопросы по теме