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.
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:
Command | Description |
---|
$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:
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 CHAR with length | |
$table->date('created_at');Equivalent to DATE | | ##$table->dateTime('created_at ');
Equivalent to DATETIME
| ##$table->dateTimeTz('created_at'); |
Equivalent to DATETIME with time zone
| ##$table->decimal('amount', 8, 2); |
Equivalent to Precision and base DECIMAL ##$table->double('amount', 8, 2); | | is equivalent to with precision and Base DOUBLE
##$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');
| Increasing ID (primary key), equivalent to "UNSIGNED INTEGER" |
##$table->integer('votes'); Equivalent to INTEGER | |
##$table->ipAddress('visitor');Equivalent to IP address | |
$table->json('options'); is 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'); |
is equivalent to MEDIUMTEXT$table->morphs('taggable'); | is equivalent to adding the incrementing taggable_id and the 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 the nullable version of | morphs() Field
| ##$table->nullableTimestamps();Equivalent to the nullable version of timestamps() | Field
| ##$table->point('position'); Equivalent to POINT
| ##$table->polygon('positions'); | Equivalent to POLYGON
| $table->rememberToken(); | Equivalent to the remember_token field of the nullable version of VARCHAR (100) | ##$table->smallIncrements('id'); | Increment ID (primary key), equivalent to "UNSIGNED SMALL INTEGER"
| $table->smallInteger('votes'); | is equivalent to SMALLINT | $table->softDeletes(); | Equivalent to adding a nullable deleted_at 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 | ##$table->timeTz('sunrise'); Equivalent to TIME with time zone | | #$table->timestamp('added_on');Equivalent to TIMESTAMP | | ##$table->timestampTz('added_on'); is equivalent to TIMESTAMP # with time zone | ##$table->timestamps(); | Equivalent to the nullable created_at and updated_at | TIMESTAMP
##$table->timestampsTz(); | Equivalent to created_at and updated_at which are nullable and have time zone TIMESTAMP | ##$table->tinyIncrements('id');
| Equivalent to automatically incrementing UNSIGNED TINYINT $table->tinyInteger('votes'); | | is equivalent to TINYINT $table->unsignedBigInteger('votes'); | | Equivalent to Unsigned BIGINT ##$table->unsignedDecimal('amount' , 8, 2); | is equivalent to UNSIGNED DECIMAL | with precision and base$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 | |
Field modificationIn 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: Modifier | Description |
---|
##->after('column')
| Place this field "after" other fields (MySQL) | ->autoIncrement()
| Set a field of type INTEGER as an auto-incrementing primary key | ->charset('utf8')
| Specify a character set (MySQL) | ->collation('utf8_unicode_ci')
| Specify the collation of the column (MySQL/SQL Server) | ->comment('my comment')
| Add comments to fields (MySQL) | ->default($value)
| Specify the "default" value for the field | ->first()
| Place this field at the "first position" of the data table (MySQL) | ->nullable($value = true)
| This field allows NULL values to be written (by default) | ->storedAs($expression)
| Create A storage-generated field (MySQL) | ##->unsigned() Set the INTEGER type field to UNSIGNED (MySQL) | | ->useCurrent() Set a field of type TIMESTAMP to use CURRENT_TIMESTAMP as the default value | | ->virtualAs($expression) Create a virtual generated field (MySQL) | |
Modify fieldsPrerequisitesBefore 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 FieldsFields 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 aliasesCommand | Description |
---|
$table->dropRememberToken(); | Delete the remember_token field. | $table->dropSoftDeletes(); | Delete the deleted_at field. | $table->dropSoftDeletesTz(); | dropSoftDeletes() Alias for the method. | ##$table->dropTimestamps();
| Delete created_at and updated_at fields . | $table->dropTimestampsTz();
| dropTimestamps() Alias for the method. |
Index ##Create indexThe 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 typesEach index method accepts an optional second parameter to specify the index name. If omitted, names will be generated based on table and column names. 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 a normal index | | $table->spatialIndex('location');Add spatial index (SQLite is not supported) | | Index length & Mysql / MariaDBLaravel 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 indexTo 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 indexTo 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: Command | Description |
---|
$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');
| Delete the spatial index from the geo table (SQLite is not supported) | 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 ConstraintsLaravel 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.
|