laravel 5.5 数据库种子功能本身没有专为测试数据设计的特殊机制,但通过模型工厂(factory)+ seeder 的组合,形成可复用、可关联、可控制规模的填充方案;seeder + factory 是其测试数据填充的核心组合,支持关联生成、字段覆盖、避免硬编码sql;默认只执行空的 databaseseeder,需手动调用具体 seeder 类;大数据量填充需手动分块、禁用查询日志等原始 workaround;无内置幂等性,依赖 truncate 或 migrate:refresh --seed 实现重复安全。

Seeder + Factory 是 Laravel 5.5 测试数据填充的核心组合
Laravel 5.5 首次将 ModelFactory 深度集成进 Eloquent,并允许在 Seeder 中直接调用 User::factory()->create()。这不是语法糖,而是解决了三个关键问题:
- 关联数据自动生成:比如
Post::factory()->count(5)->for(User::factory())->create(),自动处理user_id外键,无需手动查 ID - 字段覆盖灵活:可在
create()中传数组覆盖默认值,如User::factory()->create(['email' => 'test@example.com']) - 避免硬编码 SQL:不用写
DB::table('users')->insert([...])这类易出错、难维护的原始插入
php artisan db:seed --class=xxx 在 5.5 中必须显式指定类名
Laravel 5.5 默认只执行 DatabaseSeeder,而它本身是空的(除非你手动编辑)。很多人运行 db:seed 后没反应,其实是忘了在 DatabaseSeeder::run() 里加 $this->call(UserSeeder::class)。
实操建议:
- 不要依赖文件名或目录扫描 —— Laravel 5.5 不会自动发现
UserSeeder - 单测调试时,直接用
php artisan db:seed --class=UserSeeder,避免污染其他表 -
--class参数值必须是完整类名(含命名空间),但 5.5 默认命名空间是Database\Seeds,不是Database\Seeders(那是 Laravel 8+ 的变更)
大数据量填充容易卡死,5.5 的 workaround 很原始但有效
Laravel 5.5 没有 chunkById() 或 withoutEvents() 这类现代方法,批量插入千条以上记录时极易超时或内存溢出。
当时能用的方案只有:
- 用
DB::table('users')->insert($batch)替代循环User::create(),跳过模型开销 - 手动分块:把 5000 条数据拆成
array_chunk($data, 500),再 foreach 插入 - 在 Seeder 开头加
DB::disableQueryLog()(虽不能禁事件,但能省点内存) - 临时改 PHP 配置:
ini_set('max_execution_time', 300)
重复执行 seed 导致主键冲突,5.5 里只能靠人工防御
Laravel 5.5 的 Seeder 没有内置幂等性支持。反复跑 db:seed 就会报 SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry。
常见应对方式:
- 在
run()开头清表:DB::table('users')->truncate()(注意外键约束需先禁用) - 改用
firstOrCreate(),但仅适用于少量配置数据,不适合批量测试数据 - 配合迁移重置:
php artisan migrate:refresh --seed,这是当时最稳妥的“重来”方式











