用戶隨機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();