数据库迁移

生成迁移

通过 生成一个迁移文件,命令后面跟的是一个文件名参数,通常为这个迁移要打算做的事情。

生成的迁移文件位于根目录下的 migrations 文件夹内,每个迁移文件都包含一个时间戳,以便迁移程序确定迁移的顺序。

—table 选项可以用来指定数据表的名称,指定的表名将会默认生成在迁移文件中。—create 选项也是用来指定数据表的名称,但跟 —table 的差异在于该选项是生成创建表的迁移文件,而 —table 是用于修改表的迁移文件。

  1. php bin/hyperf.php gen:migration create_users_table --table=users
  2. php bin/hyperf.php gen:migration create_users_table --create=users

迁移结构

迁移类默认会包含 2 个方法:updownup 方法用于添加新的数据表,字段或者索引到数据库,而 down 方法就是 up 方法的反操作,和 up 里的操作相反,以便在回退的时候执行。

  1. <?php
  2. use Hyperf\Database\Schema\Schema;
  3. use Hyperf\Database\Schema\Blueprint;
  4. use Hyperf\Database\Migrations\Migration;
  5. class CreateUsersTable extends Migration
  6. {
  7. /**
  8. * Run the migrations.
  9. */
  10. public function up(): void
  11. {
  12. Schema::create('true', function (Blueprint $table) {
  13. $table->bigIncrements('id');
  14. $table->timestamps();
  15. });
  16. }
  17. /**
  18. * Reverse the migrations.
  19. */
  20. public function down(): void
  21. {
  22. Schema::dropIfExists('true');
  23. }
  24. }

运行迁移

