Mysql 时间戳是否有一个与上次插入相同的ID?

Mysql 时间戳是否有一个与上次插入相同的ID?,mysql,timestamp,last-insert-id,Mysql,Timestamp,Last Insert Id,我喜欢MySQL的最后一个函数。我一直使用它来检索刚插入的行的id,然后从存储过程返回。但是,现在我有一个表,它的主键是TIMESTAMP,设置为默认的CURRENT_TIMESTAMP。如何检索上次插入的时间戳?使用时间戳字段上的MAX方法。这样做应该安全: START TRANSACTION; {do your insert}; SELECT MAX({timestamp field}) FROM {table}; COMMIT; 另一种方法是利用该函数的版本,它实际上可以将值设置为您喜欢

我喜欢MySQL的最后一个函数。我一直使用它来检索刚插入的行的id,然后从存储过程返回。但是,现在我有一个表,它的主键是TIMESTAMP,设置为默认的CURRENT_TIMESTAMP。如何检索上次插入的时间戳?

使用时间戳字段上的
MAX
方法。

这样做应该安全:

START TRANSACTION;
{do your insert};
SELECT MAX({timestamp field}) FROM {table};
COMMIT;

另一种方法是利用该函数的版本,它实际上可以将值设置为您喜欢的任何整数(可能是时间戳的UNIX\u时间戳整数):

现在您可以:

SELECT FROM_UNIXTIME(LAST_INSERT_ID());
与Jon Harmon提供的事务解决方案一样,此解决方案的一个缺点是必须在插入时牢记这一点(使用相同的值显式覆盖列的默认值,或者启动事务)。代码可读性降低了一点,这会使希望使用此表的其他人感到困惑。我认为Jon的解决方案在保持可读性方面做得更好

另外,请记住,如果你在触发器中执行此操作

但是,如果确实需要,可以使用会话变量将其从触发器中冒泡出来


尝试以下设置
LAST\u INSERT\u ID
的示例:

SELECT FROM_UNIXTIME(LAST_INSERT_ID(UNIX_TIMESTAMP()));
SELECT FROM_UNIXTIME(LAST_INSERT_ID());

但这并不像上次插入ID那样是并发安全的,是吗?因为这就是为什么我们不对id字段使用MAX方法。@SimonBaars:如果使用可重复读取事务隔离,则自事务启动后,事务将不会看到并发客户端插入的任何行。您必须仔细检查错误,因为如果插入失败,MAX()将返回一个值,而您认为不应该返回。FWIW,我不会使用时间戳作为主键,因为冲突的可能性太大。@SimonBaars我认为
LAST\u INSERT\u ID
也会这样做,并返回最大值id@DeepanshSachdeva,LAST_INSERT_ID()不返回最大ID。它返回当前会话中插入生成的最新ID。如果其他并发客户端随后生成更大的id值,会话仍将返回会话生成的id。您可以在终端窗口中并排打开两个会话,在每个窗口中插入并选择last_insert_id(),来证明这一点。@BillKarwin噢!感谢您提供正确的信息:)如果并发插入产生相同的当前\u时间戳,会发生什么情况?你确定这是你pk的好选择吗?@AlexK。OP可能在时间戳上使用毫秒精度,但它仍然有相当高的冲突几率。这不是一个好的选择,因为插入会经常失败,需要重新执行。虽然我一般都同意@BillKarwin的观点,但偶尔也会出现这样的情况,即时间确实是(或是)自然标识符的一部分,而且我还想利用唯一约束将错误发回尝试的任何应用程序或存储过程。“这是一个功能!”@ChristopherMcGowan,是的,如果设计中不应该有多行具有相同的时间戳,那没关系。虽然我提供了一个替代方案,但我实际上更喜欢您在事务中这样做,因为这是为其他人(和我自己)阅读的最直接的方式几个月后:-P。伟大的选择!谢谢
SELECT FROM_UNIXTIME(LAST_INSERT_ID(UNIX_TIMESTAMP()));
SELECT FROM_UNIXTIME(LAST_INSERT_ID());