dongyi6183 2018-08-16 14:49
浏览 282
已采纳

生成数据库的随机ID

I have a requirement on a project where

  • I need to generate unique ID's.
  • ID's must be upper case.
  • I cannot check database to see if ID has been used previously.

We expect to have many millions of records added to database every month.

I have tried solutions here: PHP: How to generate a random, unique, alphanumeric string? and while they seem to work at first, my testing has shown there would be duplicates over time.

Now I am looking at using uniqid with a prefix. The problem I found using uniqid without a prefix is that duplicates will be generated when simultaneous requests come into server at the same exact time. I am hoping using a prefix would solve this.
I am thinking of using this function:

private function generate_id()
{
    $alpha_numeric = 'ABCDEFGHIJKLMNPQRSTUVWXYZ0123456789';
    $max = strlen($alpha_numeric);
    $prefix = '';

    for ($i = 0; $i < 5; $i++)
    {
        $prefix .= $alpha_numeric[random_int(0, $max - 1)];
    }
    return strtoupper(uniqid($prefix));
}

The prefix would be a 5 character alphanumeric string. Would this be enough to satisfy my requirements?

*****Edit*****

Using a UUID as suggested would be the best way to limit the chance of collision but it has been decided to go with the approach above but increase the prefix to 7 characters. The chance of a collision if two ID's where generated at the same millisecond would be around 1 in 8.3 million. That has been deemed acceptable by the higher ups.

  • 写回答

4条回答 默认 最新

  • douhao7889 2018-08-16 15:47
    关注

    If you use Composer or external libraries see https://github.com/ramsey/uuid

    or this function may meet your needs. For your needs strtoupper the result:

    /**
     * generate
     *
     * Returns a version 4 UUID
     *
     * @access public
     * @return string
     */
    public static function generate()
    {
        $data = openssl_random_pseudo_bytes(16);
    
        $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
    
        return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
    }
    

    See https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 安装svn网络有问题怎么办
  • ¥15 Python爬取指定微博话题下的内容,保存为txt
  • ¥15 vue2登录调用后端接口如何实现
  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥15 latex怎么处理论文引理引用参考文献