Database design 对于电子商务解决方案或付费web服务,什么是好的订单id方案?

Database design 对于电子商务解决方案或付费web服务,什么是好的订单id方案?,database-design,e-commerce,uniqueidentifier,Database Design,E Commerce,Uniqueidentifier,考虑到以下几点: a) 你需要保密(比如不告诉每个人你收到了多少订单) b) 您希望在末尾有一个校验位(例如,使用Verhoeff算法),这样您就可以很容易地辨别拼写错误,并在扫描条形码时帮助处理错误(如果是这种情况) 你必须考虑时间,以便消费者可以对订单的顺序进行排序。 d) 应该全部是数字还是十六进制等 e) 您的消费者可以通过电话向支持团队说的话,由于安全问题,这就足以识别订单,而无需员工要求发送电子邮件等 我想听听你的意见 PS:任何为解决这个问题而设计的算法对我来说都是有效的答案。你认

考虑到以下几点:

a) 你需要保密(比如不告诉每个人你收到了多少订单)

b) 您希望在末尾有一个校验位(例如,使用Verhoeff算法),这样您就可以很容易地辨别拼写错误,并在扫描条形码时帮助处理错误(如果是这种情况)

你必须考虑时间,以便消费者可以对订单的顺序进行排序。

d) 应该全部是数字还是十六进制等

e) 您的消费者可以通过电话向支持团队说的话,由于安全问题,这就足以识别订单,而无需员工要求发送电子邮件等

我想听听你的意见


PS:任何为解决这个问题而设计的算法对我来说都是有效的答案。

你认为合适的任意长度的随机字符串怎么样?使用不易与其他字符混淆的字符进行电话阅读。因此,每次订购时,都要打电话:

    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();
    }
publicstaticstring GetRandomString(int-length)
{
char[]chars=“ACDEFGHJKMNPQRTWXY34679”。tocharray();
var crypto=new RNGCryptoServiceProvider();
变量数据=新字节[长度];
加密。获取非零字节(数据);
var结果=新的StringBuilder(长度);
for(int i=0;i
猜测上述方法返回的8个字符的几率为1/282429536481。您将使用唯一的约束在数据库中保持完整性,对吗?

您可以使用。要将其缩减为客户友好的字符串,需要通过转换器运行该值,该转换器将生成一个包含26个a-Z字符和数字2-7的字符串

为了满足您的其他条件,您可以在guid值中附加一个校验位,并且您可能需要在数据库中使用一个单独的正版增量订单号来保证唯一性并允许自然索引/排序。

这是我的解决方案

有一个三部分x-y-z,其中x是时间戳,y是随机码,z是x和y串联产生的校验位。但为了简化(使其更小),x和y以自定义的基数给出,而不是以数字为基数10,但z仍然以基数10给出

使用此方法可以获得的ID示例:

  • LP9NTX-8D41-QW6R-9
  • LP9NTY-5H3L-BFS7-5
  • LP9NTZ-RWL3-D619-8
  • LP9NVB-BW74-788W-6
  • LP9NVW-G17D-4911-8
因此,您可以按时间戳进行排序(如果您不确切知道数字基数是什么,请注意它是如何以“增量字母数字”顺序排列的)

为此,我使用了的数字+大写字母(最后,我使用的是小写还是大写都无所谓),它是base62,没有一些令人困惑的字符

下面的Verhoeff::calcsum是我唯一做的编辑,就是把他的代码放在一个类中,所以它是一样的

下面是一些代码:(*与我在上面的行中承诺的有所修改^)


就在我写完这篇文章之后,我又想到了另一件可能出错的事情。我记得你不想让你的消费者感到被侮辱。因此,即使像“f?ck”或“4ss”这样的坏词最终出现可能还可以(而且几乎肯定会出现),明确的词(如将前一个词中的“4”改为“a”)也绝对不行。因此,我建议您改用以下备选基准/上限:

<?php
    $lower_limit = 27000;//=2111
    $upper_limit = 809999;//=ZZZZ
    $base = "123456789BCDFGHJKLMNPQRSTVWXYZ";//erased -a -e -u
?>

请注意,如果您尝试使用更大的数字,您将达到PHP的int上限以及mt_rand限制,这可以通过mt_getrandmax()看到。另外,我想说的是,对于我所看到的mt_rand的熵已经足够了

如果随机部分需要更大的数字,我建议在随机部分后面加上第三部分,比如mt_rand(I,j);其中i和j是基本值的最小值和最大值,这将增加订单id,单位为$num chars长度(实际上我做了这个,使用上面的配置)

在DB端,这是一个避免冲突的独特字段


谢谢大家。

“设计用于解决此问题的PHP或MySQL代码对我来说是一个有效的答案”-这是说“请发送代码”的另一种方式吗?不,但如果有人提出了一种算法,以一种很好的方式解决了这个问题,我会喜欢的。我编辑了文本以避免其他人误解我的意图。您只需要GUID的前几个字符就可以真正缩小实际条目的范围,看看Git如何只需要前4-5个字符来唯一标识提交。您只需要求客户再输入几个字符,直到您与他们的姓名匹配。那么“排序订单的顺序”呢?
<?php
    $lower_limit = 27000;//=2111
    $upper_limit = 809999;//=ZZZZ
    $base = "123456789BCDFGHJKLMNPQRSTVWXYZ";//erased -a -e -u
?>