Laravel 中使用 Migrations 的最佳实践指南
在 Laravel 项目开发中,数据库结构的管理是一项核心工作。随着项目迭代,如果没有规范的结构管理方式,很容易出现:
- 开发环境和生产环境结构不一致
- 团队成员数据库版本混乱
- 手动修改数据库导致不可追溯
- 回滚困难
Laravel 提供的 Migrations(数据库迁移) 正是为了解决这些问题。
本文将系统讲解 Laravel Migrations 的使用方式、核心原理以及实战最佳实践。
一、什么是 Migration?
Migration 本质上是:
用代码来管理数据库结构的版本控制系统。
它的作用类似于 Git,只不过 Git 管理代码版本,而 Migration 管理数据库结构版本。
二、创建 Migration
1️⃣ 创建数据表
php artisan make:migration create_users_table
生成文件路径:
database/migrations/2026_02_11_000000_create_users_table.php
文件结构:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('users');
}
};
三、Migration 核心方法解析
1️⃣ up()
用于执行结构变更(正向操作)
例如:
- 创建表
- 添加字段
- 添加索引
- 修改字段
2️⃣ down()
用于回滚操作
必须保证:
up() 做了什么,down() 就要精确反向撤销什么
否则 rollback 会出问题。
四、常用字段类型总结
常见字段类型
$table->id();
$table->string('name', 100);
$table->text('content');
$table->integer('age');
$table->bigInteger('user_id');
$table->boolean('status');
$table->decimal('amount', 10, 2);
$table->timestamp('created_at');
$table->softDeletes();
$table->timestamps();
添加索引
$table->unique('email');
$table->index(['user_id', 'status']);
外键约束
$table->foreignId('user_id')
->constrained()
->cascadeOnDelete();
等价于:
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
五、执行 Migration
运行迁移
php artisan migrate
回滚
回滚最近一次:
php artisan migrate:rollback
回滚指定步数:
php artisan migrate:rollback --step=3
重置
php artisan migrate:reset
刷新(重建)
php artisan migrate:refresh
带数据填充:
php artisan migrate:refresh --seed
六、修改已有表结构
添加字段
php artisan make:migration add_phone_to_users_table
Schema::table('users', function (Blueprint $table) {
$table->string('phone')->nullable();
});
删除字段
$table->dropColumn('phone');
⚠️ 删除字段需要安装:
composer require doctrine/dbal
七、生产环境使用建议
在生产环境执行 migration 时:
php artisan migrate --force
否则 Laravel 会拒绝执行。
八、实战最佳实践总结
✅ 1. 不要直接修改数据库
所有结构变更必须通过 Migration。
✅ 2. 每次结构修改都新建 migration
不要修改旧 migration 文件。
原因:
- 旧文件可能已经在生产执行
- 修改会导致版本错乱
✅ 3. 合理命名 migration
好的命名:
add_index_to_users_email
add_status_to_orders_table
modify_amount_precision_in_orders
✅ 4. 使用 Schema::hasTable 判断
在某些特殊场景:
if (!Schema::hasTable('users')) {
Schema::create(...);
}
✅ 5. 大表修改要谨慎
生产大表添加字段时:
- 避免高峰期执行
- 避免锁表操作
- 尽量添加 nullable 字段
九、Migration 与 Seeder 的关系
Migration 负责:
数据结构
Seeder 负责:
初始化数据
典型流程:
php artisan migrate --seed
十、团队协作中的 Migration 管理策略
推荐流程:
- 开发新增 migration
- 提交代码
- 测试环境执行 migrate
- 生产部署时自动执行 migrate
十一、常见问题总结
Q1:迁移文件执行顺序?
按文件名前缀时间戳顺序执行。
Q2:如何查看执行过哪些迁移?
查看数据表:
migrations
Q3:如何只执行某一个 migration?
php artisan migrate --path=database/migrations/xxx.php
十二、总结
Migration 的核心价值:
- 数据库结构版本化
- 可回滚
- 可协作
- 可自动化部署
一句话总结:
不使用 Migration 的 Laravel 项目,是不完整的项目。