# 大乐透模块随机 12w 条数据 3 秒这件事！

## helper 函数

``````
if (!function_exists("range_num")) {
function range_num(\$start_num = 1, \$end_num = 12, \$num = 6)
{

\$numbers = range(\$start_num, \$end_num);
//shuffle 将数组顺序随即打乱
shuffle(\$numbers);
//array_slice 取该数组中的某一段

\$result = array_slice(\$numbers, 0, \$num);
return \$result;
}
}

if (!function_exists("sortQuickArr")) {
function sortQuickArr(\$array)
{
if (count(\$array) < 1) {
return \$array;
}
//快速排序理论上可以选取任意一点作为 pivot,但是那是理论,这个案例只能取最后1个或者最后一个,因为如果无限二分的时候出现数组个数小于坐标就会报错!
\$k = \$array[0];
\$count = count(\$array);
\$left = \$right = [];
\$center = [\$k];
for (\$i = 0; \$i < \$count; \$i++) {
if (\$array[\$i] < \$k) {
\$left[] = \$array[\$i];
} elseif (\$array[\$i] > \$k) {
\$right[] = \$array[\$i];
}
}
\$left = sortQuickArr(\$left);
\$right = sortQuickArr(\$right);
\$sum = array_merge(\$left, \$center, \$right);

return \$sum;
}
}
``````

## 数据表

