迁移如同数据库版本控制,允许一个团队更容易地修改和共享应用程序数据库模式。迁移一般与 Laravel 模式构造器搭配,更容易地构造你的应用程序数据库模式。流畅的 API 贯穿整个 Laravel 支持的数据库系统。
Laravel Schema
facade 提供了与数据库无关的创建和操纵表。它共享相同的表达式,
创建一个迁移,使用make:migration
Artisan command:
php artisan make:migration create_users_table
新创建的迁移被放置在 database/migrations
目录中,每个迁移文件包含了 Laravel 决定迁移顺序的时间戳。
--table
和 --create
选项分别用于指出表名和是否迁移生成一张新表。这些选项简单地预填充指明表产生迁移的 stub 文件:
php artisan make:migration add_votes_to_users_table --table=users
php artisan make:migration create_users_table --create=users
一个迁移类包含 up
和 down
两个方法。up
方法用于添加新的表、列、或者数据库索引,down
方法简单地逆转 up
方法执行的操作。
在这两个方法的内部,使用Laravel 模式构造器来表示创建和修改的表。查看这份文档,学习 模式
构造器上所有有用的方法。例如,让我们看创建一张 flights
表简单迁移:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateFlightsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('airline');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('flights');
}
}
执行应用程序中所有杰出的迁移,使用 migrate
Artisan 命令。如果你使用的是 [Homestead 虚拟机],你应该(/docs/{{version}}/homestead),你就可以在虚拟机内执行执行这个命令:
php artisan migrate
如果当你执行迁移时接收到一个 "class not found" 错误,尝试执行 composer dump-autoload
命令,并重新使用该 migrate 命令.
有些迁移具有毁灭性操作,这意外地它们可能会导致丢失数据。为了保护执行对生产数据库不利的命令,系统会提示你输入确认。使用 --force
标记强制执行没带提示的命令:
php artisan migrate --force
回滚最后的迁移"操作",使用 rollback
命令,注意:回滚将执行迁移最后的 "一批",其中可能包含多个迁移文件:
php artisan migrate:rollback
migrate:reset
命令将回滚所有的应用程序迁移:
php artisan migrate:reset
migrate:refresh
命令将首先回滚所有的数据库迁移,然后执行 migrate
命令,这个命令有效地重建整个数据库:
php artisan migrate:refresh
php artisan migrate:refresh --seed
创建一张新的数据库表,在Schema
facade 上使用 create
方法。create
方法 接收两个参数。第一个参数是表名,第二个参数是闭包,该闭包接收一个用于定义新表的 Blueprint
对象:
Schema::create('users', function ($table) {
$table->increments('id');
});
当然了,当创建表时,你可以使用任何的模式构造器[列方法]定义表的列。(/docs/{{version}}/migrations#creating-columns)
你可以使用 hasTable
和 hasColumn
方法来检查表或列是否存在:
if (Schema::hasTable('users')) {
//
}
if (Schema::hasColumn('users', 'email')) {
//
}
如果你想要在非默认的数据库连接上执行 schema 操作,使用 connection
方法:
Schema::connection('foo')->create('users', function ($table) {
$table->increments('id');
});
为一张表设置存储引擎,需要在模式构造器上设置 engine
属性:
Schema::create('users', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
});
使用 rename
方法重新命名一张已存在的数据库表:
Schema::rename($from, $to);
要删除一张存在的表,你可以使用 drop
或者 dropIfExists
方法:
Schema::drop('users');
Schema::dropIfExists('users');
要更新一张存在的表,我们将在 Schema
facade 上使用 table
方法。和 create
方法一样,table
方法接收两个参数:表名和一个闭包,该闭包接收一个 Blueprint
实例把列添加到表中:
Schema::table('users', function ($table) {
$table->string('email');
});
当然,当你创建表时,模式构造器包含了多种多样的列类型可供使用:
Command | Description |
---|---|
$table->bigIncrements('id'); |
Incrementing ID using a "big integer" equivalent. |
$table->bigInteger('votes'); |
BIGINT equivalent for the database. |
$table->binary('data'); |
BLOB equivalent for the database. |
$table->boolean('confirmed'); |
BOOLEAN equivalent for the database. |
$table->char('name', 4); |
CHAR equivalent with a length. |
$table->date('created_at'); |
DATE equivalent for the database. |
$table->dateTime('created_at'); |
DATETIME equivalent for the database. |
$table->decimal('amount', 5, 2); |
DECIMAL equivalent with a precision and scale. |
$table->double('column', 15, 8); |
DOUBLE equivalent with precision, 15 digits in total and 8 after the decimal point. |
$table->enum('choices', ['foo', 'bar']); |
ENUM equivalent for the database. |
$table->float('amount'); |
FLOAT equivalent for the database. |
$table->increments('id'); |
Incrementing ID for the database (primary key). |
$table->integer('votes'); |
INTEGER equivalent for the database. |
$table->json('options'); |
JSON equivalent for the database. |
$table->jsonb('options'); |
JSONB equivalent for the database. |
$table->longText('description'); |
LONGTEXT equivalent for the database. |
$table->mediumInteger('numbers'); |
MEDIUMINT equivalent for the database. |
$table->mediumText('description'); |
MEDIUMTEXT equivalent for the database. |
$table->morphs('taggable'); |
Adds INTEGER taggable_id and STRING taggable_type . |
$table->nullableTimestamps(); |
Same as timestamps() , except allows NULLs. |
$table->rememberToken(); |
Adds remember_token as VARCHAR(100) NULL. |
$table->smallInteger('votes'); |
SMALLINT equivalent for the database. |
$table->softDeletes(); |
Adds deleted_at column for soft deletes. |
$table->string('email'); |
VARCHAR equivalent column. |
$table->string('name', 100); |
VARCHAR equivalent with a length. |
$table->text('description'); |
TEXT equivalent for the database. |
$table->time('sunrise'); |
TIME equivalent for the database. |
$table->tinyInteger('numbers'); |
TINYINT equivalent for the database. |
$table->timestamp('added_on'); |
TIMESTAMP equivalent for the database. |
$table->timestamps(); |
Adds created_at and updated_at columns. |
除了上面列举的列类型之外,这还有几个列 "修改器"可供添加使用。例如,使列 "nullable",你可以使用 nullable
方法:
Schema::table('users', function ($table) {
$table->string('email')->nullable();
});
下面是所有有用的列修改器列表。该列表不包含 index modifiers:
Modifier | Description |
---|---|
->first() |
Place the column "first" in the table (MySQL Only) |
->after('column') |
Place the column "after" another column (MySQL Only) |
->nullable() |
Allow NULL values to be inserted into the column |
->default($value) |
Specify a "default" value for the column |
->unsigned() |
Set integer columns to UNSIGNED |
在修改列之前,一定要在 composer.json
文件中添加 doctrine/dbal
依赖。该 Doctrine DBAL 库通常确定列的当前状态和创建 SQL 查询所需要指明调整的列。
change
方法允许修改已有列的类型或者列的属性,例如,你期望增加字符串列的尺寸。参考活动中的 change
方法,增长 name
列的尺寸从25 添加到 50:
Schema::table('users', function ($table) {
$table->string('name', 50)->change();
});
我们也会修改一列为nullable:
Schema::table('users', function ($table) {
$table->string('name', 50)->nullable()->change();
});
要重命名一列。你可能要在模式构造器上使用 renameColumn
方法。在修改列之前,一定要在 composer.json
添加 doctrine/dbal
库依赖:
Schema::table('users', function ($table) {
$table->renameColumn('from', 'to');
});
**注意:**当前不支持在一张表中重命名带
enum
的列。
要删除一列,需要在模式构造器上使用 dropColumn
方法:
Schema::table('users', function ($table) {
$table->dropColumn('votes');
});
你可以通过传递列名数组给 dropColumn
方法删除一张表的多列:
Schema::table('users', function ($table) {
$table->dropColumn(['votes', 'avatar', 'location']);
});
Note: 在 SQLite 数据库中删除列,一定要在
composer.json
文件中添加doctrine/dbal
依赖,并在安装该库的终端执行composer update
命名。
模式构造器支持几个索引类型,让我们看看指明一列的值为唯一的例子。创建索引,我们只需要在列定义之上链接上unique
方法:
$table->string('email')->unique();
非此即彼,你可以在定义列之后创建索引,例如:
$table->unique('email');
你甚至可以传递列数组到索引方法来创建组合索引:
$table->index(['account_id', 'created_at']);
####有用的所有类型
Command | Description |
---|---|
$table->primary('id'); |
Add a primary key. |
$table->primary(['first', 'last']); |
Add composite keys. |
$table->unique('email'); |
Add a unique index. |
$table->index('state'); |
Add a basic index. |
删除索引,必须首先指明索引的名字,默认下,Laravel自动分配一个合理的名字给索引,简单连结的表名,索引上中的列名,和列的类型,这里有一些实例:
Command | Description |
---|---|
$table->dropPrimary('users_id_primary'); |
Drop a primary key from the "users" table. |
$table->dropUnique('users_email_unique'); |
Drop a unique index from the "users" table. |
$table->dropIndex('geo_state_index'); |
Drop a basic index from the "geo" table. |
Laravel也提供支持创建外键约束,这是用于促使数据库级别的引用完整性。例如,我们参照 users
表上的 id
列在 posts
上定义一个 user_id
方法:
Schema::table('posts', function ($table) {
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
});
你也可以指定期望的 "on delete" 和"on update" 属性约束动作:
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
要删除一个外键,你可以使用 dropForeign
方法,外键约束使用相同的命名规定作为索引,所以,我们将链接表名和列约束,然后后缀名为 "_foreign":
$table->dropForeign('posts_user_id_foreign');