Database migration


Database: Migration

Introduction

Migration is like version control of the database, allowing teams to simply and easily edit and To share the application's database table structure, migration is often used in conjunction with Laravel's database structure generator, allowing you to easily build a database structure. If you've ever had to ask a colleague to manually add fields to a database structure, database migration can save you from having to do that.

Laravel’s

Schema facade provides corresponding support for creating and operating data tables for all database systems supported by Laravel.

Generate migrations

Use the Artisan command make:migration to create migrations.

php artisan make:migration create_users_table

New migrations are located in the database/migrations directory. Each migration file name includes a timestamp to allow Laravel to confirm the order of migrations. The

--table and --create options can be used to specify the name of the data table, or whether a new data table will be created when the migration is executed. These options need to be filled in the specified data table when pre-generating the migration file:

php artisan make:migration create_users_table --create=users

php artisan make:migration add_votes_to_users_table --table=users

If you want to specify a custom output path to generate the migration, you can run make:migration Add the --path option when commanding. The given path must be relative to the base path of the application.

Migration structure

The migration class usually contains 2 methods: 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 reverse operation of the up method, and up# The operations in ## are reversed.

In these two methods, Laravel's

Schema builder is used to create and modify tables. To understand the
Schema generator For all available methods, you can view its documentation. For example, a simple example of creating the flights table:

<?php
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    class CreateFlightsTable extends Migration{  
      /**
     * 运行数据库迁移
     *
     * @return void
     */    
     public function up()   
      {       
       Schema::create('flights', function (Blueprint $table) {  
                 $table->increments('id');            
                 $table->string('name');            
                 $table->string('airline');            
                 $table->timestamps();        
             });   
          }   
     /**
     * 回滚数据库迁移
     *
     * @return void
     */   
    public function down()   
     {       
      Schema::drop('flights');   
      }
 }

Run migration

Execute Artisan Command

migrate to run all outstanding migrations:

php artisan migrate

{Note} If you are using a Homestead virtual machine, you should execute this command in your virtual machine.

Forcing migration in a production environment

Some migration operations are destructive, meaning that data loss may occur. To prevent someone from running these commands in a production environment, the system will confirm with you before these commands are run. If you want to force the command to be run regardless of the system prompts, you can use the

--force tag:

php artisan migrate --force

Return Rolling migration

To roll back the last migration, you can use the

rollback command. This command will roll back the last "migration" operation, which may contain multiple migration files:

php artisan migrate:rollback

You can add the

step parameter after the rollback command , to limit the number of rollback migrations. For example, the following command will roll back the last five migrations:

php artisan migrate:rollback --step=5

migrate:reset The command can roll back all migrations in the application:

php artisan migrate:reset

Use a single command to perform a rollback or migration

migrate:refresh The command will not only roll back all migrations of the database but will also run the migrate command. This command can efficiently rebuild the entire database:

php artisan migrate:refresh
// 刷新数据库结构并执行数据填充
php artisan migrate:refresh --seed

Use the refresh command and provide the step parameter to roll back and perform the last specified number of migrations. For example, the following command will roll back and re-execute the last five migrations:

php artisan migrate:refresh --step=5

Delete all tables & migrate

The migrate:fresh command All tables will be deleted from the database, and then the migrate command will be executed:

php artisan migrate:fresh

php artisan migrate:fresh --seed

##data table

Create data table

Can be created using the

create method of the Schema facade New database table. The create method accepts two parameters: the first parameter is the name of the data table, and the second parameter is Closure. This closure will receive a # used to define a new data table. ##Blueprint Object:

Schema::create('users', function (Blueprint $table) 
{   
 $table->increments('id');
});
Of course, when creating a data table, you can use the

field method

of any database structure generator to define the fields of the data table.

Check whether the data table/field exists

You can use the

hasTable

and hasColumn methods to check whether the data table or field exists Existence:

if (Schema::hasTable('users')) { 
   //
   }
if (Schema::hasColumn('users', 'email')) { 
      //
    }

Database Connection & Table Options

If you want to perform structural operations on a database connection that is not the default connection, you can use the connection method:

