Migrations 迁移
创建迁移时使用空格
当输入 make:migration 命令时,不一定必须在各部分之间使用下划线 _ 符号,例如 create_transactions_table。
可以将名称放在引号中,然后使用空格而不是下划线。
// 能正常工作
php artisan make:migration create_transactions_table
// 这样也能正常工作
php artisan make:migration "create transactions table"迁移顺序
使用命令 php artisan make:migration create_posts_table --table=posts 可以快速创建迁移文件,创建的迁移文件名有一个特点,就是以时间命名的。
如果想更改数据库迁移的顺序,只需重命名文件的时间戳。
例如从 2018_08_04_070443_create_posts_table.php 到 2018_07_04_070443_create_posts_table.php(从 2018_08_04 更改为 2018_07_04)
指定列的创建顺序
注意下下面的方法,仅支持
MySQL
如果要向现有表添加新列,则它不一定必须成为列表中的最后一个。
after()
可以指定应在哪一列之后创建它:
Schema::table('users', function (Blueprint $table) {
$table->string('phone')->after('email');
});也可以使用 after() 方法添加多个字段:
Schema::table('users', function (Blueprint $table) {
$table->after('remember_token', function ($table) {
$table->string('card_brand')->nullable();
$table->string('card_last_four', 4)->nullable();
});
});before()
如果要向现有表添加新列,则它不一定必须成为列表中的最后一个。
可以指定应在哪一列之前创建它:
Schema::table('users', function (Blueprint $table) {
$table->string('phone')->before('created_at');
});first()
如果希望新增的列成为表中的第一列,可以使用 first 方法。
Schema::table('users', function (Blueprint $table) {
$table->string('uuid')->first();
});具有时区的迁移字段
在迁移中不仅有 timestamps(),还有用于时区的 timestampsTz()。
Schema::create('employees', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email');
$table->timestampsTz();
});此外,还有 dateTimeTz()、timeTz()、timestampTz()、softDeletesTz() 列。
默认时间戳
创建迁移时,可以使用带有选项 useCurrent() 和 useCurrentOnUpdate() 的 timestamp() 列类型,它将把 CURRENT_TIMESTAMP 设置为默认值。
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrentOnUpdate();更多数据库迁移列类型
有一些有趣的迁移列类型,以下是一些示例。
$table->uuid('id');
$table->geometry('positions');
$table->ipAddress('visitor');
$table->macAddress('device');
$table->point('position');请参阅官方文档中的所有列类型。
迁移状态
如果想检查哪些迁移已执行或尚未执行,无需查看数据库 migrations 表,可以使用 php artisan migrate:status 命令。
Migration name .............................................. Batch / Status
2014_10_12_000000_create_users_table ............................... [1] Ran
2014_10_12_100000_create_password_reset_tokens_table ............... [1] Ran
2019_08_19_000000_create_failed_jobs_table ......................... [1] Ran
2019_12_14_000001_create_personal_access_tokens_table .............. [1] Ran对存在表进行迁移
如果对现有表进行迁移,并且希望生成 Schema::table(),请在末尾添加_in_xxxxx_table 或 _to_xxxxx_table,或指定 --table参数。
空迁移文件
php artisan make:migration change_fields_products_table
# INFO Migration [database/migrations/2023_11_16_025034_change_fields_products_table.php] created successfully.// database/migrations/2023_11_16_025034_change_fields_products_table.php
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
//
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};指定表
方式一:使用
--table参数指定表则会生成预填充Schema::table('xxx', function() {})的类bashphp artisan make:migration whatever_you_want --table=products # INFO Migration [database/migrations/2023_11_16_025540_whatever_you_want.php] created successfully.php// database/migrations/2023_11_16_025540_whatever_you_want.php return new class extends Migration { /** * Run the migrations. */ public function up(): void { Schema::table('products', function (Blueprint $table) { // }); } /** * Reverse the migrations. */ public function down(): void { Schema::table('products', function (Blueprint $table) { // }); } };方式二:添加
in_xxxxx_table语句bashphp artisan make:migration change_fields_in_products_table # INFO Migration [database/migrations/2023_11_16_025304_change_fields_in_products_table.php] created successfully.php// database/migrations/2023_11_16_025304_change_fields_in_products_table.php return new class extends Migration { /** * Run the migrations. */ public function up(): void { Schema::table('products', function (Blueprint $table) { // }); } /** * Reverse the migrations. */ public function down(): void { Schema::table('products', function (Blueprint $table) { // }); } };运行迁移之前输出 SQL
当输入
php artisan migrate --pretend命令时,在终端中会列出待执行的 SQL 查询。如果需要的话,这是一种调试 SQL 的有趣方法。
textphp artisan migrate --pretend # 2023_11_16_025540_whatever_you_want .................................... # ⇂ alter table `products` add `description` varchar(255) null after `name`添加列的描述
可以在迁移中添加有关列的描述并提供有用的信息。
如果数据库由开发人员以外的其他人管理,可以在执行任何操作之前查看表结构中的注释。
php$table->unsignedInteger('interval') ->index() ->comment('This column is used for indexing.')
检查表是否存在
使用 hasTable 方法检查表是否存在:
if (Schema::hasTable('users')) {
// users 表存在
}检查列是否存在
使用 hasColumn 方法检查列是否存在:
if (Schema::hasColumn('users', 'email')) {
// users 表存在并且表包含 `email` 字段
}
从 Laravel 9.6.0 开始添加了 whenTableDoesntHaveColumn 方法,仅当该列不存在时,才可以在数据库表中添加该列;
whenTableHasColumn 方法判断列存在,如果存在,则可以将其删除。
return new class extends Migration {
public function up()
{
// 仅当该列不存在时,才可以在数据库表中添加该列
Schema::whenTableDoesntHaveColumn('users', 'name', function (Blueprint $table) {
$table->string('name', 30);
});
}
public function down()
{
// 判断列存在,如果存在,则可以将其删除。
Schema::whenTableHasColumn('users', 'name', function (Blueprint $table) {
$table->dropColumn('name');
});
}
}