PHP项目Laravel数据库迁移管理

wen PHP项目 6

本文目录导读:

PHP项目Laravel数据库迁移管理

  1. 基础命令
  2. 迁移文件结构
  3. 常见字段类型
  4. 常用修饰符
  5. 表操作
  6. 修改现有表
  7. 迁移高级特性
  8. 迁移注意事项
  9. 模型与迁移配合
  10. 最佳实践
  11. 十一、注意事项
  12. 十二、第三方扩展

在 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

十一、注意事项

  1. 字段类型选择:选择合理的数据类型以节省存储空间和提高查询效率
  2. 索引优化:在查询频繁的字段上添加索引
  3. 外键约束:合理使用外键保证数据完整性
  4. Avoid using Schema::dropIfExists:在生产环境要谨慎
  5. 迁移原子性:每个迁移应该独立且可逆

十二、第三方扩展

# 安装扩展包
composer require doctrine/dbal  # 支持修改字段
composer require laravel/horizon # 队列监控
# 使用扩展
Schema::table('users', function (Blueprint $table) {
    $table->string('name')->change();
});

通过遵循这些最佳实践,你可以有效地管理 Laravel 项目的数据库结构,确保项目在不同环境间的可移植性和可维护性。

抱歉,评论功能暂时关闭!