Schema::connection('foo')->create('users', function (Blueprint $table) { 
   $table->increments('id');
  });

You can use the database structure Use the following command on the generator to define options for the table:

CommandDescription
$table->engine = 'InnoDB';Specify the table storage engine (MySQL).
$table->charset = 'utf8';Specify the default character set of the data table (MySQL).
$table->collation = 'utf8_unicode_ci';Specify the default collation of the data table (MySQL).
$table->temporary();Create a temporary table (SQL Server is not supported).

Rename/delete data table

To rename the data table, you can use the rename method :

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

To delete an existing data table, you can use drop or dropIfExists method:

Schema::drop('users');Schema::dropIfExists('users');

rename Data tables with foreign keys

Before renaming a table, you should verify that any foreign key constraints on the table have an explicit name in the migration file, rather than letting Laravel set a name according to a convention. Otherwise, the foreign key's constraint name will refer to the old table name.

Field

Create Field

Use the table method of the Schema facade to update an existing data table. Like the create method, the table method accepts two parameters: one is the name of the data table, and the other is a Blueprint that can be used to add fields to the table. Closure of instance:

Schema::table('users', function (Blueprint $table) { 
   $table->string('email');
  });

Available field types

The database structure generator contains various field types that can be specified when building a table:

Increment ID (primary key), equivalent to "UNSIGNED BIG INTEGER"##$table->bigInteger('votes' );##$table->binary('data');$table->boolean('confirmed');$table->char('name', 100);$table->date('created_at');##$table->dateTime('created_at ');Equivalent to DATETIME with time zone##$table->decimal('amount', 8, 2);Equivalent to Precision and base DECIMAL is equivalent to with precision and Base DOUBLE## Increasing ID (primary key), equivalent to "UNSIGNED INTEGER" ##$table->integer('votes');##$table->ipAddress('visitor');$table->json('options');$table->jsonb('options');##$table->lineString( 'positions');Equivalent to LONGTEXTEquivalent to MAC address Increment ID (primary key), equivalent to "UNSIGNED MEDIUM INTEGER"Equivalent to MEDIUMINT is equivalent to MEDIUMTEXTEquivalent to MULTILINESTRINGEquivalent to MULTIPOINTEquivalent to MULTIPOLYGON##$table->nullableMorphs('taggable');morphs()##$table->nullableTimestamps(); Field##$table->point('position');Equivalent to POLYGONEquivalent to the Increment ID (primary key), equivalent to "UNSIGNED SMALL INTEGER"$table->smallInteger('votes'); is equivalent to SMALLINT$table->softDeletes();Equivalent to adding a nullable deleted_atEquivalent to TIME##$table->timeTz('sunrise');#$table->timestamp('added_on');##$table->timestampTz('added_on'); Equivalent to the nullable TIMESTAMPEquivalent to created_at Equivalent to automatically incrementing UNSIGNED TINYINT is equivalent to TINYINTEquivalent to Unsigned BIGINT with precision and baseEquivalent to Unsigned SMALLINT##$table->unsignedTinyInteger('votes');##$table->uuid('id');$table->year('birth_year');

Field modification

In addition to the field types listed above, there are several "modifiers" that can be used when adding fields to database tables. For example, if you want to make a field "nullable", you can use the nullable method:

Schema::table('users', function (Blueprint $table) {
    $table->string('email')->nullable();
 });

The following is a list of all available field modifiers. This list does not include index modifiers:

