2011-07-11 75 views
2

有什么办法可以让我的模型ID(主键)生成随机唯一的8位数字,只包含数字而不是默认的自动增量? 一位客户请求了这个特定的8位数字的功能,所以我不能多说理由。自定义唯一ID

我想使用PHP uniqid,但它是13位数字,也包含字母。

有什么想法?

谢谢。

更新

我忘了告诉我需要的ID随机生成的被保存每一个新的纪录。

只是想问一下生成ID的机制,然后保存ID(也是属性)。我是否必须首先检查随机生成的ID是否存在另一个相同的密钥,然后保存属性或什么?

+1

身份证必须是随机的,还是只有8位? –

+0

这个ID必须是随机的 –

回答

1

是的,你可以。当谈论AI时,我假设你在MySQL上。只是不要将它设置为自动增量,并为其他列插入值。您可以创建一个函数或方法,它将随机或按特定顺序(算法)最多占用8个数字。

​​。

考虑INT(11)值可能接受从-2147483648到2147483647.这将适合你8位数的数字。如果在稍后客户端请求更大的数字,您可能需要切换到BIGINT。

我用它来设置主键为无符号,它允许你一个0到4294967295

之间的配合数为PHP函数 - 8位数字生成器:

<?php 

mt_srand(); 
$id = mt_rand(10000000, 99999999); 

?> 

你可以阅读更多关于在PHP文档上的mt_srand()和mt_rand()。据说他们比srand()和rand()更好。

+0

让它随机生成一个ID是一个坏主意,我们可以有多个具有相同ID的行,这会造成很大的问题。这就是为什么我建议填充实际ID,以便它有13位数字。 – dotty

+0

@dotty:这就是为什么你使用数据库'UNIQUE'约束。 – phant0m

+0

是的,这是样本,您的方法也适用,作为第三个。另一个检查是必要的。 是的,这也是事实,主键也是唯一的。 – Rolice

1

保留ID,但填充它。

$id = 6; 
$padded_id = sprintf("%013d", $id); 
// This will print 0000000000006 

那将垫$id,以便它的13位长。

每当您需要显示ID时,请使用一个函数将其转换,如下所示。

function padId($id){ 
    return sprintf("%013d", $id); 
} 

或者你可以让你的表称为pad-id一排,然后运行该功能,当你创建一个记录(与mysql_insert_id沿(获取ID刚刚插入))。

+0

这个工作,但他想得到8位数字。 –

+0

NINJA EDIT。你说的8位数字,我的例子打印13! – dotty

+0

在原始的问题,我的意思是:) –

3

为什么不保留自动增量,而是将其设置为从主键而不是1开始10000000?

ALTER TABLE some_table AUTO_INCREMENT=10000000

1

最好的方法取决于你的客户的随机性需求的一个细微环节 - 当他们说随机做他们的意思是完全不可预测的,或只是很难预测?在Lewinski的审判中,我的意思不是听起来像克林顿,但是当你的客户说随机会影响你是否有可能满足要求。

如果客户想要隐藏用户ID(对于某些感知到的安全性好处)并且使它们几乎不可能预测或反向工程,那么这非常困难。如果客户满意只是“难”预测(我怀疑),那么你可以做一些简单的事情,类似于MD5方法(@Dotty)。但md5不是collision resistant。即使使用最好的,可证明的独特哈希算法(其中md5不是),如果用户数量大于用户ID允许的数字位数(8),则会出现冲突问题。你有大约27位可以使用8位十进制数字。这意味着你可能在2^N/2 = 2 ^(27/2)之后发生冲突,这大约是10K用户。所以如果你的客户的用户列表接近10K用户,那么即使是最好的散列算法也会花费大量的时间过滤掉所有的冲突。 要解决这个问题,不使用过滤器和非确定性算法,只需使用简单的“Full Cycle”算法。有些会产生伪随机数(PRN),这些伪随机数保证是唯一的,并保证完全覆盖你想要覆盖的范围(例如,所有8位正整数的集合)。如果您需要对用户注册序列进行逆向工程,只需重新运行全循环PRN发生器,无论您使用什么初始值。如果您的客户想要让黑客更容易地对您的用户ID序列进行逆向工程,那么您可以保留这个初始值,像私人密钥一样。

您的客户端的另一个问题是在用户标识中是否允许前导零。如果是这样(并且客户的随机性要求是自由的),那么维基百科上的简单的Full Cycle算法将很适合你。它可以蒸馏成2行PHP。 无论使用哪种算法,最好在单独的表中生成正式的8位半随机用户ID列表,然后只要从表顶部“弹出”该值(删除该行)就可以了你添加一个新用户。数据库内存的要求不应该过高,并且会简化用户体验,消除由复杂的,非确定性的随机数生成器和唯一性过滤器引起的任何延迟和内存吞噬。试图在线创建用户ID,实际上,可以想象,您可以通过一些哈希算法无限期地阻止用户注册,从而进入永久循环。这种失速(由于永久碰撞)可能不会发生,直到用户1000或10000.相比之下,使用脱机查找表方法,您可以轻松地添加其他客户端指定的过滤器,如消除具有前导零的ID;如果客户从不想看到ID为1的用户(00000001)。而且你会事先知道是否所有东西都能正常工作,没有任何挂起。