2012-06-25 21 views
0

假设您有一个随机数生成器将数字分配到1到100 000 000之间,并且您希望在生成数据时将它们存储在具有时间戳的数据库(MySQL)中。如果以前看过的号码出现,它会被丢弃。维护数据库中的唯一值列表

什么是最好的算法来做到这一点?根据需要选择INSERT然后INSERT?有没有更有效率的东西?

+0

如何自增表?或者你可以创建一个序列。 –

回答

1
  1. 你可以去SEQUENCE

    +

    • 没有关系被锁定,从而获得最佳性能;
    • 没有比赛条件;
    • 便携式。

    -

    • 有可能在一系列数字让“差距”。
  2. 你可以做一个SELECT ...然后INSERT ...

    +

    • 没有间隙,你也可以做你的号码了一些复杂的数学。

    -

    • 有可能在SELECTINSERT之间的中间再弄平行会议和2个数量相等告终。
    • 如果存在UNIQUE约束,则previos的情况会导致异常;
    • 为了避免出现这种情况,您可能会寻求一个明确的表锁,但这会对性能产生直接的影响。
  3. 您可以选择INSERT ON DUPLICATE KEY UPDATE道路,现在它似乎是最好的选择(看看"INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE"),至少在我看来,唯一的例外 - 无法移植到其他的RDBMS。

P.S. This article与MySQL无关,但值得一读,以获得所有可能发生的捕获的概述。

+0

感谢您的出色反应,它确实给了我一些阅读和做一些思考! – paullb

1

如果在每次使用INSERT IGNORE或REPLACE INTO时不需要插入新的随机值。否则,你应该选择检查,然后插入。

0

这通常可以通过在表中的随机数字列上创建唯一索引来解决。你可以试验一下,看看b-tree和hash是否有更好的性能。

如果您有很多内存,您可以预先填充100,000,000行的表格 - 所有可能的值。然后,当你查看是否已经创建了一些东西时,你只需要看看时间戳是否为非空。但是,这需要超过1 GB的RAM才能将表存储在内存中,并且如果您试图每秒最大化事务处理量,则这只是最佳解决方案。

0

如果你把一个UNIQUE指数列与提取数字的任意INSERT试图复制UNIQUE失败

因此最简单和最便携的版本将是(PHP代码,但你的想法):

function extraction() { 
    do { 
    $random = generate_random_number(); 
    $result = @mysql_query("INSERT INTO extractions(number) VALUE ($random)"); 
    } while (!$result); 
    return $random; 
}