CommandDescription
##$table->bigIncrements('id ');
Equivalent to BIGINT
Equivalent to BLOB
Equivalent to BOOLEAN
Equivalent to CHAR with length
Equivalent to DATE
Equivalent to DATETIME##$table->dateTimeTz('created_at');
##$table->double('amount', 8, 2);
##$table->enum('level', ['easy', 'hard']);Equivalent ENUM
$table->float('amount', 8, 2); is equivalent to FLOAT# with precision and base
$table->geometry('positions');Equivalent to GEOMETRY
$table ->geometryCollection('positions');Equivalent to GEOMETRYCOLLECTION
##$table->increments('id');
Equivalent to INTEGER
Equivalent to IP address
is equivalent to JSON
Equivalent to JSONB
Equivalent to LINESTRING##$table->longText('description');
$table->macAddress('device');
$table->mediumIncrements('id');
$table->mediumInteger('votes');
$ table->mediumText('description');
$table->morphs('taggable'); is equivalent to adding the incrementing taggable_id and the string taggable_type
##$table->multiLineString('positions');
$table->multiPoint('positions');
$table-> multiPolygon('positions');
Equivalent to the nullable version of Field
Equivalent to the nullable version of timestamps()
Equivalent to POINT##$table->polygon('positions');
$table->rememberToken();
remember_token field of the nullable version of VARCHAR (100) ##$table->smallIncrements('id');
field for soft deletion
$table->softDeletesTz();Equivalent to adding a nullable deleted_at field with time zone for soft deletion
$table->string('name', 100); Equivalent to VARCHAR with length
$table->text('description');Equivalent to TEXT
##$table-> ;time('sunrise');
Equivalent to TIME with time zone
Equivalent to TIMESTAMP
is equivalent to TIMESTAMP# with time zone ##$table->timestamps();
created_at and updated_at ##$table->timestampsTz();
and updated_at which are nullable and have time zone TIMESTAMP##$table->tinyIncrements('id');
$table->tinyInteger('votes');
$table->unsignedBigInteger('votes');
##$table->unsignedDecimal('amount' , 8, 2); is equivalent to UNSIGNED DECIMAL
$table->unsignedInteger('votes');Equivalent to Unsigned INT
$ table->unsignedMediumInteger('votes');Equivalent to Unsigned MEDIUMINT
##$table->unsignedSmallInteger('votes') ;
Equivalent to Unsigned TINYINT
Equivalent to UUID
Equivalent to YEAR
Place this field "after" other fields (MySQL)Set a field of type INTEGER as an auto-incrementing primary keySpecify a character set (MySQL)Specify the collation of the column (MySQL/SQL Server)Add comments to fields (MySQL)Specify the "default" value for the fieldPlace this field at the "first position" of the data table (MySQL)This field allows NULL values ​​to be written (by default)Create A storage-generated field (MySQL)##->unsigned()->useCurrent()->virtualAs($expression)

Modify fields

Prerequisites

Before modifying fields, please make sure Add the doctrine/dbal dependency to the composer.json file. The Doctrine DBAL library is used to determine the current state of a field and create the SQL queries required to make specified adjustments to the field:

composer require doctrine/dbal

Update Field Properties

The change method can modify the existing field type to a new type or modify attributes.
For example, you may want to increase. For the length of the string field, you can use the change method to increase the length of the name field from 25 to 50:

 Schema::table('users', function (Blueprint $table) { 
    $table->string('name', 50)->change(); 
  });

We should modify the field to be nullable:

Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->nullable()->change();
  });

{Note} 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.

Renaming Fields

Fields can be renamed using the renameColumn method on the structure builder. Before renaming fields, please make sure that doctrine/dbal has been added to your composer.json file. Dependency:

Schema::table('users', function (Blueprint $table) {
    $table->renameColumn('from', 'to');
 });

{Note} Currently not supported Field renaming of enum type.

To delete a field

you can use the dropColumn method on the structure builder to delete the field. Before deleting fields from the SQLite database, you need to add the doctrine/dbal dependency to the composer.json file and execute composer update in the terminal to install the dependency:

Schema::table('users', function (Blueprint $table) {
    $table->dropColumn('votes');
 });

You can pass an array of fields to the dropColumn method to delete multiple fields:

Schema::table('users', function (Blueprint $table) {  
  $table->dropColumn(['votes', 'avatar', 'location']);
});

{Note} It is not supported to delete multiple fields when using a SQLite database. Delete or modify multiple fields during migration.

Available command aliases

