使用MySQL生成唯一且随机的数字代码

4

初衷:

我想在表格中生成随机且唯一的代码(6位数字)。我使用以下SQL查询来实现这一目标:

SELECT SUBSTRING(CRC32(RAND()), 1, 6) as myCode
FROM `codes`
HAVING myCode NOT IN (SELECT code FROM `codes`)

我被问及当没有更多可用代码时,它将如何反应,因此我进行了以下测试


测试环境:

MySQL版本:5.5.20

MySQL数据表:

CREATE TABLE `codes` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`code` VARCHAR( 10 ) NOT NULL ,
UNIQUE (
`code`
)
) ENGINE = InnoDB;

初始数据:

INSERT INTO `codes` (`id`, `code`)
VALUES (NULL, '1'), (NULL, '2'), (NULL, '3'), (NULL, '4'), (NULL, '5'), (NULL, '6'), (NULL, '7'), (NULL, '8');

SQL查询:

SELECT SUBSTRING(CRC32(RAND()), 1, 1) as myCode
FROM `codes`
HAVING myCode NOT IN (SELECT code FROM `codes`)

通过执行这个查询,我期望它总是返回9,因为这是唯一不存在的一位数字代码。
但结果是:
- 有时它会返回任何行 - 有时它会返回已经存在的值的行
我不理解这种行为,所以如果有人能帮忙解释一下就好了 :)
所以重要问题是:
MySQL如何返回已经存在的值的行?
谢谢。

只需使用AUTO_INCREMENT即可。虽然不是随机的,但它将是唯一的。要求随机似乎毫无意义。 - DwB
1个回答

2

我会在一个名为 sequencetable 的表中填充所有可能的值,按顺序。

然后,随机查询将从 sequencetable 中随机选择记录,并每次选择一条记录后都会将其删除。这样,您肯定可以得到所有数字,而不需要浪费时间查找“空洞”的数字(尚未选择)。

CREATE TABLE `sequencetable` 
(
    `sequence` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`sequence`)
)
ENGINE=InnoDB
AUTO_INCREMENT=1;

填写序列(实际上不需要自动增量)。

DECLARE i INT;

SET i=1;
REPEAT
    INSERT INTO sequencetable VALUES (i);
    SET i=i+1;
UNTIL i>999999 END REPEAT;

从序列中随机选择一条记录(在循环中执行,直到有记录可用):
DECLARE sequencen INT;

SET sequencen = 
    (SELECT sequence FROM sequencetable ORDER BY RAND() LIMIT  1);

DELETE FROM sequencetable WHERE sequence = sequencen;

谢谢你的回答,Vulkanino。我一定会查看你的解决方案,但除了这个替代方案,我不理解MySQL的行为... MySQL如何返回我在查询中排除的值: HAVING myCode NOT IN (SELECT code FROM codes) - CocoRambo
SQL不是那样工作的,你想要在选择记录时排除它们! - vulkanino
“你想排除已选择的记录”是什么意思? - CocoRambo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接