mysql last_insert_id和参数序列实现

nue99wik  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(307)

在mysql中创建线程安全序列时,我偶然发现了mysql文档-https://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_last-插入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时直接查询sequence表来获取id?像这样-从序列中选择id;直接查询sequence表和文档中建议的last\u insert\u 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:在和所有回复的人交谈之后,更新序列创建过程,使其无锁。我还使表更加通用,以便在单个表中容纳多个序列,并使用函数而不是过程

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');
3gtaxfhh

3gtaxfhh1#

如果另一个客户端同时运行您的过程,则该过程将不起作用,因为它们都在更新 sequence table。你需要同时运行 UPDATE 以及 SELECT 在交易中防止重叠。 LAST_INSERT_ID() 在每个连接的基础上进行管理,因此每个客户机都有自己的序列,而不必用事务将彼此锁定。

相关问题