Laravel数据库迁移
在 Laravel 项目开发中,数据库表结构经常会随着业务变化不断调整。如果每次都手动登录数据库执行 SQL,不仅容易漏改,也不方便多人协作。Laravel Migration 提供了一种更规范的方式,可以把建表、改字段、加索引等操作写进代码里,让数据库结构也能像业务代码一样被版本管理。
一、Laravel Migration 是什么
Laravel Migration 通常翻译为数据库迁移。它的作用是用 PHP 文件描述数据库表结构变化,例如创建数据表、添加字段、修改字段、删除字段、创建索引等。
简单理解,Migration 就是数据库结构的版本记录。团队成员拉取代码后,只要执行迁移命令,就可以把本地数据库更新到和项目一致的结构。
它适合解决以下问题:
- 多人开发时数据库结构不一致。
- 新环境部署时不知道要手动建哪些表。
- 表结构修改后缺少记录。
- 上线前需要统一执行数据库变更。
- 修改失败时需要回滚。
对于 Laravel 项目来说,Migration 是非常重要的基础能力,尤其适合中长期维护的项目。
二、创建迁移文件
Laravel 可以通过 Artisan 命令创建迁移文件。
例如创建一张文章表:
php artisan make:migration create_posts_table
执行后,会在 database/migrations 目录下生成一个迁移文件,文件名通常带有时间戳,例如:
2026_09_02_100000_create_posts_table.php
时间戳的作用是让 Laravel 按顺序执行迁移文件,避免表结构变更顺序混乱。
如果要在创建迁移文件时指定表名,可以这样写:
php artisan make:migration create_posts_table --create=posts
如果是修改已有表,可以使用:
php artisan make:migration add_status_to_posts_table --table=posts
三、迁移文件的基本结构
一个迁移文件通常包含两个方法: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('posts', function (Blueprint $table) {
$table->id();
$table->string('title', 200);
$table->text('content')->nullable();
$table->unsignedTinyInteger('status')->default(0);
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('posts');
}
};
up 方法用于执行迁移,例如创建表或添加字段。
down 方法用于回滚迁移,例如删除表或移除字段。
写迁移文件时,不要只写 up,也要认真写 down。否则后续回滚时可能出现问题。
四、常用字段类型
Laravel 的 Blueprint 提供了很多字段定义方法,常用的有:
$table->id();
$table->string('name', 100);
$table->text('description');
$table->integer('sort');
$table->unsignedBigInteger('user_id');
$table->boolean('is_active')->default(true);
$table->decimal('price', 10, 2);
$table->date('published_at')->nullable();
$table->timestamps();
常见字段说明:
id:自增主键。string:短文本字段,常用于标题、名称、邮箱等。text:长文本字段,常用于正文和描述。integer:整数。boolean:布尔值。decimal:小数,常用于金额。date:日期。timestamps:自动创建created_at和updated_at字段。
如果字段允许为空,可以加上 nullable():
$table->string('subtitle')->nullable();
如果字段需要默认值,可以使用 default():
$table->unsignedTinyInteger('status')->default(0);
五、执行数据库迁移
迁移文件写好后,可以执行:
php artisan migrate
Laravel 会读取尚未执行的迁移文件,并按时间顺序执行。
如果迁移成功,数据库中会生成对应的数据表。同时,Laravel 会在 migrations 表中记录哪些迁移已经执行过。
可以查看迁移状态:
php artisan migrate:status
这个命令可以看到每个迁移文件是否已经运行。
六、回滚数据库迁移
如果刚刚执行的迁移需要撤销,可以使用:
php artisan migrate:rollback
该命令会回滚上一批迁移。
如果想回滚指定步数,可以使用:
php artisan migrate:rollback --step=1
如果想重新执行所有迁移,可以使用:
php artisan migrate:fresh
需要注意,migrate:fresh 会删除所有表并重新执行迁移,通常只适合本地开发环境,不要随意在生产环境执行。
如果需要重新执行迁移并填充测试数据,可以使用:
php artisan migrate:fresh --seed
七、修改已有数据表
业务开发中,经常需要给已有表增加字段。例如给 posts 表增加 views 字段:
php artisan make:migration add_views_to_posts_table --table=posts
迁移文件示例:
public function up(): void
{
Schema::table('posts', function (Blueprint $table) {
$table->unsignedInteger('views')->default(0)->after('status');
});
}
public function down(): void
{
Schema::table('posts', function (Blueprint $table) {
$table->dropColumn('views');
});
}
Schema::table 用于修改已有表,after 可以指定字段位置。不过字段位置不是所有数据库都完全支持,实际使用时以项目数据库为准。
八、添加索引和唯一约束
如果某些字段经常用于查询,可以添加索引。例如给 status 字段添加普通索引:
$table->index('status');
如果某个字段不能重复,可以添加唯一索引:
$table->string('slug')->unique();
也可以在修改表时添加索引:
Schema::table('posts', function (Blueprint $table) {
$table->index('published_at');
});
回滚时可以删除索引:
Schema::table('posts', function (Blueprint $table) {
$table->dropIndex(['published_at']);
});
索引可以提升查询效率,但不是越多越好。频繁写入的表如果索引过多,可能影响写入性能。
九、生产环境使用注意事项
生产环境执行迁移前,要特别谨慎。建议注意以下几点:
- 执行前备份数据库。
- 确认迁移文件已经在测试环境跑过。
- 避免在业务高峰期执行大表结构变更。
- 不要随意使用
migrate:fresh。 - 大表添加字段或索引时,要评估锁表风险。
- 上线前确认
down方法是否可用。 - 团队协作时,不要修改已经上线执行过的旧迁移文件。
比较推荐的做法是:已经被其他环境执行过的迁移文件不要再改。如果需要调整表结构,应新建迁移文件。
十、常见问题
Laravel Migration 可以代替 SQL 文件吗?
在多数 Laravel 项目中可以。Migration 更适合代码化管理表结构,方便版本控制和多人协作。但复杂数据库初始化、存储过程或特殊 SQL,仍可能需要额外 SQL 文件配合。
已经执行过的迁移文件还能修改吗?
不建议修改。已经执行过的迁移文件如果被改动,其他环境可能出现结构不一致。更稳妥的做法是新建一个迁移文件继续调整。
生产环境能执行 php artisan migrate 吗?
可以,但要谨慎。执行前建议备份数据库,并确认迁移内容不会造成数据丢失或长时间锁表。
migrate:fresh 能在线上使用吗?
一般不建议。migrate:fresh 会删除所有表并重新创建,可能造成数据丢失,通常只用于本地开发和测试环境。
广告合作
QQ群号:4114653
- 本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。邮箱:2942802716#qq.com(#改为@)。
- 本站原创内容未经允许不得转载,转载请注明出处“站长百科”和原文地址。