Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 生成一百万个唯一的随机12位数字_Php_Mysql_Optimization_Random_Unique - Fatal编程技术网

Php 生成一百万个唯一的随机12位数字

Php 生成一百万个唯一的随机12位数字,php,mysql,optimization,random,unique,Php,Mysql,Optimization,Random,Unique,我需要为一个scratch卡应用程序生成接近一百万(100批10000个数字)的唯一和随机12位代码。此过程将重复,每次都需要生成相同数量的代码 此外,生成的代码需要输入到数据库中,以便消费者稍后在我的网站上输入时可以对其进行验证。我正在使用PHP和Mysql来实现这一点。这些是我正在遵循的步骤 获取有关批数和每批代码的管理员输入 使用for循环使用 mt_兰特(1000000000009999999999) 每次生成数字时检查是否存在重复 在数据库中,如果不添加到结果变量,则重新生成 如果唯一

我需要为一个scratch卡应用程序生成接近一百万(100批10000个数字)的唯一和随机12位代码。此过程将重复,每次都需要生成相同数量的代码

此外,生成的代码需要输入到数据库中,以便消费者稍后在我的网站上输入时可以对其进行验证。我正在使用PHP和Mysql来实现这一点。这些是我正在遵循的步骤

  • 获取有关批数和每批代码的管理员输入

  • 使用for循环使用
    mt_兰特(1000000000009999999999)

  • 每次生成数字时检查是否存在重复 在数据库中,如果不添加到结果变量,则重新生成

  • 如果唯一,则将生成的编号保存在db中

  • 在所需数量的代码上重复b、c和d

  • 以csv格式向管理员输出代码

  • 使用的代码(删除了大多数注释以减少其冗长性,因为我已经在前面解释了这些步骤):

    $totalabels=$numBatch*$numLabelsPerBatch;
    //下载文件名
    $fileName=$customerName.“\u scratchcodes\u”。日期(“Ymdhs”)。“.csv”;
    $flag=false;
    $generatedCodeInfo=array();
    //下载的标题
    标题(“内容处置:附件;文件名=\”$filename\”);
    标题(“内容类型:application/vnd.ms excel”);
    $codeObject=新代码();
    //获取新批号
    $batchNumber=$codeObject->getLastBatchNumber()+1;
    $random=array();
    对于($i=0;$i<$totalAbels;$i++){
    做{
    $random[$i]=mt_rand(1000000000009999999999);//考虑到数据库的增长,需要对此进行优化以减少冲突
    }而(isCodeNotUnique($random[$i],$db));
    $codeObject=新代码();
    $codeObject->UID=$random[$i];
    $codeObject->customerName=$customerName;
    $codeObject->batchNumber=$batchNumber;
    $generatedCodeInfo[$i]=$codeObject->addCode();
    //更改下一批的批号
    如果($i==($numLabelsPerBatch-1)){$batchNumber++;}
    //$generatedCodeInfo[i]=数组(“UID”=>10001,“OID”=>$random[$i]);
    如果(!$flag){
    //将列名显示为第一行
    回声内爆(“\t”,数组_键($generatedCodeInfo[$i]))。“\n”;
    $flag=true;
    }
    //过滤数据
    数组_walk($generatedCodeInfo[$i],'filterData');
    echo内爆(“\t”,数组值($generatedCodeInfo[$i]))。“\n”;
    }
    函数filterData(&$str)
    {
    $str=preg_replace(“/\t/”、“\\t”、$str);
    $str=preg\u replace(“/\r?\n/”、“\\n”、$str);
    如果(strstrstr($str,“'))$str=''''''''''''.str_替换('''''','''''',''''''.''''.''.'',$str)。''''';
    }
    函数isCodeNotUnique($random){
    $codeObject=新代码();
    $codeObject->UID=$random;
    如果(!empty($codeObject->getCodeByUID())){
    返回true;
    }
    返回false;
    }
    
    现在这需要很长时间来执行,我认为这不是最佳的

  • 如何优化以快速生成唯一的随机数

  • 如果数字是用mysql或其他方式而不是php生成的,速度会更快吗?如果是,我该怎么做

  • 当db开始增长时,步骤b中的重复检查将非常耗时,因此如何避免这种情况

  • mysql中的行数有限制吗

  • 注意:在应用程序的整个生命周期中,所有批次的数字都必须是唯一的。

    1)根据批次数量将数字范围划分为更小的范围。例如,如果您的范围为0-1000,并且您有10个批次,则有一个从0-99到下一个100-199的批次,等等。当您为批次生成数字时,仅从批次范围生成随机数。这样您就知道在一个批次中只能有重复的编号

    不要将每个数字分别插入数据库,而是将它们存储在一个数组中。当您生成一个新的随机数时,使用函数检查数组,而不是数据库。批处理完成后,使用单个
    insert
    语句插入批处理的内容:

    insert into yourtable (bignumber) values (1), (2), ..., (n)
    
    检查MySQL的
    max_allowed_packet
    设置,看看它是否能够一次性接收完整的sql语句

    实施回退计划,以防在插入过程中仍然发现重复值(错误处理和编号重新生成)

    2) MySQL在程序方面不是很好,所以我会坚持使用外部语言,比如php

    3) 在包含随机数的字段上添加唯一索引。如果您试图插入重复记录,MySQL将阻止它并抛出一个错误。它真的很快


    4) 根据实际使用的表引擎(innodb、myisam等)、其配置和操作系统,表的大小可能会受到某些限制。请参阅此处的问题,以获得更详细的答案(请选择投票最多的答案,而不是被接受的答案)。

    您可以执行以下操作:

    $random = getExistingCodes(); // Get what you already have (from the DB).  
    $random = array_flip($random); //Make them into keys
    $existingCount = count($random); //The codes you already have 
    
    do {
        $random[mt_rand(100000000000,999999999999)] = 1;
    } while ((count($random)-$existingCount) < $totalLabels);
    
    $random = array_keys($random);
    
    $random=getExistingCodes();//从数据库中获取您已经拥有的内容。
    $random=数组翻转($random)//把它们做成钥匙
    $existingCount=计数($random)//您已有的代码
    做{
    $random[mt_rand(1000000000009999999999)]=1;
    }而((计数($random)-$existingCount)<$totalabels);
    $random=数组_键($random);
    
    当您生成一个重复的数字时,它只会覆盖该键,而不会增加计数


    要插入,您可以启动一个事务,并根据需要执行尽可能多的插入。MySQL将尝试在一个事务中优化所有操作。

    下面是一个查询,它可以生成100万个不重复的伪随机数:

    select cast(  (@n := (13*@n + 97) % 899999999981)+1e11 as char(12)) as num
    from   (select @n := floor(rand() * 9e11) ) init,
           (select 1 union select 2) m01,
           (select 1 union select 2) m02,
           (select 1 union select 2) m03,
           (select 1 union select 2) m04,
           (select 1 union select 2) m05,
           (select 1 union select 2) m06,
           (select 1 union select 2) m07,
           (select 1 union select 2) m08,
           (select 1 union select 2) m09,
           (select 1 union select 2) m10,
           (select 1 union select 2) m11,
           (select 1 union select 2) m12,
           (select 1 union select 2) m13,
           (select 1 union select 2) m14,
           (select 1 union select 2) m15,
           (select 1 union select 2) m16,
           (select 1 union select 2) m17,
           (select 1 union select 2) m18,
           (select 1 union select 2) m19,
           (select 1 union select 2) m20
    limit 1000000;
    
    工作原理 它首先生成一个带有0的随机整数值n 插入1e6/15次

    检查
    COUNT(*)
    查看您是否有一百万。执行此操作,直到表格显示为一百万行:

    INSERT IGNORE INTO x (v) VALUES
        (FLOOR(1e12*RAND());
    
    注:

    • ZEROFILL
      @n := floor(rand() * 9e11)
      
      @n := (13*@n + 97) % 899999999981
      
      CREATE TABLE x (v BIGINT(12) ZEROFILL NOT NULL PRIMARY KEY);
      
      INSERT IGNORE INTO x (v) VALUES
          (FLOOR(1e12*RAND()), (FLOOR(1e12*RAND()), (FLOOR(1e12*RAND()),
          (FLOOR(1e12*RAND()), (FLOOR(1e12*RAND()), (FLOOR(1e12*RAND()),
          (FLOOR(1e12*RAND()), (FLOOR(1e12*RAND()), (FLOOR(1e12*RAND()),
          (FLOOR(1e12*RAND()), (FLOOR(1e12*RAND()), (FLOOR(1e12*RAND()),
          (FLOOR(1e12*RAND()), (FLOOR(1e12*RAND()), (FLOOR(1e12*RAND());
      
      INSERT IGNORE INTO x (v) VALUES
          (FLOOR(1e12*RAND());
      
      <?php
      // Does mt_rand() repeat?
      
      TryMT(100);
      TryMT(100);
      TryMT(1000);
      TryMT(10000);
      TryMT(1e6);
      TryMT(1e8);
      TryMT(1e10);
      TryMT(1e12);
      TryMT(1e14);
      
      function TryMT($max) {
          $h = [];
          for ($j = 0; $j<$max; $j++) {
              $v = mt_rand(1, $max);
              if (isset($h[$v])) {
                  echo "Dup after $j iterations (limit=$max)<br>\n";
      
                  return;
              }
              $h[$v] = 1;
          }
      }
      
      Dup after 7 iterations (limit=100)<br>
      Dup after 13 iterations (limit=100)<br>
      Dup after 29 iterations (limit=1000)<br>
      Dup after 253 iterations (limit=10000)<br>
      Dup after 245 iterations (limit=1000000)<br>
      Dup after 3407 iterations (limit=100000000)<br>
      Dup after 29667 iterations (limit=10000000000)<br>
      Dup after 82046 iterations (limit=1000000000000)<br>
      Dup after 42603 iterations (limit=1.0E+14)<br>