mySQL:获取一个随机的唯一整数ID



我试图编写一个SQL功能,该函数在1000000和4294967295之间生成未使用的唯一ID。我需要数字值,因此UUID()都不是解决方案。听起来并不困难,但是由于某种原因,下面的代码在表上的插入插入中称为主键的值(当然不是自动iNcrement)。该声明就像 INSERT INTO table (id, content) VALUES ((SELECT getRandomID(0,0)), 'blabla bla');(由于此类函数不允许默认值,因此我很快就将每个参数提交0,并将其设置为所需的值。)

呼叫一次,与插入或python代码分开,一切都很好。调用几次,不仅发生了一些奇怪的事情,而且服务器也可能挂在REPEAT中。然后,该过程甚至不可能杀死/重新开始。我必须重新启动机器-.-它似乎也只有一些随机值为我准备,因为在调用一些呼叫后一次又一次出现相同的值,但我实际上认为内部rand()将是外部rand()的足够的启动/种子。从Python召集的循环在经过一些回合后开始悬挂,尽管我的测试中的第一个总是会产生有用的新ID,因此在第一轮后应该退出。wyh?好吧,表是空的...所以SELECT COUNT(*)...返回0,这实际上是离开循环的信号……但事实并非如此。

有什么想法吗?我正在运行MariaDB 10.在SLES 12.2上的工作。这是导出的源代码:

DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `getRandomID`(`rangeStart` BIGINT UNSIGNED, `rangeEnd` BIGINT UNSIGNED) RETURNS bigint(20) unsigned
READS SQL DATA
BEGIN
    DECLARE rnd BIGINT unsigned; 
    DECLARE i BIGINT unsigned; 
    IF rangeStart is null OR rangeStart < 1 THEN
        SET rangeStart = 1000000;
    END IF;
    IF rangeEnd is null OR rangeEnd < 1 THEN
        SET rangeEnd = 4294967295; 
    END IF; 
    SET i = 0;
    r: REPEAT
        SET rnd = FLOOR(rangeStart + RAND(RAND(FLOOR(1 + rand() * 1000000000))*10) * (rangeEnd - rangeStart));
        SELECT COUNT(*) INTO i FROM `table` WHERE `id` = rnd;    
    UNTIL i = 0 END REPEAT r; 
    RETURN rnd;
END$$
DELIMITER ;

略有改进:

    SELECT COUNT(*) INTO i FROM `table` WHERE `id` = rnd;    
UNTIL i = 0 END REPEAT r; 

->

UNTIL NOT EXISTS( SELECT 1 FROM `table` WHERE id = rnd ) REPEAT r; 

不要将任何参数传递给RAND-这是为了建立可重复的随机数序列。

mysql> SELECT RAND(123), RAND(123), RAND(), RAND()G
*************************** 1. row ***************************
RAND(123): 0.9277428611440052
RAND(123): 0.9277428611440052
   RAND(): 0.5645420109522921
   RAND(): 0.12561983719991504
1 row in set (0.00 sec)

如此简化

    SET rnd = FLOOR(rangeStart + RAND() * (rangeEnd - rangeStart));

如果要在可能的输出中包括rangeEnd,请添加1:

    SET rnd = FLOOR(rangeStart + RAND() * (rangeEnd - rangeStart + 1));

相关内容

  • 没有找到相关文章

最新更新