大批量假数据填充的正确方法
说明
开发 数据填充 时,必须
特别注意 php artisan db:seed
的运行效率,否则随着项目的代码量越来越大,db:seed
的运行时间会变得越来越长,有些项目多达几分钟甚至几十分钟。
只有当 db:seed
运行起来很快的时候,才能完全利用数据填充工具带来的便利,而不是最后变成累赘。
模型工厂
Laravel 的官方文档中,建议 使用模型工厂来填充数据 ,在日常使用中,需要注意以下。
避免使用 create 方法
在使用 模型工厂函数 来书写假数据插入逻辑时,要注意避免使用 create
方法,因为每一次就是一条 SQL 语句。
factory(\App\Models\User::class)->times(300)->create();
以下截图是一个使用 factory
辅助函数的例子,插入 300 条数据,总共执行了 602 条 SQL 语句,总执行时长为 23.91
秒。
轻轻松松运行时间就累积起来了,你能想象运行一次 db:seed
要半个小时是什么感觉么?
正确的做法:使用 make
方法
$users = factory(\App\Models\User::class)->times(1000)->make();
\App\Models\User::insert($users->toArray());
感谢 @NauxLiu
传统方式
一个错误的例子
下面代码执行了 1000 条 SQL 语句,在书写数据填充的时候,也是要尽量避免。
$faker = Faker::create();
$users = User::lists('id');
foreach (range(1, 1000) as $index)
{
Topic::create([
'user_id' => $faker->randomElement($users),
'title' => $faker->sentence(),
'description' => $faker->text(),
]);
}
解决方案
使用 DB:insert
,直接,快速,一步到位:
$faker = Faker::create();
$users = User::lists('id');
$data = [];
foreach (range(1, 1000) as $index)
{
$data[] = [
'user_id' => $faker->randomElement($users),
'title' => $faker->sentence(),
'description' => $faker->text(),
'created_at' => Carbon::now()->toDateTimeString(),
'updated_at' => Carbon::now()->toDateTimeString(),
];
}
DB::table('topics')->insert($data);
只有 db:seed
运行起来很快的时候,你才可以随时随地,想 seed 就 seed。
— EOF —
本帖已被设为精华帖!
@NauxLiu 贴代码
@NauxLiu 发哥说你家猫很吵
@NauxLiu 估计是猫被「死亡呼噜」吵到有点焦躁了。
@skyLee
@jacobcyl https://github.com/barryvdh/laravel-debugb...
楼主我有个疑问,我之前都是先定义好了在factory.php,然后用命令行执行 factory(。。。,1000)->create(),确实挺慢的。你说这种先make(),再转成数组,再插入挺好,但是是分好几步的啊,用命令行怎么完成?第一次make()了之后,数据就打印到了额控制台,还怎么再toArray啊?小弟新学,见笑了
请问,如果要插入的数据的同时也要插入关联表的数据,用insert还好弄吗?
发现了一个秘密,文章的阅读数量是以
2
为基数递增的,别问我怎么知道的(现在是凌晨2:35)@vidon520 貌似create的时候会忽略$fillable和$hidden,但是make不会忽略.所以被hidden的字段就会为空...不知道最新版本的laravel有没有对create进行优化...
@刘拯明 5.6的也还是存在这种情况呢
修改

ModelFactory.php
文件后每次都要执行composer dump-autoload
吗?头几次执行没问题 但是后面执行就报错
删除vendor文件后执行
composer install
可以执行 但是再次执行composer dump-autoload
还是报错 这到底是为什么呢? 有遇到过这个问题的吗?文中执行语句数量,时间,使用什么查看的
@aboutimes laravel-debugbar扩展了解一下
教程:【扩展推荐】Laravel-debugbar 开发调试利器
大批量假数据填充的时候,可以考虑下用存储过程,效率绝对杠杠的 :see_no_evil:
填充时如果碰到有模型访问器的时候会出现生成的假数据经过访问器
make()怎么使用中文数据,例如create('zh_CN')这种。
正确的插入姿势: $post->articlsts()->creatMany($insertArr);
$post->insert($insertArr);
@jsoner 如何批量创建 post 的同时,拿到 post_id 再批量创建评论呢
这种填充方式,不会生成created_at和updated_at
:grinning: 不适用于需要主键的方式