mysql LAST_INSERT_ID 带参数序列实现
mysql LAST_INSERT_ID with parameter sequence implementation
在 mysql 中创建线程安全序列时,我遇到了 mysql 文档 - https://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_last-insert-id,建议创建这样的序列 -
1. mysql> CREATE TABLE sequence (id INT NOT NULL);
2. mysql> INSERT INTO sequence VALUES (0);
3. mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
4. mysql> SELECT LAST_INSERT_ID();
我的问题不是第 4 步,为什么我不能在每次需要获取新 ID 时直接查询序列 table 来获取 ID?像这样 - SELECT id FROM sequence;按照文档中的建议直接查询序列 table 与 LAST_INSERT_ID 有什么缺点吗?
我的 mysql 实现如下所示 -
CREATE TABLE sequence (id INT NOT NULL);
INSERT INTO sequence VALUES (0);
DELIMITER //
CREATE PROCEDURE nextVal(OUT nextval INT)
BEGIN
UPDATE sequence SET id=LAST_INSERT_ID(id+1);
SELECT id into nextval FROM sequence;
END //
DELIMITER ;
为了生成新的 ID,我可以使用这个
call nextVal(@output1);
select @output1;
Edit1:在与所有回复的人交谈后,更新序列创建过程,以解除锁定。我还使 table 更通用,以在单个 table 中容纳多个序列,并使用函数代替过程
CREATE TABLE sequences (
name CHAR(20),
id BIGINT DEFAULT 1,
increment TINYINT,
UNIQUE KEY(name)
);
/* Call nextval('seqname'), and it returns the next value. */
/* If the named sequence does not yet exist, it is created with initial value 1 and increment 1 */
DELIMITER //
CREATE FUNCTION nextval (seqname CHAR(20))
RETURNS BIGINT
BEGIN
INSERT INTO sequences(name,id,increment) VALUES (seqname,LAST_INSERT_ID(1),1)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id+increment);
RETURN LAST_INSERT_ID();
END
//
/* Testing */
SELECT nextval('seq1');
SELECT nextval('seq2');
insert into sequences(name,id,increment) values ('seq3', 1000, 5);
SELECT nextval('seq3');
如果另一个客户端 运行 同时执行您的程序,您的程序将无法运行,因为它们都在更新 sequence
table 的同一行。您需要 运行 交易中的 UPDATE
和 SELECT
以防止重叠。
LAST_INSERT_ID()
是在每个连接的基础上进行管理的,因此每个客户端都有自己的序列,而不必通过事务相互锁定。
在 mysql 中创建线程安全序列时,我遇到了 mysql 文档 - https://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_last-insert-id,建议创建这样的序列 -
1. mysql> CREATE TABLE sequence (id INT NOT NULL);
2. mysql> INSERT INTO sequence VALUES (0);
3. mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
4. mysql> SELECT LAST_INSERT_ID();
我的问题不是第 4 步,为什么我不能在每次需要获取新 ID 时直接查询序列 table 来获取 ID?像这样 - SELECT id FROM sequence;按照文档中的建议直接查询序列 table 与 LAST_INSERT_ID 有什么缺点吗?
我的 mysql 实现如下所示 -
CREATE TABLE sequence (id INT NOT NULL);
INSERT INTO sequence VALUES (0);
DELIMITER //
CREATE PROCEDURE nextVal(OUT nextval INT)
BEGIN
UPDATE sequence SET id=LAST_INSERT_ID(id+1);
SELECT id into nextval FROM sequence;
END //
DELIMITER ;
为了生成新的 ID,我可以使用这个
call nextVal(@output1);
select @output1;
Edit1:在与所有回复的人交谈后,更新序列创建过程,以解除锁定。我还使 table 更通用,以在单个 table 中容纳多个序列,并使用函数代替过程
CREATE TABLE sequences (
name CHAR(20),
id BIGINT DEFAULT 1,
increment TINYINT,
UNIQUE KEY(name)
);
/* Call nextval('seqname'), and it returns the next value. */
/* If the named sequence does not yet exist, it is created with initial value 1 and increment 1 */
DELIMITER //
CREATE FUNCTION nextval (seqname CHAR(20))
RETURNS BIGINT
BEGIN
INSERT INTO sequences(name,id,increment) VALUES (seqname,LAST_INSERT_ID(1),1)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id+increment);
RETURN LAST_INSERT_ID();
END
//
/* Testing */
SELECT nextval('seq1');
SELECT nextval('seq2');
insert into sequences(name,id,increment) values ('seq3', 1000, 5);
SELECT nextval('seq3');
如果另一个客户端 运行 同时执行您的程序,您的程序将无法运行,因为它们都在更新 sequence
table 的同一行。您需要 运行 交易中的 UPDATE
和 SELECT
以防止重叠。
LAST_INSERT_ID()
是在每个连接的基础上进行管理的,因此每个客户端都有自己的序列,而不必通过事务相互锁定。