hyperf/docs/en/db/migration.md

504 lines
20 KiB
Markdown
Raw Normal View History

2022-10-31 01:47:12 +08:00
# Database migration
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
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.
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
# Generate migrations
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
Generate a migration file via `gen:migration`, the command is followed by a filename parameter, usually for what the migration is intended to do.
2019-06-08 14:44:32 +08:00
```bash
php bin/hyperf.php gen:migration create_users_table
```
2022-10-31 01:47:12 +08:00
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.
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
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.
2019-06-08 14:44:32 +08:00
```bash
php bin/hyperf.php gen:migration create_users_table --table=users
php bin/hyperf.php gen:migration create_users_table --create=users
```
2022-10-31 01:47:12 +08:00
# Migration structure
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
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.
2019-06-08 14:44:32 +08:00
```php
<?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');
}
}
```
2022-10-31 01:47:12 +08:00
# Run migration
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
Run all pending migration files by executing the `migrate` command:
2019-06-08 14:44:32 +08:00
2019-06-08 14:47:00 +08:00
```bash
2019-06-08 14:44:32 +08:00
php bin/hyperf.php migrate
2019-06-08 14:47:00 +08:00
```
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
## Force the migration
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
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:
2019-06-08 14:44:32 +08:00
2019-06-08 15:28:47 +08:00
```bash
2019-06-08 14:44:32 +08:00
php bin/hyperf.php migrate --force
2019-06-08 14:47:00 +08:00
```
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
## Rollback migration
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
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:
2019-06-08 14:44:32 +08:00
2019-06-08 14:47:00 +08:00
```bash
2019-06-08 14:44:32 +08:00
php bin/hyperf.php migrate:rollback
2019-06-08 14:47:00 +08:00
```
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
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:
2019-06-08 14:44:32 +08:00
2019-06-08 15:28:47 +08:00
```bash
2019-06-08 14:44:32 +08:00
php bin/hyperf.php migrate:rollback --step=5
2019-06-08 14:47:00 +08:00
```
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
If you wish to roll back all migrations, you can do so with `migrate:reset`:
2019-06-08 14:44:32 +08:00
2019-06-08 14:47:00 +08:00
```bash
2019-06-08 14:44:32 +08:00
php bin/hyperf.php migrate:reset
2019-06-08 14:47:00 +08:00
```
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
## Rollback & Migrate
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
`migrate:refresh` The command not only rolls back the migration but also runs `migrate` command, which rebuilds some migrations efficiently:
2019-06-08 14:44:32 +08:00
2019-06-08 14:47:00 +08:00
```bash
2019-06-08 14:44:32 +08:00
php bin/hyperf.php migrate:refresh
2022-10-31 01:47:12 +08:00
// Rebuild database structure and perform data population
2019-06-08 14:44:32 +08:00
php bin/hyperf.php migrate:refresh --seed
2019-06-08 14:47:00 +08:00
```
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
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:
2019-06-08 14:44:32 +08:00
```bash
php bin/hyperf.php migrate:refresh --step=5
```
2022-10-31 01:47:12 +08:00
## Rebuild database
2019-06-08 14:44:32 +08:00
2022-10-31 01:47:12 +08:00
The entire database can be efficiently rebuilt with the `migrate:fresh` command, which deletes all databases before executing the `migrate` command:
2019-06-08 14:44:32 +08:00
```bash
php bin/hyperf.php migrate:fresh
2022-10-31 01:47:12 +08:00
// Rebuild database structure and perform data population
2019-06-08 14:44:32 +08:00
php bin/hyperf.php migrate:fresh --seed
```
2022-10-31 01:47:12 +08:00
# Schema
2019-06-08 15:28:47 +08:00
2022-10-31 01:47:12 +08:00
In the migration file, the `Hyperf\Database\Schema\Schema` class is mainly used to define the data table and manage the migration process.
2019-06-08 15:28:47 +08:00
2022-10-31 01:47:12 +08:00
## Create table
2019-06-08 15:28:47 +08:00
2022-10-31 01:47:12 +08:00
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:
2019-06-08 15:28:47 +08:00
```php
<?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();
});
}
}
```
2022-10-31 01:47:12 +08:00
You can use the following commands on the database structure generator to define options for a table:
2019-06-08 15:31:06 +08:00
```php
2022-10-31 01:47:12 +08:00
// Specify the table storage engine
2019-06-08 15:31:06 +08:00
$table->engine = 'InnoDB';
2022-10-31 01:47:12 +08:00
// Specifies the default character set for data tables
2019-06-08 15:31:06 +08:00
$table->charset = 'utf8';
2022-10-31 01:47:12 +08:00
// Specifies the default collation of the data table
2019-06-08 15:31:06 +08:00
$table->collation = 'utf8_unicode_ci';
2022-10-31 01:47:12 +08:00
// Create a temporary table
2019-06-08 15:31:06 +08:00
$table->temporary();
```
2022-10-31 01:47:12 +08:00
## Rename table
2019-06-08 15:31:06 +08:00
2022-10-31 01:47:12 +08:00
If you wish to rename a data table, you can use the `rename` method:
2019-06-08 15:31:06 +08:00
```php
Schema::rename($from, $to);
```
2022-10-31 01:47:12 +08:00
### Rename table with foreign key
2019-06-08 15:31:06 +08:00
2022-10-31 01:47:12 +08:00
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 .
2019-06-08 15:31:06 +08:00
2022-10-31 01:47:12 +08:00
## Drop table
2019-06-08 15:31:06 +08:00
2022-10-31 01:47:12 +08:00
To drop an existing table, use the `drop` or `dropIfExists` methods:
2019-06-08 15:31:06 +08:00
```php
Schema::drop('users');
Schema::dropIfExists('users');
```
2022-10-31 01:47:12 +08:00
## Check if the data table or field exists
2019-06-08 15:28:47 +08:00
2022-10-31 01:47:12 +08:00
The `hasTable` and `hasColumn` methods can be used to check whether a data table or field exists:
2019-06-08 15:28:47 +08:00
```php
if (Schema::hasTable('users')) {
//
}
if (Schema::hasColumn('name', 'email')) {
//
}
```
2022-10-31 01:47:12 +08:00
## Database connection options
2019-06-08 15:28:47 +08:00
2022-10-31 01:47:12 +08:00
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:
2019-06-08 15:28:47 +08:00
```php
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
2022-10-31 01:47:12 +08:00
// This corresponds to the connection key in config/autoload/databases.php
2019-06-08 15:28:47 +08:00
protected $connection = 'foo';
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
}
}
2019-06-09 01:20:40 +08:00
```
2022-10-31 01:47:12 +08:00
# Fields
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
## Create fields
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
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`:
2019-06-09 01:20:40 +08:00
```php
<?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');
});
}
}
```
2022-10-31 01:47:12 +08:00
## Available field definition methods
| 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 |
## Modify fields
### Prerequisites
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:
2019-06-09 01:20:40 +08:00
```bash
composer require doctrine/dbal
```
2022-10-31 01:47:12 +08:00
### Update field properties
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
`change` Methods can modify existing field types to new types or modify other properties.
2019-06-09 01:20:40 +08:00
```php
<?php
Schema::create('users', function (Blueprint $table) {
2022-10-31 01:47:12 +08:00
// Modify the length of the field to 50
2019-06-09 01:20:40 +08:00
$table->string('name', 50)->change();
});
```
2022-10-31 01:47:12 +08:00
Or modify the field to be `nullable`:
2019-06-09 01:20:40 +08:00
```php
<?php
Schema::table('users', function (Blueprint $table) {
2022-10-31 01:47:12 +08:00
// Modify the length of the field to 50 and allow null
2019-06-09 01:20:40 +08:00
$table->string('name', 50)->nullable()->change();
});
```
2022-10-31 01:47:12 +08:00
> 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.
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
### Rename field
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
Fields can be renamed via the `renameColumn` method:
2019-06-09 01:20:40 +08:00
```php
<?php
Schema::table('users', function (Blueprint $table) {
2022-10-31 01:47:12 +08:00
// Rename field from from to to
2019-06-09 01:20:40 +08:00
$table->renameColumn('from', 'to')->change();
});
```
2022-10-31 01:47:12 +08:00
> Field renaming of type enum is not currently supported.
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
### Delete field
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
Fields can be dropped via the `dropColumn` method:
2019-06-09 01:20:40 +08:00
```php
<?php
Schema::table('users', function (Blueprint $table) {
2022-10-31 01:47:12 +08:00
// Remove the name field
2019-06-09 01:20:40 +08:00
$table->dropColumn('name');
2022-10-31 01:47:12 +08:00
// Delete multiple fields
2019-06-09 01:20:40 +08:00
$table->dropColumn(['name', 'age']);
});
```
2022-10-31 01:47:12 +08:00
#### Available command aliases
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
| 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. |
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
## Index
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
### Create index
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
### Unique index
Use the `unique` method to create a unique index:
2019-06-09 01:20:40 +08:00
```php
<?php
2022-10-31 01:47:12 +08:00
// Create index at definition time
2019-06-09 01:20:40 +08:00
$table->string('name')->unique();
2022-10-31 01:47:12 +08:00
// Create indexes after fields are defined
2019-06-09 01:20:40 +08:00
$table->unique('name');
```
2022-10-31 01:47:12 +08:00
#### Compound index
2019-06-09 01:20:40 +08:00
```php
<?php
2022-10-31 01:47:12 +08:00
// Create a compound index
2019-06-09 01:20:40 +08:00
$table->index(['account_id', 'created_at'], 'index_account_id_and_created_at');
```
2022-10-31 01:47:12 +08:00
#### Define index name
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
The migrator automatically generates a reasonable index name, and each index method accepts an optional second argument to specify the name of the index:
2019-06-09 01:20:40 +08:00
```php
<?php
2022-10-31 01:47:12 +08:00
// Define a unique index name as unique_name
2019-06-09 01:20:40 +08:00
$table->unique('name', 'unique_name');
2022-10-31 01:47:12 +08:00
// Define a composite index named index_account_id_and_created_at
2019-06-09 01:20:40 +08:00
$table->index(['account_id', 'created_at'], '');
```
2022-10-31 01:47:12 +08:00
##### Available index types
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
| 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 |
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
### Rename index
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
You can rename an index with the `renameIndex` method:
2019-06-09 01:20:40 +08:00
```php
<?php
$table->renameIndex('from', 'to');
```
2022-10-31 01:47:12 +08:00
### delete index
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
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:
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
| 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 |
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
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:
2019-06-09 01:20:40 +08:00
```php
<?php
Schema:table('users', function (Blueprint $table) {
$table->dropIndex(['account_id', 'created_at']);
});
```
2022-10-31 01:47:12 +08:00
### foreign key constraints
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
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:
2019-06-09 01:20:40 +08:00
```php
Schema::table('posts', function (Blueprint $table) {
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
```
2022-10-31 01:47:12 +08:00
You can also specify the desired action for the `on delete` and `on update` properties:
2019-06-09 01:20:40 +08:00
```php
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
```
2022-10-31 01:47:12 +08:00
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:
2019-06-09 01:20:40 +08:00
2019-06-15 23:31:39 +08:00
```php
2019-06-09 01:20:40 +08:00
$table->dropForeign('posts_user_id_foreign');
2019-06-15 23:31:39 +08:00
```
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
Or pass an array of fields and have the migrator generate the names according to the agreed-upon rules:
2019-06-09 01:20:40 +08:00
2020-02-22 12:19:50 +08:00
```php
2019-06-09 01:20:40 +08:00
$table->dropForeign(['user_id'']);
2019-06-15 23:31:39 +08:00
```
2019-06-09 01:20:40 +08:00
2022-10-31 01:47:12 +08:00
You can turn foreign key constraints on or off using the following methods in the migration file:
2019-06-09 01:20:40 +08:00
```php
2022-10-31 01:47:12 +08:00
// Enable foreign key constraints
2019-06-09 01:20:40 +08:00
Schema::enableForeignKeyConstraints();
2022-10-31 01:47:12 +08:00
// Disable foreign key constraints
2019-06-09 01:20:40 +08:00
Schema::disableForeignKeyConstraints();
2020-02-22 12:19:50 +08:00
```