在触发器中生成ID以生成进一步的请求

问题描述

我有一个包含两列的表:

  • 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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...