问题描述
我有一个包含两列的表:
- caseId,引用外部表列
- caseEventId,整数,唯一(对于给定的caseId),我想针对相同的caseId自动递增。
我知道基于 InnoDb 的 mySql 中不提供基于另一列的自动递增选项:
MySQL Auto Increment Based on Foreign Key
MySQL second auto increment field based on foreign key
所以我将caseEventId生成到触发器中。我的桌子:
CREATE TABLE IF NOT EXISTS mydb.caseEvent (
`caseId` CHAR(20) NOT NULL,`caseEventId` INT NOT NULL DEFAULT 0,PRIMARY KEY (`caseId`,`caseEventId`),# Foreign key definition,not important here.
ENGINE = InnoDB;
还有我的触发器:
CREATE DEFINER=`root`@`%` TRIGGER `mydb`.`caseEvent_BEFORE_INSERT` BEFORE INSERT ON `caseEvent` FOR EACH ROW
BEGIN
SELECT COALESCE((SELECT MAX(caseEventId) + 1 FROM caseEvent WHERE caseId = NEW.caseId),0)
INTO @newCaseEventId;
SET NEW.`caseEventId` = @newCaseEventId;
END
有了这个,我得到了caseEventId,它会自动递增。
但是我需要在INSERT事务中的进一步调用中重新使用此新的caseEventId,因此我将此ID放入触发器内的@newCaseEventId中,并在以下说明中使用它:
START TRANSACTION;
INSERT INTO mydb.caseEvent (caseId) VALUES ('fziNw6muQ20VGYwYPW1b');
SELECT @newCaseEventId;
# Do stuff based on @newCaseEventId
COMMIT;
这似乎很好用,但是...并发,使用连接池等...
此@newCaseEventId变量是否将与使用同一连接的所有客户端共享,当客户端服务器启动两个并发事务时是否会出现问题?这是在nodejs下使用mysql。
这安全吗,或者有更安全的方法进行此操作?谢谢。
编辑2020/09/24
仅供参考,我完全放弃了这种方法。我试图以一种不被使用的方式使用数据库。
基本上,我删除了caseEventId,以及应该根据给定的列值很好地递增的任何索引。
当我检索数据时,我依赖读取端正确编写的查询来重新创建我的caseEventId字段...
解决方法
没关系,用户为每个客户端定义了一个变量。
这意味着每个用户都有其自己的使用定义的变量
用户定义的变量是特定于会话的。一个客户端定义的用户变量不能被其他客户端看到或使用。 (例外:有权访问性能模式user_variables_by_thread表的用户可以查看所有会话的所有用户变量。)给定客户端会话的所有变量在该客户端退出时会自动释放。 see manul