Laravel Seeder 生成百萬模擬資料

Mr-houzi發表於2021-03-24

Laravel 整合了 Faker 庫,並提供了 Seeder 可以幫助我們輕鬆地生成模擬資料。

先書寫資料倉儲和資料填充程式碼

資料倉儲程式碼

use App\Models\Topic;
use Faker\Generator as Faker;

$factory->define(Topic::class, function (Faker $faker) {

    $sentence = $faker->sentence();

    // 隨機取一個月以內的時間
    $updated_at = $faker->dateTimeThisMonth();

    // 傳參為生成最大時間不超過,因為建立時間永遠比更改時間要早
    $created_at = $faker->dateTimeThisMonth($updated_at);

    return [
        'title' => $sentence,
        'body' => $faker->text(),
        'excerpt' => $sentence,
        'created_at' => $created_at,
        'updated_at' => $updated_at,
    ];
});

資料填充程式碼

 class TopicsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // 所有使用者ID陣列,如:[1,2,3,4]
        $user_ids = User::all()->pluck('id')->toArray();

        // 所有分類 ID 陣列,如:[1,2,3,4]
        $category_ids = Category::all()->pluck('id')->toArray();

        // 獲取 Faker 例項
        $faker = app(Faker\Generator::class);

        $topics = factory(Topic::class)
            ->times(1000)
            ->make()
            ->each(function ($topic, $index) use ($user_ids, $category_ids, $faker){
                // 從使用者 ID 陣列中隨機取出一個並賦值
                $topic->user_id = $faker->randomElement($user_ids);

                // 話題分類,同上
                $topic->category_id = $faker->randomElement($category_ids);
            });

        // 將資料集合轉換為陣列,並插入到資料庫中
        Topic::insert($topics->toArray());
    }
}

我們通過是 times() 設定了填充的次數,執行資料填充命令,可以將 1000 條資料填充至 topics 表中,這很方便。

php artisan db:seed --class=TopicsTableSeeder

如果我們想要插入 100w 條資料,是不是把 times() 的引數改為 1000,000 就可以了?當你這樣做之後,你會發現如下報錯

General error: 1390 Prepared statement contains too many placeholders

這個問題是因為 mysql 預設支援的佔位符最多為 65535(2^16-1) 個,寫入資料為 m 列,n 行。m*n 必須小於 65535。

所以沒法一次性插入大量資料,查了一下 php artisan db:seed 也沒有提供執行次數的相關引數。

最後,決定使用 shell 指令碼進行解決。

for (( i = 0; i < 1000; i++ )); do
    /usr/local/bin/php artisan db:seed --class=TopicsTableSeeder
done

等待片刻,你會發現 100w 資料已經生成完畢!

PS:資料倉儲和資料填充程式碼來自 larabbs

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章