資料庫遷移
#刪除索引
產生遷移
使用 Artisan 指令 make:migration
來建立遷移。
php artisan make:migration create_users_table
新的遷移位於 database/migrations
目錄下。每個遷移檔名都包含時間戳,以便讓 Laravel 確認遷移的順序。
--table
和 --create
選項可用來指定資料表的名稱,或是該遷移執行時是否會建立的新資料表。這些選項需要在預先產生遷移檔案時填入指定的資料表:
php artisan make:migration create_users_table --create=users php artisan make:migration add_votes_to_users_table --table=users
如果你想要指定產生遷移指定一個自訂輸出路徑,則可以在執行make:migration
命令時新增 --path
選項,給定的路徑必須是相對於應用程式的基本路徑。
遷移結構
遷移類別通常會包含2 個方法: up
和down
。 up
方法用來新增新的資料表, 欄位或索引到資料庫,而 down
# 方法就是up
方法的反操作,而 up
裡的操作相反。
在這2 個方法中都要用到Laravel 的Schema
建構器來建立和修改表,
若要了解Schema
生成器中的所有可用方法,可以查看它的文件。例如,建立flights
表的簡單範例:
<?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'); } }
#運行遷移
執行Artisan指令migrate
來執行所有未完成的遷移:
php artisan migrate
#{注意} 如果你正在使用Homestead 虛擬機,你應該在你的虛擬機裡執行這個指令。
在生產環境強制執行遷移
某些遷移作業是具有破壞性的, 這表示可能會導致資料遺失。為了防止有人在生產環境中運行這些命令, 系統會在這些命令被運行之前與你進行確認。如果要強制忽略系統的提示執行指令,則可以使用 --force
標記:
php artisan migrate --force##回滾遷移若要回滾最後一次遷移, 可以使用
rollback 指令。此指令會回滾最後一次「遷移」 的操作,其中可能包含多個遷移檔:
php artisan migrate:rollback你可以在
rollback 指令後面加上
step 參數,來限制回滾遷移的個數。例如,以下指令將回滾最近五次遷移:
php artisan migrate:rollback --step=5
migrate:reset 指令可以回滾應用程式中的所有遷移:
php artisan migrate:reset
使用單一指令來執行回滾或遷移
migrate:refresh
指令不僅會回滾資料庫的所有遷移還會接著執行 migrate
指令。這個指令可以有效率地重建整個資料庫:
php artisan migrate:refresh // 刷新数据库结构并执行数据填充 php artisan migrate:refresh --seed
使用 refresh
指令並提供 step
參數來回滾來並再執行最後指定的遷移數。例如, 下列指令會回滾並重新執行最後五次遷移:
php artisan migrate:refresh --step=5
刪除所有表& 遷移
The migrate:fresh
指令會從資料庫中刪除所有表,然後執行migrate
指令:
php artisan migrate:fresh php artisan migrate:fresh --seed##資料表建立資料表可以使用
Schema facade 的
create 方法來創建新的資料庫表。
create 方法接受兩個參數:第一個參數為資料表的名稱,第二個參數是
Closure ,此閉包會接收一個用於定義新資料表的
Blueprint 物件:
Schema::create('users', function (Blueprint $table) { $table->increments('id'); });當然,在建立資料表的時候,可以使用任何資料庫結構產生器的
欄位方法 來定義資料表的欄位。
檢查資料表/ 欄位是否存在可以使用hasTable 和
hasColumn 方法來檢查資料表或欄位是否存在:
if (Schema::hasTable('users')) { // } if (Schema::hasColumn('users', 'email')) { // }
資料庫連線& 表格選項
如果要對非預設連線的資料庫連線執行結構操作,可以使用connection
方法:
Schema::connection('foo')->create('users', function (Blueprint $table) { $table->increments('id'); });
你可以在資料庫結構生成器上使用以下指令來定義表格的選項:
指令 | 描述 |
---|---|
| |
| ##$table->engine = 'InnoDB';|
| $table->charset = 'utf8';|
| $table->collation = 'utf8_unicode_ci';
重新命名/ 刪除資料表
若要重新命名資料表,可以使用rename
方法:
Schema::rename($from, $to);
刪除一個已存在的資料表, 可使用 drop
或dropIfExists
方法:
Schema::drop('users');Schema::dropIfExists('users');
# 重新命名帶外鍵的資料表
在重新命名表之前,你應該驗證表上的任何外鍵約束在遷移檔案中都有明確的名稱,而不是讓Laravel 依照約定來設定名稱。否則,外鍵的約束名稱將引用舊表名。
#創建欄位
使用Schema
facade 的table
方法可以更新現有的資料表。如同create
方法一樣,table
方法會接受兩個參數:一個是資料表的名稱,另一個則是接收可以用來新增欄位的Blueprint
實例的閉包:
Schema::table('users', function (Blueprint $table) { $table->string('email'); });
可用的欄位類型
資料庫結構產生器包含在建構表時可以指定的各種欄位類型:
指令 | 描述 |
---|---|
#$table->bigIncrements('id '); | 遞增ID(主鍵),相當於「UNSIGNED BIG INTEGER」 |
$table->bigInteger('votes' ); | 相當於BIGINT |
#$table->binary('data'); | 相當於BLOB |
$table->boolean('confirmed'); | 相當於BOOLEAN |
$table->char('name', 100); | #相當於有長度的CHAR |
##$table->date('created_at');
| 相當於DATE|
$table->dateTime('created_at ');
| 相當於DATETIME|
#$table->dateTimeTz('created_at');
| #相當於帶時區DATETIME|
$table->decimal('amount', 8, 2); ##相當於帶有精確度與基底數DECIMAL | |
##相當於帶有精確度與基數DOUBLE | |
相當於ENUM | |
相當於帶有精確度與基數FLOAT | |
$table->geometry('positions'); | #相當於GEOMETRY |
##$table ->geometryCollection('positions');
| 相當於GEOMETRYCOLLECTION|
$table->increments('id');
| 遞增的ID (主鍵),相當於「UNSIGNED INTEGER」|
$table->integer('votes');
| 相當於INTEGER|
$table->ipAddress('visitor');
| 相當於IP 位址|
$table->json('options');
| 等於JSON|
$table->jsonb('options');
| 相當於JSONB|
$table->lineString( 'positions');
| 相當於LINESTRING|
#$table->longText('description');
| #相當於LONGTEXT|
$table->macAddress('device');
| 相當於MAC 位址|
$table->mediumIncrements('id');
| #遞增ID (主鍵) ,相當於「UNSIGNED MEDIUM INTEGER」|
$table->mediumInteger('votes');
| #相當於MEDIUMINT|
$ table->mediumText('description');
| 相當於MEDIUMTEXT|
$table->morphs('taggable'); | 等於加入遞增的taggable_id 與字串taggable_type |
$table->multiLineString('positions'); | 相當於MULTILINESTRING |
#$table->multiPoint('positions'); | #相當於MULTIPOINT |
$table-> multiPolygon('positions'); | 相當於MULTIPOLYGON |
$table->nullableMorphs('taggable'); | 相當於可空版本的morphs() 欄位 |
#$table->nullableTimestamps(); | #相當於可空版本的timestamps() 欄位 |
#$table->point('position'); | 相當於POINT |
$table->polygon('positions'); | 相當於POLYGON |
$table->rememberToken(); | 相當於可空版本的VARCHAR (100) 的remember_token 字段 |
$table->smallIncrements('id'); | 遞增ID (主鍵) ,相當於「UNSIGNED SMALL INTEGER」 |
$table->smallInteger('votes'); | 相當於SMALLINT |
$table->softDeletes(); | 相當於為軟體刪除新增一個可空的deleted_at 欄位 |
$table->softDeletesTz(); | #相當於為軟體刪除新增一個可空的帶時區的deleted_at 欄位 |
$table->string('name', 100); | 等於有長度的VARCHAR |
$table->text('description'); | #相當於TEXT |
$table-> ;time('sunrise'); | 相當於TIME |
#$table->timeTz('sunrise'); | 相當於帶有時區的TIME |
$table->timestamp('added_on'); | 相當於TIMESTAMP |
$table->timestampTz('added_on'); | 相當於時區的TIMESTAMP |
$table->timestamps(); | 等於可空的created_at 和updated_at TIMESTAMP |
$table->timestampsTz(); | #相當於可空且帶有時區的created_at 和updated_at TIMESTAMP |
$table->tinyIncrements('id'); | 相當於自動遞增UNSIGNED TINYINT |
$table->tinyInteger('votes'); | #相當於TINYINT |
$table->unsignedBigInteger('votes'); | 相當於Unsigned BIGINT |
$table->unsignedDecimal('amount' , 8, 2); | 相當於帶有精確度和基底數的UNSIGNED DECIMAL |
$table->unsignedInteger('votes'); | #相當於Unsigned INT |
$ table->unsignedMediumInteger('votes'); | 相當於Unsigned MEDIUMINT |
$table->unsignedSmallInteger('votes') ; | 相當於Unsigned SMALLINT |
#$table->unsignedTinyInteger('votes'); | #相當於Unsigned TINYINT |
$table->uuid('id'); | 相當於UUID |
|
欄位修飾
除了上述列出的欄位類型之外,還有幾個可以在新增欄位到資料庫表格時使用的 「修飾符」。例如,如果要把欄位設為 「可空 ", 你可以使用 nullable
方法:
Schema::table('users', function (Blueprint $table) { $table->string('email')->nullable(); });
以下是所有可用的欄位修飾符的清單。此清單不包括 索引修飾符:
Modifier | Description | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
->after('column') | 將此欄位放置在其它欄位"之後" (MySQL) | ||||||||||||||||||||||||||||||||||
->autoIncrement() | #將INTEGER 類型的欄位設定為自動遞增的主鍵 | ||||||||||||||||||||||||||||||||||
#->charset('utf8') | ##指定字元集(MySQL)|||||||||||||||||||||||||||||||||||
->collation('utf8_unicode_ci')
| 指定資料列的排序規則(MySQL/SQL Server)|||||||||||||||||||||||||||||||||||
->comment('my comment')
| #為欄位增加註解(MySQL)|||||||||||||||||||||||||||||||||||
->default($value)
| 為欄位指定"預設" 值|||||||||||||||||||||||||||||||||||
將此欄位放置在資料表的"首位" (MySQL) | |||||||||||||||||||||||||||||||||||
此欄位允許寫入NULL 值(預設) | |||||||||||||||||||||||||||||||||||
##創建一個儲存產生的欄位(MySQL) | |||||||||||||||||||||||||||||||||||
設定INTEGER 類型的欄位為UNSIGNED (MySQL) | |||||||||||||||||||||||||||||||||||
#將TIMESTAMP 類型的欄位設定為使用CURRENT_TIMESTAMP 作為預設值 | |||||||||||||||||||||||||||||||||||
建立一個虛擬產生的欄位(MySQL) |
Command | Description |
---|---|
| Description
|
$table->dropRememberToken(); | 刪除remember_token 欄位。 |
$table->dropSoftDeletes(); | 刪除 deleted_at 欄位。 |
$table->dropSoftDeletesTz(); | dropSoftDeletes() 方法的別名。
|
##刪除 created_at | and updated_at 字段。 |
索引
建立索引
結構產生器支援多種類型的索引。首先,先指定欄位值唯一,即簡單地在欄位定義之後鍊式呼叫 unique
方法來建立索引,例如:
$table->string('email')->unique();
或者,你也可以在定義完欄位之後建立索引。例如:
$table->unique('email');
你甚至可以將陣列傳遞給索引方法來建立一個複合(或合成)索引:
$table->index(['account_id', 'created_at']);
Laravel 會自動產生一個合理的索引名稱,但你也可以傳遞第二個參數來自訂索引名稱:
$table->unique('email', 'unique_email');
可用的索引類型
每個索引方法都接受一個可選的第二個參數來指定索引的名稱。如果省略,名稱將根據表格和列的名稱產生。
指令 | 描述 |
---|---|
#$table->primary ('id'); | 新增主鍵 |
#$table->primary(['id', 'parent_id']); | 新增複合鍵 |
$table->unique('email'); | 新增唯一索引 |
$table->index('state'); | ##新增普通索引|
$table->spatialIndex('location');
| #新增空間索引(不支援SQLite)
指令 | 描述 |
---|---|
$table- >dropPrimary('users_id_primary'); | 從users 表中刪除主鍵 |
$table-> dropUnique('users_email_unique'); | 從users 表中刪除唯一索引 |
$table->dropIndex ('geo_state_index'); | 從geo 表中刪除基本索引 |
$table->dropSpatialIndex( 'geo_location_spatialindex'); | 從geo 表中刪除空間索引(不支援SQLite) |
如果將欄位陣列傳給 dropIndex
方法,會刪除根據表名、欄位和鍵類型產生的索引名稱。
Schema::table('geo', function (Blueprint $table) { $table->dropIndex(['state']); // 删除 'geo_state_index' 索引 });
外鍵約束
Laravel 也支援建立用於在資料庫層中的強制參考完整性的外鍵約束。例如,讓我們在posts
表上定義一個引用users
表格的id
欄位的user_id
欄位:
Schema::table('posts', function (Blueprint $table) { $table->unsignedInteger('user_id'); $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');
或者,你也可以傳遞一個字段數組,在刪除的時候會按照約定字段轉換為對應的外鍵名稱:
$table->dropForeign(['user_id']);
你可以在遷移檔案中使用以下方法來開啟或關閉外鍵約束:
Schema::enableForeignKeyConstraints(); Schema::disableForeignKeyConstraints();
{註} SQLite 預設為停用外鍵約束。使用 SQLite 時,請確保在資料庫設定中啟用 [啟用外鍵支援](/docs/laravel/5.8 /database#configuration),然後再嘗試在遷移中建立它們。