ModifierDescription
##->after('column')
->autoIncrement()
->charset('utf8')
->collation('utf8_unicode_ci')
->comment('my comment')
->default($value)
->first()
->nullable($value = true)
->storedAs($expression)
Set the INTEGER type field to UNSIGNED (MySQL)
Set a field of type TIMESTAMP to use CURRENT_TIMESTAMP as the default value
Create a virtual generated field (MySQL)
Delete

Index

##Create index

The structure generator supports multiple types of indexes. First, specify that the field value is unique, that is, simply call the

unique method in a chain after the field definition to create an index, for example:

$table->string('email')->unique();

Or, you can also create it after defining the field. index. For example:

$table->unique('email');

You can even pass an array to the index method to create a composite (or synthetic) index:

$table->index(['account_id', 'created_at']);

Laravel will automatically generate a sensible index name, but you can also pass The second parameter to customize the index name:

$table->unique('email', 'unique_email');

Available index types

Each index method accepts an optional second parameter to specify the index name. If omitted, names will be generated based on table and column names.

CommandDescription
$table->dropRememberToken();Delete the remember_token field.
$table->dropSoftDeletes();Delete the deleted_at field.
$table->dropSoftDeletesTz();dropSoftDeletes() Alias ​​for the method.
##$table->dropTimestamps();created_at and updated_at fields .
$table->dropTimestampsTz();dropTimestamps() Alias ​​for the method.
CommandDescription##$table->primary ('id');$table->primary(['id', 'parent_id']); ##$table->unique('email');$table->index('state');$table->spatialIndex('location');

Index length & Mysql / MariaDB

Laravel uses utf8mb4 encoding by default, which supports storing emojis in the database. If you are creating an index on a MySQL version earlier than 5.7.7 or a MariaDB version earlier than 10.2.2, you need to manually configure the default string length for database migration.
That is, call the Schema::defaultStringLength method in AppServiceProvider to configure it:

use Illuminate\Support\Facades\Schema;
/**
 * 引导任何应用程序服务
 *
 * @return void
 */ 
public function boot() {  
   Schema::defaultStringLength(191);
  }

Of course, you can also choose to enable the database's innodb_large_prefix options. As for how to enable it correctly, please consult the database documentation yourself.

Rename index

To rename an index, you need to call the renameIndex method . This method accepts the current index name as its first argument and the desired name as its second argument:
You need to pass the current index name as its first argument and the new index name as its second Parameters:

$table->renameIndex('from', 'to')

Delete index

To delete an index, you must specify the name of the index. By default, Laravel will automatically simply concatenate the database name, index field name, and index type together as the name. For example:

Add primary key
Add composite key
Add unique Index
Add a normal index
Add spatial index (SQLite is not supported)
Delete the spatial index from the

If the field array is passed to the dropIndex method, the index name generated based on the table name, field and key type will be deleted.

Schema::table('geo', function (Blueprint $table) {
    $table->dropIndex(['state']); 
    // 删除 'geo_state_index' 索引
   });

Foreign Key Constraints

Laravel also supports the creation of constraints for enforcing referential integrity in the database layer. Foreign key constraints. For example, let's define a user_id field on the posts table 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 attributes:

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

You can use the dropForeign method to drop a foreign key . Foreign key constraints are named in the same way as indexes. That is, connect the data table name and the constrained field, and add the _foreign suffix:

$table->dropForeign('posts_user_id_foreign');

Or, you can also pass a field array, and when deleting, the fields will be deleted according to the agreement Convert to the corresponding foreign key name:

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

You can use the following method in the migration file to turn on or off foreign key constraints:

Schema::enableForeignKeyConstraints();
Schema::disableForeignKeyConstraints();

{Note} SQLite disables foreign keys by default constraint. When using SQLite, make sure to enable [Enable foreign key support] in the database configuration (/docs/laravel/5.8/database#configuration) before trying to create them in a migration.

This article was first published on the LearnKu.com website.
CommandDescription
$table- >dropPrimary('users_id_primary');Delete the primary key from the users table
$table-> dropUnique('users_email_unique');Delete the unique index from the users table
$table->dropIndex ('geo_state_index');Delete base index from geo table
##$table->dropSpatialIndex( 'geo_location_spatialindex');geo table (SQLite is not supported)