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 次