用户随机50选1。好的车牌用户选不到。
我目前的做法是这样的。所有车牌入库。别人选了状态就修改为1。下面是入库程序,想跟大家讨论一下,有没有更好的方式。
use Illuminate\Database\Seeder;
class LicensePlatesTableSeeder extends Seeder
{
public function identicalNumber($numbers = [])
{
$identical = array_count_values($numbers);
$data = [
1 => 0,
2 => 0,
3 => 0,
4 => 0,
5 => 0,
];
foreach ($identical as $item) {
$data[$item]++;
}
return $data;
}
public function orderLength($keys = [])
{
$current = null;
$length = 0;
foreach ($keys as $key) {
if ($current === null || $key - 1 != $current || $key==26) {
$current = $key;
$length = 1;
continue;
}
$length += 1;
}
return $length;
}
public function run()
{
/**
* 生成26个字母和0到9的数字
*/
$data = [];
for ($i = 65; $i < 91; $i++) {
$data[] = strtoupper(chr($i));
}
for ($i = 0; $i <= 9; $i++) {
$data[] = $i;
}
$license = [];
foreach ($data as $key1 => $item1) {
foreach ($data as $key2 => $item2) {
foreach ($data as $key3 => $item3) {
foreach ($data as $key4 => $item4) {
foreach ($data as $key5 => $item5) {
$numbers = [$item1, $item2, $item3, $item4, $item5];
$key = [$key1, $key2, $key3, $key4, $key5];
$identicalNumber = $this->identicalNumber($numbers);
$license[] = [
'number' => implode('', $numbers),
'order_length' => $this->orderLength($key),//最大顺子长度。
'reverse_order_length' => $this->orderLength(array_reverse($key)),//倒序,最大顺子长度。
'identical_2' => $identicalNumber[2],//有2个数字相同的次数。
'identical_3' => $identicalNumber[3],//有3个数字相同的次数。
'identical_4' => $identicalNumber[4],//有4个数字相同的次数。
'identical_5' => $identicalNumber[5],//有5个数字相同的次数。
];
if (count($license) >= 8000) {
\App\LicensePlate::insert($license);
$license = [];
}
}
}
}
}
}
if ($license) {
\App\LicensePlate::insert($license);
}
\App\LicensePlate::where('id', '>', 0)->update([
'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
'updated_at' => \Carbon\Carbon::now()->toDateTimeString(),
]);
}
}
会生成6千万+条数据。用户查询出问题。之前想过,好的车牌放一个表,差的放一个表,但是怕业务会改规则,可能后面3个相同的,或4个相同的,都放出来随机。
用户查询50个随机车牌,去掉一些好的车牌。大家有什么好的优化方式吗?
$id=mt_rand(1,36*36*36*36*36-100000);
$LicensePlates = App\LicensePlate::select('id', 'number')
->whereBetween('id',[$id,$id+100000])//为什么加这个,是因为不加根本查不出来
->whereNull('use_at')//已使用的
->where('order_length', '<=', 2)//不能选顺子长度大于等于3的 比如 123AD ABCD8
->where('reverse_order_length', '<=', 2)//不能选倒序顺子长度大于等于3的 比如 AD321 D4321
->where('identical_2', '<=', 1)//不能选有二个对子,比如 11A22,BBC88
->where('identical_3', 0)//不能选2个相同的 比如 A1A4A AA23A AAA23
->where('identical_4', 0)//不能选4个相同的 比如 AAAA4 77B77 777B7
->where('identical_5', 0)//不能选5个相同的 比如 88888 99999 AAAAA
->inRandomOrder()//随机
->limit(50)
->get();