Php 检索InnoDB复合键表的上次插入ID

Php 检索InnoDB复合键表的上次插入ID,php,mysql,pdo,auto-increment,Php,Mysql,Pdo,Auto Increment,我有下表: CREATE TABLE `my_table` ( composite_pk1 INT NOT NULL , composite_pk2 INT NOT NULL , data VARCHAR(255) NOT NULL , primary key (composite_pk1, composite_pk2) ) ENGINE=InnoDB; 对于给定的composite_pk1,我希望composite_pk2充当自动递增主键。我不希望锁定表,因此计划使用触发

我有下表:

CREATE  TABLE `my_table` (
  composite_pk1 INT NOT NULL ,
  composite_pk2 INT NOT NULL ,
  data VARCHAR(255) NOT NULL ,
   primary key (composite_pk1, composite_pk2)
) ENGINE=InnoDB;
对于给定的
composite_pk1
,我希望
composite_pk2
充当自动递增主键。我不希望锁定表,因此计划使用触发器,如以下所示:

DELIMITER $$

CREATE TRIGGER my_trigger BEFORE INSERT ON my_table
FOR EACH ROW BEGIN
    SET NEW.composite_pk2 = (
       SELECT IFNULL(MAX(composite_pk2), 0) + 1
       FROM issue_log
       WHERE composite_pk1  = NEW.composite_pk1
 );

END $$
我现在可以插入一条记录:

$stmt=$myDB->prepare('INSERT INTO my_table(composite_pk1, data) VALUES (?,?)');
$stmt->execute([123,'hello']);

如何获取最后一次插入的
composite_pk2
<代码>PDO::lastInsertId仅适用于本机自动增量表(即,不是触发器方法)。我“可以”稍后执行SELECT查询以获取最大值,但是,不能保证另一条记录已经潜入。

您可以使用
自动增量
复合\u pk2
设置为唯一键:

CREATE  TABLE `my_table` (
  composite_pk1 INT NOT NULL ,
  composite_pk2 INT NOT NULL unique auto_increment,
  data VARCHAR(255) NOT NULL ,
   primary key (composite_pk1, composite_pk2)
) ENGINE=InnoDB;

现在,
last\u insert\u id()
将返回最近为
composite\u pk2

创建的id。不幸的是,这并不是一个好方法。您可能面临的另一个问题是MAX函数返回另一个update/insert语句由于读取一致性而刚刚使用的值。你可以争夺那个号码。复合_pk2的顺序重要吗?@TGray触发器不会确保没有更新/插入悄悄进入吗?“阅读一致性”是什么意思?关于组合pk2的重要性顺序,你们是什么意思?谢谢1-不,触发器不会锁定一个值,这意味着处理完全不同的记录的人也可能在您工作时检索到最大值。2 -读一致性意味着“我工作在一个副本的数据,而其他人在一个副本上工作-如果在我看着它的时候发生了什么变化,直到我的触发器失败了(例如),我不知道。3—CypItEypK2必须被排序- 1, 2, 3,4,…?如果不是,你可以考虑使用UUID()。而不是函数定义的数值。@TGray啊,谢谢你的#1和#2。关于#3,顺序会很好,但不是必需的,并且在必要时考虑uuid(但是不喜欢额外的重量)。is
uuid()
通常用于首先生成并返回密钥,然后插入到单独的查询中?如果没有,如何将其返回到应用程序?使用InnoDB engine?@user1032531,是的。根据,
last\u insert\u id()
返回自动递增的id。我发誓我读到你不能用InnoDB这样做,但你的解决方案似乎有效。谢谢!复合\u pk2上唯一索引的原因是什么?
last\u insert\u id()
不会对InnoDB中的每个
组合_pk1
单独递增。我认为这个答案有效时,我对它投了赞成票。@user1032531,对。id是表中唯一的。因为您考虑使用uuid,我认为它是可以接受的