Неясно, в чем проблема, которую вы пытаетесь решить.
Но это звучит так, как будто у вас есть две таблицы со id
колонки, и вы хотите, чтобы убедиться, что значение id
же не используется в обеих таблицах. То есть, если id
значение 42
существует в table1
, вы хотите, чтобы 42
не использовался как id
значение в table2
.
К сожалению, MySQL не предоставляет каких-либо декларативных ограничений для этого.
Звучит так, как будто вы хотите объект SEQUENCE в стиле Oracle. И, к сожалению, MySQL не предоставляет эквивалент.
Но что мы можем сделать, это эмулировать это. Создайте дополнительную таблицу «sequence», которая содержит столбец AUTO_INCREMENT. Цель этой таблицы будет использоваться для генерации id
значений, и следить за самое высокое генерируемую id
значения:
CREATE TABLE mysequence (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
Тогда мы бы удалить атрибут AUTO_INCREMENT
из id
столбцов два таблицы, которые мы хотим генерировать отличные значения id
.
Для этих таблиц мы создадим триггеры BEFORE INSERT
, которые получат отличные значения id
и назначат их столбцу id
. Чтобы создать уникальное значение, мы можем вставить строку в новую таблицу mysequence
, а затем получить значение auto_increment с помощью функции LAST_INSERT_ID
.
Что-то вроде этого:
CREATE TRIGGER table1_bi
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
DECLARE generated_id INT UNSIGNED;
-- do we need to generate a value for id column?
IF NEW.id IS NULL THEN
-- generate unique id value with insert into sequence table
INSERT INTO mysequence (id) VALUES (NULL);
-- retrieve inserted id value
SELECT LAST_INSERT_ID() INTO generated_id;
-- assign the retrieved value to the id columns of the row being inserted
SET NEW.id = generated_id;
END IF
END$$
(. Это просто грубый набросок, скорее всего, есть по крайней мере одна ошибка синтаксиса где-то там)
Вы должны были бы создать BEFORE INSERT
триггер для каждого из столы.
Это один из подходов к созданию отдельных значений для столбцов id
.
Обратите внимание, что нет необходимости хранить ВСЕ строки в таблице mysequence
, необходимо сохранить строку с наибольшим значением id
.
Также обратите внимание, что это не накладывает ограничений на любые таблицы; какая-то сессия может предоставить значение для id
, которое уже находится в другой таблице. Чтобы предотвратить это, триггер может вызвать ошибку, если предоставляется значение, отличное от NULL id
. Также может быть возможно разрешить значения, отличные от NULL, и выполнить запрос, чтобы проверить, существует ли уже существующее значение id
в другой таблице и при возникновении ошибки возникает ошибка.Но этот запрос будет подвержен условию гонки ... два параллельных сеанса, выполняющих вставки в таблицы, и вам нужно будет реализовать некоторые механизмы блокировки блокировки параллелизма для предотвращения одновременных вставок.