docs/en/db/migration.md
Database migration can be understood as version management of the database structure, which can effectively solve the management of the database structure across members of the team.
Generate a migration file via gen:migration, the command is followed by a filename parameter, usually for what the migration is intended to do.
php bin/hyperf.php gen:migration create_users_table
The generated migration files are located in the migrations folder in the root directory, and each migration file includes a timestamp so that the migration program can determine the order of migrations.
The --table option can be used to specify the name of the data table. The specified table name will be generated in the migration file by default.
The --create option is also used to specify the name of the data table, but the difference from --table is that this option generates a migration file for creating a table, while --table is a migration file for modifying the table.
php bin/hyperf.php gen:migration create_users_table --table=users
php bin/hyperf.php gen:migration create_users_table --create=users
The migration class will contain 2 methods by default: up and down.
The up method is used to add a new data table, field or index to the database, and the down method is the inverse of the up method, which is the opposite of the operation in up, so that it is executed during rollback.
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('true', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('true');
}
}
Run all pending migration files by executing the migrate command:
php bin/hyperf.php migrate
Some migration operations are destructive, which means that data loss may result. To prevent someone from running these commands in a production environment, the system will confirm with you before these commands are run, but if you wish to ignore these confirmations, force To run a command, you can use the --force flag:
php bin/hyperf.php migrate --force
If you want to roll back the last migration, you can use the migrate:rollback command to roll back the last migration. Note that a migration may contain multiple migration files:
php bin/hyperf.php migrate:rollback
You can also set the number of rollback migrations by appending the step parameter to the migrate:rollback command. For example, the following command will roll back the last 5 migrations:
php bin/hyperf.php migrate:rollback --step=5
If you wish to roll back all migrations, you can do so with migrate:reset:
php bin/hyperf.php migrate:reset
migrate:refresh The command not only rolls back the migration but also runs migrate command, which rebuilds some migrations efficiently:
php bin/hyperf.php migrate:refresh
// Rebuild database structure and perform data population
php bin/hyperf.php migrate:refresh --seed
Specify the number of rollbacks and rebuilds with the --step parameter. For example, the following command will rollback and re-execute the last 5 migrations:
php bin/hyperf.php migrate:refresh --step=5
The entire database can be efficiently rebuilt with the migrate:fresh command, which deletes all databases before executing the migrate command:
php bin/hyperf.php migrate:fresh
// Rebuild database structure and perform data population
php bin/hyperf.php migrate:fresh --seed
In the migration file, the Hyperf\Database\Schema\Schema class is mainly used to define the data table and manage the migration process.
Create a new database table with the create method. The create method accepts two parameters: the first parameter is the name of the data table, and the second parameter is a Closure, which will receive a Hyperf\Database' to define the new data table \Schema\Blueprint object:
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
}
}
You can use the following commands on the database structure generator to define options for a table:
// Specify the table storage engine
$table->engine = 'InnoDB';
// Specifies the default character set for data tables
$table->charset = 'utf8';
// Specifies the default collation of the data table
$table->collation = 'utf8_unicode_ci';
// Create a temporary table
$table->temporary();
If you wish to rename a data table, you can use the rename method:
Schema::rename($from, $to);
Before renaming a table, you should verify that all foreign key constraints on the table have an explicit name in the migration file, rather than letting the migration program set a name by convention, otherwise, the foreign key's constraint name will refer to the old table name .
To drop an existing table, use the drop or dropIfExists methods:
Schema::drop('users');
Schema::dropIfExists('users');
The hasTable and hasColumn methods can be used to check whether a data table or field exists:
if (Schema::hasTable('users')) {
//
}
if (Schema::hasColumn('name', 'email')) {
//
}
If multiple databases are managed at the same time, different migrations will correspond to different database connections, then we can define different database connections in the migration file by overriding the $connection class attribute of the parent class:
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
// This corresponds to the connection key in config/autoload/databases.php
protected $connection = 'foo';
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
}
}
Define the definition or change to be performed by the migration file within the Closure of the second parameter of the table or create method. For example, the following code defines a string field of name:
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->string('name');
});
}
}
| Command | Description |
|---|---|
| $table->bigIncrements('id'); | Increment ID (primary key), equivalent to "UNSIGNED BIG INTEGER" |
| $table->bigInteger('votes'); | equivalent to BIGINT |
| $table->binary('data'); | equivalent to BLOB |
| $table->boolean('confirmed'); | equivalent to BOOLEAN |
| $table->char('name', 100); | equivalent to with length CHAR |
| $table->date('created_at'); | equivalent to DATE |
| $table->dateTime('created_at'); | equivalent to DATETIME |
| $table->dateTimeTz('created_at'); | equivalent to with time zone DATETIME |
| $table->decimal('amount', 8, 2); | equivalent to with precision and base DECIMAL |
| $table->double('amount', 8, 2); | equivalent to with precision and base DOUBLE |
| $table->enum('level', ['easy', 'hard']); | equivalent to ENUM |
| $table->float('amount', 8, 2); | equivalent to with precision and base FLOAT |
| $table->geometry('positions'); | equivalent to GEOMETRY |
| $table->geometryCollection('positions'); | equivalent to GEOMETRYCOLLECTION |
| $table->increments('id'); | Incrementing ID (primary key), equivalent to "UNSIGNED INTEGER" |
| $table->integer('votes'); | equivalent to INTEGER |
| $table->ipAddress('visitor'); | equivalent to IP address |
| $table->json('options'); | equivalent to JSON |
| $table->jsonb('options'); | equivalent to JSONB |
| $table->lineString('positions'); | equivalent to LINESTRING |
| $table->longText('description'); | equivalent to LONGTEXT |
| $table->macAddress('device'); | equivalent to MAC address |
| $table->mediumIncrements('id'); | Increment ID (primary key), equivalent to "UNSIGNED MEDIUM INTEGER" |
| $table->mediumInteger('votes'); | equivalent to MEDIUMINT |
| $table->mediumText('description'); | equivalent to MEDIUMTEXT |
| $table->morphs('taggable'); | equivalent to adding incremental taggable_id and string taggable_type |
| $table->multiLineString('positions'); | equivalent to MULTILINESTRING |
| $table->multiPoint('positions'); | equivalent to MULTIPOINT |
| $table->multiPolygon('positions'); | equivalent to MULTIPOLYGON |
| $table->nullableMorphs('taggable'); | equivalent to nullable version morphs() field |
| $table->nullableTimestamps(); | equivalent to nullable version timestamps() field |
| $table->point('position'); | equivalent to POINT |
| $table->polygon('positions'); | equivalent to POLYGON |
| $table->rememberToken(); | equivalent to nullable version VARCHAR (100) of remember_token field |
| $table->smallIncrements('id'); | Increment ID (primary key), equivalent to "UNSIGNED SMALL INTEGER" |
| $table->smallInteger('votes'); | equivalent to SMALLINT |
| $table->softDeletes(); | equivalent to add a nullable for soft delete deleted_at field |
| $table->softDeletesTz(); | equivalent to add a nullable for soft delete deleted_at field with time zone |
| $table->string('name', 100); | equivalent to with length VARCHAR |
| $table->text('description'); | equivalent to TEXT |
| $table->time('sunrise'); | equivalent to TIME |
| $table->timeTz('sunrise'); | equivalent to with time zone of TIME |
| $table->timestamp('added_on'); | equivalent to TIMESTAMP |
| $table->timestampTz('added_on'); | equivalent to with time zone TIMESTAMP |
| $table->timestamps(); | equivalent to nullable created_at and updated_at TIMESTAMP |
| $table->timestampsTz(); | equivalent to nullable with timezone created_at and updated_at TIMESTAMP |
| $table->tinyIncrements('id'); | equivalent to auto increment UNSIGNED TINYINT |
| $table->tinyInteger('votes'); | equivalent to TINYINT |
| $table->unsignedBigInteger('votes'); | equivalent to UNSIGNED BIGINT |
| $table->unsignedDecimal('amount', 8, 2); | equivalent to with precision and base UNSIGNED DECIMAL |
| $table->unsignedInteger('votes'); | equivalent to UNSIGNED INT |
| $table->unsignedMediumInteger('votes'); | equivalent to UNSIGNED MEDIUMINT |
| $table->unsignedSmallInteger('votes'); | equivalent to UNSIGNED SMALLINT |
| $table->unsignedTinyInteger('votes'); | equivalent to UNSIGNED TINYINT |
| $table->uuid('id'); | equivalent to UUID |
| $table->year('birth_year'); | equivalent to YEAR |
| $table->comment('Table Comment'); | Set table comment, equivalent to COMMENT |
Make sure to add the doctrine/dbal dependency to the composer.json file before modifying the fields. The Doctrine DBAL library is used to determine the current state of a field and create the SQL query required to make the specified adjustments to that field:
composer require "doctrine/dbal:^3.0"
change Methods can modify existing field types to new types or modify other properties.
<?php
Schema::create('users', function (Blueprint $table) {
// Modify the length of the field to 50
$table->string('name', 50)->change();
});
Or modify the field to be nullable:
<?php
Schema::table('users', function (Blueprint $table) {
// Modify the length of the field to 50 and allow null
$table->string('name', 50)->nullable()->change();
});
Only the following field types can be "modified": bigInteger, binary, boolean, date, dateTime, dateTimeTz, decimal, integer, json, longText, mediumText, smallInteger, string, text, time, unsignedBigInteger, unsignedInteger and unsignedSmallInteger.
Fields can be renamed via the renameColumn method:
<?php
Schema::table('users', function (Blueprint $table) {
// Rename field from from to to
$table->renameColumn('from', 'to')->change();
});
Field renaming of type enum is not currently supported.
Fields can be dropped via the dropColumn method:
<?php
Schema::table('users', function (Blueprint $table) {
// Remove the name field
$table->dropColumn('name');
// Delete multiple fields
$table->dropColumn(['name', 'age']);
});
| Command | Description |
|---|---|
| $table->dropRememberToken(); | Remove the remember_token field. |
| $table->dropSoftDeletes(); | Delete the deleted_at field. |
| $table->dropSoftDeletesTz(); | Alias for the dropSoftDeletes() method. |
| $table->dropTimestamps(); | Delete the created_at and updated_at fields. |
| $table->dropTimestampsTz(); | Alias for the dropTimestamps() method. |
Use the unique method to create a unique index:
<?php
// Create index at definition time
$table->string('name')->unique();
// Create indexes after fields are defined
$table->unique('name');
<?php
// Create a compound index
$table->index(['account_id', 'created_at'], 'index_account_id_and_created_at');
The migrator automatically generates a reasonable index name, and each index method accepts an optional second argument to specify the name of the index:
<?php
// Define a unique index name as unique_name
$table->unique('name', 'unique_name');
// Define a composite index named index_account_id_and_created_at
$table->index(['account_id', 'created_at'], '');
| Command | Description |
|---|---|
| $table->primary('id'); | Add primary key |
| $table->primary(['id', 'parent_id']); | Add composite key |
| $table->unique('email'); | Add unique index |
| $table->index('state'); | Add normal index |
| $table->spatialIndex('location'); | Add spatial index |
You can rename an index with the renameIndex method:
<?php
$table->renameIndex('from', 'to');
You can drop an index in the following way. By default, the migration program will automatically concatenate the database name, the field name of the index, and the index type as the name. Examples are as follows:
| Command | Description |
|---|---|
| $table->dropPrimary('users_id_primary'); | Drop the primary key from the users table |
| $table->dropUnique('users_email_unique'); | Drop unique index from users table |
| $table->dropIndex('geo_state_index'); | Drop base index from geo table |
| $table->dropSpatialIndex('geo_location_spatialindex'); | Drop the spatial index from the geo table |
You can also pass an array of fields to the dropIndex method and the migrator will generate an index name based on the table name, field and key type:
<?php
Schema:table('users', function (Blueprint $table) {
$table->dropIndex(['account_id', 'created_at']);
});
We can also create foreign key constraints at the database layer through the foreign, references, on methods. For example, let's let the posts table define a user_id field that references the id field of the users table:
Schema::table('posts', function (Blueprint $table) {
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
You can also specify the desired action for the on delete and on update properties:
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
You can drop foreign keys with the dropForeign method. Foreign key constraints are named in the same way as indexes, followed by a _foreign suffix:
$table->dropForeign('posts_user_id_foreign');
Or pass an array of fields and have the migrator generate the names according to the agreed-upon rules:
$table->dropForeign(['user_id'']);
You can turn foreign key constraints on or off using the following methods in the migration file:
// Enable foreign key constraints
Schema::enableForeignKeyConstraints();
// Disable foreign key constraints
Schema::disableForeignKeyConstraints();