本文目录导读:

在 Laravel 项目中,数据库迁移(Migrations)是管理数据库结构版本控制的强大工具,以下是全面的 Laravel 数据库迁移管理指南:
基础命令
创建迁移文件
# 创建迁移(自动根据表名生成) php artisan make:migration create_users_table # 指定表名和操作 php artisan make:migration add_phone_to_users_table --table=users php artisan make:migration create_products_table --create=products # 创建带有模型的迁移 php artisan make:model Product -m
执行迁移
# 运行所有未执行的迁移 php artisan migrate # 指定路径 php artisan migrate --path=/database/migrations/custom # 指定数据库连接 php artisan migrate --database=mysql_backup
回滚迁移
# 回滚最后一次迁移 php artisan migrate:rollback # 回滚多步 php artisan migrate:rollback --step=3 # 回滚所有迁移 php artisan migrate:reset # 回滚并重新迁移 php artisan migrate:refresh # 刷新并执行数据填充 php artisan migrate:refresh --seed
迁移文件结构
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* 运行迁移
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* 回滚迁移
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
常见字段类型
Schema::create('products', function (Blueprint $table) {
// 主键和索引
$table->id();
$table->bigIncrements('id')->unsigned();
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
// 字符串类型
$table->string('name', 100);
$table->char('code', 10);
$table->text('description');
$table->mediumText('medium_text');
$table->longText('long_text');
// 数字类型
$table->integer('quantity');
$table->unsignedInteger('stock')->default(0);
$table->decimal('price', 10, 2);
$table->float('weight', 8, 2);
$table->double('length', 8, 2);
$table->boolean('is_active')->default(true);
// 日期时间
$table->date('published_date');
$table->time('opens_at');
$table->datetime('started_at');
$table->timestamp('expired_at')->nullable();
$table->dateTime('created_at')->useCurrent();
$table->softDeletes(); // deleted_at
// 其他
$table->json('metadata');
$table->binary('file_data');
$table->uuid('uuid');
$table->geometry('location');
$table->enum('status', ['active', 'inactive', 'pending']);
$table->ipAddress('visitor_ip');
$table->macAddress('client_mac');
// 时间戳
$table->timestamps(); // created_at + updated_at
});
常用修饰符
Schema::create('examples', function (Blueprint $table) {
$table->id();
$table->string('name')->comment('用户名称');
$table->integer('age')->unsigned()->default(18);
$table->string('email')->unique();
$table->string('slug')->index();
$table->boolean('is_admin')->default(false);
$table->string('nullable_column')->nullable();
$table->string('first_name')->after('id'); // 位置
$table->string('last_name')->after('first_name');
$table->string('full_name')->storedAs("concat(first_name, ' ', last_name)");
// 复合索引
$table->index(['name', 'email']);
});
表操作
// 重命名表
Schema::rename('old_table', 'new_table');
// 删除表
Schema::drop('posts');
// 检查表是否存在
if (Schema::hasTable('users')) {
// 表存在
}
// 检查列是否存在
if (Schema::hasColumn('users', 'email')) {
// 列存在
}
// 获取所有表
$tables = DB::select('SHOW TABLES');
修改现有表
public function up()
{
Schema::table('users', function (Blueprint $table) {
// 添加字段(需要安装 doctrine/dbal)
$table->string('phone')->nullable()->after('email');
// 修改字段
$table->string('name', 200)->change();
// 重命名字段
$table->renameColumn('from', 'to');
// 删除字段
$table->dropColumn(['column1', 'column2']);
// 删除索引/约束
$table->dropIndex('index_name');
$table->dropUnique('unique_name');
$table->dropForeign('foreign_key_name');
$table->dropPrimary();
// 添加索引
$table->index('column');
$table->unique('column');
});
}
迁移高级特性
条件迁移
public function up()
{
if (!Schema::hasTable('table_name')) {
Schema::create('table_name', function (Blueprint $table) {
// ...
});
}
}
可回滚的迁移
public function up()
{
// 创建视图或存储过程
DB::statement("CREATE VIEW v_users AS SELECT * FROM users");
}
public function down()
{
DB::statement("DROP VIEW IF EXISTS v_users");
}
一次性迁移
Schema::create('temp_table', function (Blueprint $table) {
// 不记录在迁移表
});
迁移注意事项
生产环境部署建议
# 使用 --force 在生产环境执行 php artisan migrate --force # 预先生成迁移 SQL 文件 php artisan schema:dump
迁移顺序管理
创建时间要确保依赖顺序:
// 2024_01_01_000000_create_categories_table.php
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
});
}
// 2024_01_02_000000_create_products_table.php
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->foreignId('category_id')
->constrained() // 自动创建外键和索引
->onDelete('cascade');
});
}
模型与迁移配合
// Product.php
class Product extends Model
{
use SoftDeletes;
protected $fillable = [
'name', 'description', 'price'
];
protected $casts = [
'price' => 'decimal:2',
'is_active' => 'boolean'
];
protected $dates = ['published_at'];
}
最佳实践
迁移文件命名规范
2024_01_01_000000_create_users_table.php
2024_01_02_000000_add_email_to_users_table.php
2024_01_03_000000_drop_unnecessary_columns.php
开发流程建议
# 1. 创建 Model 和迁移 php artisan make:model Product -m -c # 2. 使用资源控制器 php artisan make:controller ProductController --resource # 3. 运行迁移 php artisan migrate --seed # 4. 测试回滚 php artisan migrate:rollback --step=1 # 5. 生产部署 php artisan migrate --force
常用指令组合
# 完全重建数据库(开发环境) php artisan migrate:fresh --seed # 查看迁移状态 php artisan migrate:status # 生成模型关系图(需要额外工具) composer require beyondcode/laravel-er-diagram
十一、注意事项
- 字段类型选择:选择合理的数据类型以节省存储空间和提高查询效率
- 索引优化:在查询频繁的字段上添加索引
- 外键约束:合理使用外键保证数据完整性
- Avoid using Schema::dropIfExists:在生产环境要谨慎
- 迁移原子性:每个迁移应该独立且可逆
十二、第三方扩展
# 安装扩展包
composer require doctrine/dbal # 支持修改字段
composer require laravel/horizon # 队列监控
# 使用扩展
Schema::table('users', function (Blueprint $table) {
$table->string('name')->change();
});
通过遵循这些最佳实践,你可以有效地管理 Laravel 项目的数据库结构,确保项目在不同环境间的可移植性和可维护性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播