我正在使用特定查询来生成没有自动增量的ID:
'insert into global_ids (`id`) select (((max(id)>>4)+1)<<4)+1 from global_ids'
CREATE TABLE `global_ids` (
`id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
我有获取最后一个插入行id的问题(因为我没有使用自动增量,cur.lastrowid是None)
如何在我的情况下获取插入行id值的结果?
答案 0 :(得分:0)
如果您不关心竞争条件,则可以使用id
在表格中获得最高SELECT MAX(id) AS id FROM global_ids
值。
但是,你确实关心竞争条件。如果你的python程序的两个副本正在运行会发生什么?一个人可以做一个插入,然后另一个可以在第一个进行我所建议的选择之前进行插入。如果发生这种情况,则select将返回错误的值。
你可以尝试
START TRANSACTION;
SELECT (((max(id)>>4)+1)<<4)+1 INTO @id FROM global_ids WITH UPDATE;
INSERT INTO global_ids (id) VALUES (@id);
COMMIT;
SELECT @id AS id;
使用事务序列化id
生成/检索操作。 (这在MyISAM表中不起作用,因为它们忽略了事务。)
但是,在MySQL中避免竞争条件麻烦的最佳选择是实际使用自动增量功能。你可以试试这个。
CREATE TABLE global_ids (
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
)
然后一个接一个地发出这些查询:
INSERT INTO global_ids () VALUES ();
SELECT (((LAST_INSERT_ID()>>4)+1)<<4)+1 AS id;
这将使用自动递增功能生成转换后的id
值,而不会冒竞争条件的风险。