如何在数据库中生成和插入数百万个随机数,然后将其保存在Laravel中?

时间:2015-12-02 11:19:52

标签: php laravel laravel-5

我目前正在使用Laravel应用程序,并且它具有某些特定用户将登录以生成唯一的12位PIN码的功能。

拥有特定权限的用户应该能够在一个请求中生成至少1,000或10,000个PINS。

我目前正在这样做,效率低下,因为它在服务器资源方面成本非常高:

class PinController extends ApiController
{

      public function __construct(Auth $auth, Pin $pin){
             $this->auth    = $auth;
             $this->pin = $pin;
             $this->middleware('jwt.auth', ['except' => ['index','show']]);
      }


     //pin generator - works
     protected function random($length = 14)
     {
         $pool = '123456789';
         return substr(str_shuffle(str_repeat($pool, $length)), 0, $length - 2);
     }


    public function store(StoreRequest $request)
    {
         $number_of_pins = $request->get('number_of_pins');//say 10000
         $user = $this->auth->user();
         $numbers =[];

         for($i=0; $i <= $number_of_pins; $i++){

              $number = $this->random(); //generate random 12 digit pins
              $numbers[] = $number;

              if(!in_array($numbers, $number) || !$this->pin->where('number',$number)->get())
              {
                    $this->pin->create(['number'=>$number,'user_id'=>$user->id]);
              }else{
                    $i--;
              }
        }

    }
}

这需要很长时间才能执行始终失败。 我正在考虑使用队列作业来执行此操作,但它可能不是我应用程序功能的最佳解决方案。

我怎么能以一种不用太久而且不会失败的方式做到这一点?

1 个答案:

答案 0 :(得分:1)

用于测试唯一性的

if(!in_array($numbers, $number)会随着$numbers列表的增长而变得越来越慢.....而不是将$number设置为数组中的值,将其设置为密钥,然后你可以直接检查重复,这比使用in_array()快得多

您还要在 之前将$number添加到$numbers 进行重复检查,因此您已经添加了复制到你的数组(这就是它总是失败的原因)

每个值的数据库检查也是一个很大的开销,最好的消除如果可以的话

if(!isset($numbers[$number])) {
    $this->pin->create(['number'=>$number,'user_id'=>$user->id]);
    $numbers[$number] = true;
}else{
    $i--;
}