假设您有一个随机数生成器吐出 1 到 100 000 000 之间的数字,并且您希望将它们存储在数据库 (MySQL) 中,并带有生成它们时的时间戳。如果出现了以前见过的数字,则将其丢弃。
实现这一目标的最佳算法是什么?根据需要选择然后插入?有什么更有效的吗?
假设您有一个随机数生成器吐出 1 到 100 000 000 之间的数字,并且您希望将它们存储在数据库 (MySQL) 中,并带有生成它们时的时间戳。如果出现了以前见过的数字,则将其丢弃。
实现这一目标的最佳算法是什么?根据需要选择然后插入?有什么更有效的吗?
如果不需要每次都插入新的随机值,可以使用 INSERT IGNORE 或 REPLACE INTO。否则你应该选择检查然后插入。
你可以去SEQUENCE
:
+
-
你可以这样SELECT ...
做INSERT ...
:
+
-
SELECT
并INSERT
以 2 个相等的数字结束;UNIQUE
约束,则先前的情况将导致异常;您可以选择INSERT ON DUPLICATE KEY UPDATE
,到目前为止,它似乎是最好的选择(看看"INSERT IGNORE" 与 "INSERT ... ON DUPLICATE KEY UPDATE"),至少在我看来,唯一的例外 - 不能移植到其他 RDBMS。
PS这篇文章与 MySQL 无关,但值得一读以了解在您的过程中可能发生的所有问题。
这通常可以通过在表中的随机数列上创建唯一索引来解决。您可以尝试看看 b 树与散列是否具有更好的性能。
如果您有大量内存,您可以预先填充一个包含 100,000,000 行的表——所有可能的值。然后,当您查看是否已创建某些内容时,您只需要查看时间戳是否为非空。但是,这将需要超过 1 GB 的 RAM 才能将表存储在内存中,并且只有在您尝试最大化每秒事务数时才是最佳解决方案。
如果您UNIQUE
在具有提取数字的列上放置索引,则任何复制键INSERT
的尝试都将失败。UNIQUE
因此,最简单和最便携的版本将是(PHP 代码,但你明白了):
function extraction() {
do {
$random = generate_random_number();
$result = @mysql_query("INSERT INTO extractions(number) VALUE ($random)");
} while (!$result);
return $random;
}