Hen*_*nte 7 database-design uniqueidentifier e-commerce
考虑以下因素:
a)你想要一些机密性(因为没有告诉每个人你收到了多少订单).
b)您想校验位(例如,使用费尔赫夫算法)在年底,所以你可以很容易地分辨拼错和帮助条形码扫描时,如果是这样的情况下,处理错误.
c)您需要考虑时间,以便消费者可以对订单的顺序进行排序.
d)它应该是全数字还是十六进制等?
E)东西,你的消费者可以说通过电话支持团队和刚好够识别顺序,不必问,因为安全问题的电子邮件等,工作人员.
我很想听听一些意见.
PS:任何为解决这个问题而设计的算法对我来说都是一个有效的答案.
这是我的解决方案.
有一个三部分xyz,其中x是时间戳,y是随机码,z是由x和y的串联产生的校验位.但是为了简化(使其更小),x和y在自定义基础中给出,而不是数字基础10,但是仍然在基数10给出z.
使用此方法可以获得的ID示例:
因此,您可以按时间戳进行排序(如果您不确切知道数字基数是什么,请注意它是如何以'增量字母数字'顺序排列的).
为此,我使用了base58的数字+大写字母(最后,如果我使用小写或上部,则无关紧要),这是base62而没有一些令人困惑的字符.Flickr,bit.ly和其他人使用base58来制作Twitter'友好'链接等.
下面的Verhoeff :: calcsum是Dahnielson的Verhoeff的Dihedral Group D5 Check.我所做的唯一编辑是将他的代码放在一个类中,所以它也是一样的.
这里有一些代码:(*稍微改进了我在那里的承诺^)
<?php
$time_divisor = 3;
$base = "123456789ABCDEFGHJKLMNPQRSTUVWXYZ";//consider using another base **see note below**
$lower_limit = 50000;//just to avoiding to confuse the user with a lower number
$upper_limit = 1291467968;//1291467968 == ZZZZZZ in this base I used
//you can check the limit with base_decode("ZZZZZZ", $base);
$ptime = (int)($_SERVER['REQUEST_TIME']/$time_divisor);//or time();
$rand1 = mt_rand($lower_limit, $upper_limi);
$rand2 = mt_rand($lower_limit, $upper_limi);
$ptime_b = base_encode($time, $base);
$rand1_b = base_encode($rand1, $base);
$rand2_b = base_encode($rand2, $base);
$order_id = $ptime_b.$rand1_b.$rand2_b.Verhoeff::calcsum($time.$rand1.$rand2);
echo $order_id;
?>
Run Code Online (Sandbox Code Playgroud)
在我写完这篇文章之后,另一个可能出现问题的东西出现在我脑海中.我记得你不希望你的消费者感到受到侮辱.因此,即使认为诸如'f?ck'或'4ss'之类的坏词最终也可能出现(而且几乎肯定会出现),明确的词语(如在前一词中改变'a'的'4')绝对不是.因此,我建议您使用以下备用base/upper_limit:
<?php
$lower_limit = 27000;//=2111
$upper_limit = 809999;//=ZZZZ
$base = "123456789BCDFGHJKLMNPQRSTVWXYZ";//erased -a -e -u
?>
Run Code Online (Sandbox Code Playgroud)
请注意,如果您尝试使用更大的数字,您将达到PHP的上限int以及mt_rand限制,这可以通过mt_getrandmax()看到.另外,我想说,因为我看到mt_rand的熵就足够了.
如果你需要更大的随机部分数字,我建议只需要添加mt_rand(i,j)之类的第三部分; 其中i和j是你的基数的最小值和最大值,它将增加$ num-chars长度的订单ID(实际上我做了这个,带有上面的配置).
在数据库方面,它是一个独特的领域,以避免碰撞.
谢谢你们.
您认为合适的任意长度的随机字符串怎么样?使用不易与其他字符混淆的字符用于通过电话阅读。因此,在每个订单上调用如下内容:
public static string GetRandomString(int length)
{
char[] chars = "ACDEFGHJKMNPQRTWXY34679".ToCharArray();
var crypto = new RNGCryptoServiceProvider();
var data = new byte[length];
crypto.GetNonZeroBytes(data);
var result = new StringBuilder(length);
for (int i = 0; i < data.Length; i++)
{
result.Append(chars[data[i] % chars.Length]);
}
return result.ToString();
}
Run Code Online (Sandbox Code Playgroud)
猜测上述方法返回的 8 个字符的概率为 1/282429536481。并且您将通过唯一约束来保持数据库的完整性,对吧?