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 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)