2015-05-10 27 views
0

我期待根据MySQL数据库生成一个没有重复的随机数。我如何更改以下函数,以便它检查数据库,如果生成的数字已经存在,并且如果不存在,则将其插入到表中。另外,如何布置表格?我不是最好的设计行,使他们尽可能小(和实用)。生成非重复数字,对数据库保持警惕

功能:

function genNonRepNum($min, $max, $quantity) { 
    $numbers = range($min, $max); 
    shuffle($numbers); 
    return array_slice($numbers, 0, $quantity); 
} 


使用功能:

print_r(genNonRepNum(1000, 10000, 3)); 

回报:

Array ([0] => 8586 [1] => 9666 [2] => 8169) 

这是真棒,但我只希望它检查一个数据库,看看它是否存在,如果没有,就插入它。提前致谢。

+0

使db索引唯一,那么现有数字的任何插入都将失败 –

+0

这可以解决插入它们的问题,但它并不能真正回答我的问题。另外,如果我使用它,我是否必须使用'try'块来插入它们,如果它失败了,或者如果我打电话它会好吗? – Zak

+1

在问题中没有插入,我不知道你的方法 –

回答

2

此处的解决方案是对自动递增数字使用加密。作为我的意思的一个例子,想象一下你有一个加密算法,它采用8位密钥并且输出8位加密数据。如果您使用了相同的密钥并对值0至255进行了加密,则会以不同的顺序输出所有0到255的值。您无法获取任何重复项,因为按定义加密是可逆的,这意味着两个不同的值无法使用相同的密钥和算法加密为相同的值,因为您无法解密它。由于像雪崩效应这样的密码质量,数字序列会显得随机。所以基本上,你只需要用一个秘密密钥来加密一个自动递增的数字,根据你的质量和速度需求使用你选择的算法。这就是新的信用卡号码的生成方式,同时表示卡号还没有发出。有关更多信息,请查阅“格式保留加密”。

+0

顺便说一句,这也是一个很好的方式来洗牌大型列表或大范围的值,而不必实际洗牌或存储列表。 –

+0

我非常喜欢这个主意。谢谢!我可以从这里弄出一切。 – Zak

+0

太棒了!祝你好运,并与朋友分享技术。它非常有用,但人们似乎并不知道它:p –

0

我认为这不是你应该去做的方式只是使用php openssl-random-pseudo-bytes它给你一串随机字节(任何加密安全的随机生成器/散列函数,可以创建不可预知的安全ID将完成工作) - 这个将给是肯定不同的(或极不可能在理论上是相同的)键,或者如果你想有一个很好的使用次数自动递增并获得lastinsert_id通过驱动程序如提供:

mysqli_insert_id() 
PDO::lastInsertId() 

后查询执行并在软件中使用它

手动检查是否插入并重试既贵又不好,应该避免

请尽量保持您的旅行数据库到最低!!!!!!!

0

首先,通常你不这样做 - 你可以设计一个足够大的数字,使得碰撞概率可以忽略不计,然后使用一个强大的随机生成器来生成这个大小的随机数。除非你实现某种深奥的密码方案 - 例如你可以存储一个计数器并使用AES进行加密;当然这些数字并不是真正的“随机的” “,但他们也不容易预测),并且您必须在开始时定义随机范围,您可以创建一个已插入随机数的表格:用连续数字填充表格,然后插入另一个具有唯一通过RAND()进行的auto_increment键排序。

现在,当您需要一个随机数时,您获取表的第i个元素并读取其value列,然后递增i以确保您不重复使用该数字。如果两个进程都需要一个随机数,您将需要使用锁定和事务。

这还有一个好处,就是当号码池将要变干时,此时您可以插入新号码。这会稍微随机(第一百万个数字在0-999999范围内是随机的,第二个百万个数字将在1000000-1999999范围内),但是对于您的目的来说也许就足够了。

或者你可以创建两个独特的列

CREATE TABLE randompool (
    id integer not null primary key auto_increment, 
    value integer 
); 
CREATE UNIQUE INDEX randompool_uniq ON randompool(value); 

,并使用二次加工,以检查随机表,当一个全局变量的地方保存,NEXT_ID,是说的COUNT(*) FROM randompool 10%之内 - 这意味着随机池下降到了10%的能力 - 而且,如果是的话,产生一些随机数和尝试将它们插入

INSERT IGNORE INTO randompool (value) VALUES (?),(?),(?),... 

当然,更大randompool,效率较低这一Ø peration。当randompool包含2亿个数字时,生成一个随机的带符号32位数的随机数将有10%的击中副本并被拒绝的概率,因此插入1000个新的随机数将比开始时按比例增加成本;还考虑到索引重复查找会花费更多。没有更多,但更多。但是,如果这个过程是独立的,并且在系统负载不太高的情况下运行,这可能不是问题。

随机数的选择仍然使用NEXT_ID计数器直接从表中读取它们,因此读取数字将非常便宜。