目前尚不完全清楚您要解决什么问题。
但听起来好像您有两个表,其中有一个 id 列,并且您希望确保两个表中都没有使用 id 的 same 值。也就是说,如果id 值42 存在于table1 中,您要确保42 不用作id 值在table2 中。
不幸的是,MySQL 没有为此提供任何声明性约束。
听起来好像您想要一个 Oracle 风格的 SEQUENCE 对象。不幸的是,MySQL 没有提供等价物。
但我们能做的就是效仿。创建一个包含 AUTO_INCREMENT 列的额外“序列”表。此表的目的是用于生成id 值,并跟踪生成的最高id 值:
CREATE TABLE mysequence (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
然后,我们将删除两个表的id 列中的AUTO_INCREMENT 属性,我们要为其生成不同的id 值。
对于这些表,我们将创建BEFORE INSERT 触发器,该触发器将获得不同的id 值并将其分配给id 列。要生成唯一值,我们可以在新的mysequence 表中插入一行,然后使用LAST_INSERT_ID 函数检索 auto_increment 值。
类似这样的:
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 值是否已存在于另一个表中,如果存在则引发错误。但是该查询会受到竞争条件的影响......两个并发会话对表进行插入,并且您需要实现一些并发终止锁定机制以防止并发插入。