通过执行 migrate 命令运行所有尚未完成的迁移文件:

    一些迁移操作是具有破坏性的,这意味着可能会导致数据丢失,为了防止有人在生产环境中运行这些命令,系统会在这些命令运行之前与你进行确认,但如果您希望忽略这些确认信息强制运行命令,可以使用 —force 标记:

    1. php bin/hyperf.php migrate --force

    回滚迁移

    若您希望回滚最后一次的迁移,可以通过 migrate:rollback 命令回滚最后一侧的迁移,注意一次迁移可能会包含多个迁移文件:

    1. php bin/hyperf.php migrate:rollback

    您还可以在 migrate:rollback 命令后面加上 step 参数来设置回滚迁移的次数,比如以下命令将回滚最近 5 次迁移:

    1. php bin/hyperf.php migrate:rollback --step=5

    如果您希望回滚所有的迁移,可以通过 migrate:reset 来回滚:

    1. php bin/hyperf.php migrate:reset

    回滚并迁移

    migrate:refresh 命令不仅会回滚迁移还会接着运行 migrate 命令,这样可以高效地重建某些迁移:

    1. php bin/hyperf.php migrate:refresh
    2. // 重建数据库结构并执行数据填充
    3. php bin/hyperf.php migrate:refresh --seed

    通过 —step 参数指定回滚和重建次数,比如以下命令将回滚并重新执行最后 5 次迁移:

    1. php bin/hyperf.php migrate:refresh --step=5

    重建数据库

    通过 migrate:fresh 命令可以高效地重建整个数据库,这个命令会先删除所有的数据库,然后再执行 migrate 命令:

    1. php bin/hyperf.php migrate:fresh
    2. // 重建数据库结构并执行数据填充
    3. php bin/hyperf.php migrate:fresh --seed

    数据表

    通过 create 方法来创建新的数据库表。 create 方法接受两个参数:第一个参数为数据表的名称,第二个参数是一个 ,此闭包会接收一个用于定义新数据表的 Hyperf\Database\Schema\Blueprint 对象:

    您可以在数据库结构生成器上使用以下命令来定义表的选项:

    1. // 指定表存储引擎
    2. $table->engine = 'InnoDB';
    3. // 指定数据表的默认字符集
    4. $table->charset = 'utf8';
    5. // 指定数据表默认的排序规则
    6. $table->collation = 'utf8_unicode_ci';
    7. // 创建临时表
    8. $table->temporary();

    重命名数据表

    若您希望重命名一个数据表,可以通过 rename 方法:

    1. Schema::rename($from, $to);

    在重命名表之前,您应该验证表上的所有外键约束在迁移文件中都有明确的名称,而不是让迁移程序按照约定来设置一个名称,否则,外键的约束名称将引用旧表名。

    删除数据表

    删除一个已存在的数据表,可以通过 dropdropIfExists 方法:

    1. Schema::drop('users');
    2. Schema::dropIfExists('users');

    检查数据表或字段是否存在

    可以通过 hasTablehasColumn 方法来检查数据表或字段是否存在:

    1. if (Schema::hasTable('users')) {
    2. //
    3. }
    4. if (Schema::hasColumn('name', 'email')) {
    5. //
    6. }

    如果在同时管理多个数据库的情况下,不同的迁移会对应不同的数据库连接,那么此时我们可以在迁移文件中通过重写父类的 $connection 类属性来定义不同的数据库连接:

    1. <?php
    2. use Hyperf\Database\Schema\Schema;
    3. use Hyperf\Database\Schema\Blueprint;
    4. use Hyperf\Database\Migrations\Migration;
    5. class CreateUsersTable extends Migration
    6. {
    7. // 这里对应 config/autoload/databases.php 内的连接 key
    8. protected $connection = 'foo';
    9. public function up(): void
    10. {
    11. Schema::create('users', function (Blueprint $table) {
    12. $table->bigIncrements('id');
    13. $table->timestamps();
    14. });
    15. }
    16. }

    字段

    创建字段

    tablecreate 方法的第二个参数的 闭包(Closure) 内定义该迁移文件要执行的定义或变更,比如下面的代码为定义一个 name 的字符串字段:

    1. <?php
    2. use Hyperf\Database\Schema\Schema;
    3. use Hyperf\Database\Schema\Blueprint;
    4. use Hyperf\Database\Migrations\Migration;
    5. class CreateUsersTable extends Migration
    6. {
    7. public function up(): void
    8. {
    9. $table->string('name');
    10. });
    11. }
    12. }

    可用的字段定义方法

    修改字段

    先决条件

    在修改字段之前,请确保将 doctrine/dbal 依赖添加到 composer.json 文件中。Doctrine DBAL 库用于确定字段的当前状态, 并创建对该字段进行指定调整所需的 SQL 查询:

    1. composer require doctrine/dbal

    更新字段属性

    change 方法可以将现有的字段类型修改为新的类型或修改其它属性。

    1. <?php
    2. Schema::create('users', function (Blueprint $table) {
    3. // 将字段的长度修改为 50
    4. $table->string('name', 50)->change();
    5. });

    或修改字段为 可为空

    1. <?php
    2. Schema::table('users', function (Blueprint $table) {
    3. // 将字段的长度修改为 50 并允许为空
    4. $table->string('name', 50)->nullable()->change();
    5. });
    1. <?php
    2. Schema::table('users', function (Blueprint $table) {
    3. // 将字段从 from 重命名为 to
    4. $table->renameColumn('from', 'to')->change();
    5. });

    当前不支持 enum 类型的字段重命名。

    删除字段

    可以通过 dropColumn 方法来删除字段:

    可用的命令别名

    创建索引

    通过 unique 方法来创建一个唯一索引:

    1. <?php
    2. // 在定义时创建索引
    3. $table->string('name')->unique();
    4. // 在定义完字段之后创建索引
    5. $table->unique('name');

    复合索引

    1. <?php
    2. // 创建一个复合索引
    3. $table->index(['account_id', 'created_at'], 'index_account_id_and_created_at');

    定义索引名称

    迁移程序会自动生成一个合理的索引名称,每个索引方法都接受一个可选的第二个参数来指定索引的名称:

    1. <?php
    2. // 定义唯一索引名称为 unique_name
    3. $table->unique('name', 'unique_name');
    4. // 定义一个复合索引名称为 index_account_id_and_created_at
    5. $table->index(['account_id', 'created_at'], '');
    可用的索引类型

    重命名索引

    您可通过 renameIndex 方法重命名一个索引的名称:

    1. <?php
    2. $table->renameIndex('from', 'to');

    删除索引

    您可通过下面的方法来删除索引,默认情况下迁移程序会自动将数据库名称、索引的字段名及索引类型简单地连接在一起作为名称。举例如下:

    您也可以通过传递字段数组到 dropIndex 方法,迁移程序会根据表名、字段和键类型生成的索引名称:

    1. <?php
    2. Schema:table('users', function (Blueprint $table) {
    3. $table->dropIndex(['account_id', 'created_at']);
    4. });

    我们还可以通过 foreignreferenceson 方法创建数据库层的外键约束。比如我们让 posts 表定义一个引用 users 表的 id 字段的 user_id 字段:

    1. Schema::table('posts', function (Blueprint $table) {
    2. $table->unsignedInteger('user_id');
    3. $table->foreign('user_id')->references('id')->on('users');
    4. });

    还可以为 on deleteon update 属性指定所需的操作:

    1. $table->foreign('user_id')
    2. ->references('id')->on('users')
    3. ->onDelete('cascade');

    您可以通过 dropForeign 方法来删除外键。外键约束采用的命名方式与索引相同,然后加上 _foreign 后缀:

    1. $table->dropForeign('posts_user_id_foreign');

    或者传递一个字段数组,让迁移程序按照约定的规则生成名称:

    1. $table->dropForeign(['user_id'']);

    您可以在迁移文件中使用以下方法来开启或关闭外键约束:

    1. // 开启外键约束
    2. Schema::enableForeignKeyConstraints();
    3. Schema::disableForeignKeyConstraints();