MySQL非顺序ID

时间:2018-04-19 18:08:53

标签: mysql triggers auto-increment last-insert-id

挑战:

创建一种方法,以非顺序方式为表设置“auto_increment”值。 目标是覆盖“auto_increment”机制并允许函数“LAST_INSERT_ID()”继续按预期工作(返回INT),这样软件方面就不需要进行任何更改。

我的解决方案

我找到的方法基于辅助表( unique_id ),它存储可分配的值。然后随机选择值,并从使用的表中删除。当表变空时,会创建一组新的ID。

此示例按预期工作,但有一个问题。 演示表:

CREATE TABLE `unique_id` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=100;

CREATE TABLE `test_unique_id` (
   `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
   `name` VARCHAR(50) NOT NULL DEFAULT '0',
   PRIMARY KEY (`id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;

定义了存储过程和函数:

DELIMITER $$  
DROP PROCEDURE IF EXISTS `UNIQUE_ID_REFILL`$$
CREATE PROCEDURE UNIQUE_ID_REFILL()
BEGIN
   DECLARE a INT Default 0 ;
   simple_loop: LOOP
      SET a=a+1;
      INSERT INTO unique_id (id) values(null);
      IF a=100 THEN
         LEAVE simple_loop;
      END IF;
   END LOOP simple_loop;
END $$

DROP FUNCTION IF EXISTS `UNIQUE_ID_GET`$$
CREATE FUNCTION UNIQUE_ID_GET()
RETURNS INT(11)
MODIFIES SQL DATA
BEGIN
    DECLARE new_id INT(11);
    DECLARE unique_id_count INT(11);
    SET new_id = 0;
    SELECT COUNT(*) INTO unique_id_count FROM unique_id;
    IF unique_id_count=0 THEN
        CALL UNIQUE_ID_REFILL();
    END IF;
    SELECT id INTO new_id FROM unique_id ORDER BY RAND() LIMIT 1;
    DELETE FROM unique_id WHERE id = new_id;
    RETURN new_id;
END $$

在目标表( test_unique_id )上创建了一个触发器:

CREATE TRIGGER test_unique_id__unique_id BEFORE INSERT ON test_unique_id
  FOR EACH ROW 
    SET NEW.id = UNIQUE_ID_GET();

解决方案是按预期获得随机ID:

INSERT INTO test_unique_id(name) VALUES ('A'),('B'),('C');

创建行:

id   name
154  'A'
129  'B'
173  'C'

问题

主要问题是LAST_INSERT_ID()停止工作......软件方面坏了:

SELECT LAST_INSERT_ID();
0

有关如何解决此问题的任何想法?或任何其他不同的挑战方法?

非常感谢。

0 个答案:

没有答案