``````
CREATE TABLE `lottery_ball`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`lottery_num` varchar(30) NOT NULL COMMENT '期号' ,
`user_id` int (11) DEFAULT NULL COMMENT '用户id',
`front_area` varchar (30) NOT NULL COMMENT '前区',
`after_area` varchar (30) NOT NULL COMMENT '后区',
`is_open` tinyint(1) NOT NULL DEFAULT 0 COMMENT '0未开奖 1开奖' ,
`level` tinyint(1) NOT NULL DEFAULT 0 COMMENT  '0未中奖1-等奖 2二等奖 3三等奖 4四等奖 5五等奖 6六等奖 7七等奖 8八等奖 9九等奖 ',
`date` date NOT NULL,
`red1` tinyint(1) NOT NULL DEFAULT 0 COMMENT '红球1' ,
`red2` tinyint(1) NOT NULL DEFAULT 0 COMMENT '红球2' ,
`red3` tinyint(1) NOT NULL DEFAULT 0 COMMENT '红球3' ,
`red4` tinyint(1) NOT NULL DEFAULT 0 COMMENT '红球4' ,
`red5` tinyint(1) NOT NULL DEFAULT 0 COMMENT '红球5' ,
`blue1` tinyint(1) NOT NULL DEFAULT 0 COMMENT '篮球1' ,
`blue2` tinyint(1) NOT NULL DEFAULT 0 COMMENT '篮球2' ,
`blue_num` tinyint(1) NOT NULL DEFAULT 0 COMMENT '开奖篮球数目' ,
`red_num` tinyint(1) NOT NULL DEFAULT 0 COMMENT '开奖红球数据' ,
`created_at` timestamp NOT NULL,
`updated_at` timestamp NOT NULL,
PRIMARY KEY(`id`),
KEY `front_area` (`front_area`),
KEY `after_area` (`after_area`),
KEY `front_area_2` (`front_area`,`after_area`),
KEY `user_id`(`user_id`),
KEY `date` (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='随机大乐透号码';``````

## 模型

``````<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;

class LotteryBall extends Model
{
use HasFactory;
protected \$table = 'lottery_ball';

protected \$fillable = ['lottery_num','user_id','front_area','after_area','is_open','level','red1','red2','red3','red4','red5'
,'blue1','blue2','blue_num','red_num','created_at','updated_at'];

}
``````

## 假数据

factory

``````<?php

namespace Database\Factories;

use App\Models\LotteryBall;
use Illuminate\Database\Eloquent\Factories\Factory;

class LotteryBallFactory extends Factory
{
protected \$model = LotteryBall::class;

public function definition()
{
\$sentence = \$this->faker->sentence();

\$red = range_num(1, 35, 5);
\$blue = range_num(1, 12, 2);

\$red = sortQuickArr(\$red);
\$blue = sortQuickArr(\$blue);

return [
'lottery_num' => '16546fd1fd51g',
'user_id' => \$this->faker->randomElement([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
'front_area' => implode(" ", \$red),
'after_area' => implode(" ", \$blue),
'red1' => \$red[0],
'red2' => \$red[1],
'red3' => \$red[2],
'red4' => \$red[3],
'red5' => \$red[4],
'blue1' => \$blue[0],
'blue2' => \$blue[1],
'date' => date("Y-m-d"),

];
}
}
``````

``````<?php

namespace Database\Seeders;

use App\Models\LotteryBall;
use Illuminate\Database\Seeder;

/**
* php artisan db:seed --class=LotteryBallSeeder
* Class LotteryBallSeeder
* @package Database\Seeders
*/
class LotteryBallSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//
foreach (range(1, 90) as \$index) {
\$users = LotteryBall::factory()->times(1000)->make();
\App\Models\LotteryBall::insert(\$users->toArray());
}
}
}
``````

## 测试服务

``````<?php

namespace App\Services;

use App\Models\LotteryBall;

/**
* 大乐透逻辑
*
* Class LotteryBallService
* @package App\Services
*/
class LotteryBallService
{
/**
* 模拟开奖
*/
public function runPrice()
{
\$red = [13, 20, 27, 29, 30];
\$blue = [01, 07];

// 如果多次测试就加上这句，初始化计数，多 0.5 秒时间
\$this->initNum();

\$this->draw_prize(\$red, \$blue);
}

/**
* 开奖
* @param array \$red
* @param array \$blue
*/
public function draw_prize(\$red = [], \$blue = [])
{
for (\$j = 1; \$j <= 5; \$j++) {
\$n1 = "red" . strval(\$j);
LotteryBall::whereIn(\$n1, \$red)->increment("red_num");
}

for (\$j = 1; \$j <= 2; \$j++) {
\$n1 = "blue" . strval(\$j);
LotteryBall::whereIn(\$n1, \$blue)->increment("blue_num");
}
}

/**
* 中奖结果设置
*/
public function setLevel()
{
\$getPrice = [
['red_num' => 5, 'blue_num' => 2, 'level' => 1],
['red_num' => 5, 'blue_num' => 1, 'level' => 2],
['red_num' => 5, 'blue_num' => 0, 'level' => 3],
['red_num' => 4, 'blue_num' => 2, 'level' => 4],
['red_num' => 4, 'blue_num' => 1, 'level' => 5],
['red_num' => 3, 'blue_num' => 2, 'level' => 6],
['red_num' => 4, 'blue_num' => 0, 'level' => 7],
['red_num' => 3, 'blue_num' => 1, 'level' => 8],
['red_num' => 3, 'blue_num' => 0, 'level' => 9],
['red_num' => 2, 'blue_num' => 1, 'level' => 9],
['red_num' => 1, 'blue_num' => 2, 'level' => 9],
];
foreach (\$getPrice as \$value) {
LotteryBall::where("red_num", \$value['red_num'])->where("blue_num", \$value['blue_num'])->update(["level" => \$value['level']]);
}
}

/**
* 中奖结果查询
*/
public function show_getPrice()
{
\$arr = ['一', '二', '三', '四', '五', '六', '七', '八', '九'];
\$res = '';
for (\$j = 1; \$j <= 9; \$j++) {
\$co = LotteryBall::where("level", \$j)->count();

\$res .= \$arr[\$j - 1] . "等奖：" . strval(\$co) . " ";
}

dump(\$res);
return \$res;
}

/**
* 把中奖数目初始化
*/
public function initNum()
{
LotteryBall::where("id", ">", 0)->update(["red_num" => 0, "blue_num" => 0]);
}
}
``````

## 运行命令

``````<?php

namespace App\Console\Commands;

use App\Services\LotteryBallService;
use Illuminate\Console\Command;

/**
*      php artisan lottery:send
*
* Class SendLottery
* @package App\Console\Commands
*/
class SendLottery extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected \$signature = 'lottery:send';

/**
* The console command description.
*
* @var string
*/
protected \$description = 'Command description';

/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
\$stime=microtime(true);

\$obj = new LotteryBallService();

//        return \$obj->initNum();

\$obj->runPrice();
\$obj->setLevel();
\$obj->show_getPrice();

\$etime=microtime(true);//获取程序执行结束的时间
\$total=\$etime-\$stime;   //计算差值
dump("ok, ".\$total." 秒");
return Command::SUCCESS;
}
}
``````

《L05 电商实战》

《L01 基础入门》

``````for(\$i=0; \$i<12; \$i++){
\$users = \App\Models\User::factory()->times(10000)->make();
\App\Models\User::insert(\$users->toArray());
}``````

``````for(\$i=0; \$i<12; \$i++){
\App\Models\User::factory(10000)->create();
}``````
2周前 评论

2周前 评论

2周前 评论

18

10

23

21