Laravel 数据库迁移实战:用 Schema 与可回滚迁移守住表结构演进
test12026-10-041 次阅读
为什么用迁移管理表结构
表结构不该靠手敲 SQL 在每台环境里改。迁移是一段带版本、可前进也可回退的 PHP 代码,在开发、测试、生产执行同一份,环境差异带来的「我本地是好的」从此消失。
创建迁移
php artisan make:migration create_orders_table
生成的文件放在 database/migrations,文件名带时间戳决定执行顺序。
写 up 与 down
up 描述「前进」时建什么,down 描述「回退」时拆什么,二者必须对称:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->string('no')->unique();
$table->decimal('amount', 12, 2);
$table->tinyInteger('status')->default(0);
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('orders');
}
};
常用列与索引
- 外键:$table->foreignId('user_id')->constrained();
- 索引:$table->index('status'); 或 unique 约束保证唯一。
- 改已有表用 Schema::table,新增列要同时考虑 down 里的 dropColumn。
带数据的一次性迁移
结构变化常常伴随默认值填充,用匿名迁移把逻辑写进 up,并包成事务保证原子:
return new class extends Migration {
public function up(): void
{
Schema::table('orders', function (Blueprint $table) {
$table->string('currency')->default('CNY');
});
// 历史数据补默认值,包在事务里
DB::transaction(function () {
DB::table('orders')
->whereNull('currency')
->update(['currency' => 'CNY']);
});
}
public function down(): void
{
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('currency');
});
}
};
执行与回退
php artisan migrate # 执行未跑过的迁移
php artisan migrate:rollback # 回退最近一批
php artisan migrate:status # 查看每张表迁移进度
生产环境注意
- 已上线的表不要随手 drop 列,先评估数据量与锁表影响,大表用在线 DDL 工具。
- 迁移一旦推到生产就不要修改文件内容,需要变更就新增一份迁移。
- down 方法不是摆设,演练回退比演练前进更能在出事时救命。
T
test1
文章作者
为什么用迁移管理表结构 表结构不该靠手敲 SQL 在每台环境里改。迁移是一段带版本、可前进也可回退的 PHP 代码,在...
- 分类
- 技术
- 发布时间
- 2026-10-04
- 字数
- 约 1839 字
- 阅读
- 1 次
