資料庫:遷移
簡介
遷移就像是資料庫的版本控制,讓您的團隊可以定義和分享應用程式的資料庫結構定義。如果您曾經需要告訴隊友在從原始碼控制拉取您的變更後,手動將資料行新增到他們的本機資料庫結構中,那麼您就遇到了資料庫遷移要解決的問題。
Laravel Schema
facade 提供了資料庫不可知的支援,用於在所有 Laravel 支援的資料庫系統中建立和操作資料表。通常,遷移會使用此 facade 來建立和修改資料庫資料表和資料行。
產生遷移
您可以使用 make:migration
Artisan 命令 來產生資料庫遷移。新的遷移將放置在您的 database/migrations
目錄中。每個遷移檔案名稱都包含一個時間戳記,讓 Laravel 可以判斷遷移的順序
1php artisan make:migration create_flights_table
Laravel 將使用遷移的名稱來嘗試猜測資料表的名稱,以及遷移是否將建立新的資料表。如果 Laravel 能夠從遷移名稱判斷資料表名稱,Laravel 將使用指定的資料表預先填寫產生的遷移檔案。否則,您可以簡單地在遷移檔案中手動指定資料表。
如果您想要為產生的遷移指定自訂路徑,您可以在執行 make:migration
命令時使用 --path
選項。給定的路徑應相對於應用程式的基本路徑。
遷移 stub 可以使用stub 發佈來自訂。
壓縮遷移
當您建置應用程式時,您可能會隨著時間的推移累積越來越多的遷移。這可能會導致您的 database/migrations
目錄膨脹,其中可能包含數百個遷移。如果您願意,您可以將您的遷移「壓縮」成單一 SQL 檔案。若要開始,請執行 schema:dump
命令
1php artisan schema:dump2 3# Dump the current database schema and prune all existing migrations...4php artisan schema:dump --prune
當您執行此命令時,Laravel 會將「schema」檔案寫入您應用程式的 database/schema
目錄。schema 檔案的名稱將對應於資料庫連線。現在,當您嘗試遷移資料庫且沒有其他遷移已執行時,Laravel 將首先執行您正在使用的資料庫連線的 schema 檔案中的 SQL 陳述式。在執行 schema 檔案的 SQL 陳述式後,Laravel 將執行任何不屬於 schema 轉儲的剩餘遷移。
如果您的應用程式的測試使用與您在本地開發期間通常使用的資料庫連線不同的資料庫連線,您應確保您已使用該資料庫連線轉儲 schema 檔案,以便您的測試能夠建置您的資料庫。您可能希望在轉儲您在本地開發期間通常使用的資料庫連線後執行此操作
1php artisan schema:dump2php artisan schema:dump --database=testing --prune
您應將您的資料庫 schema 檔案提交到原始碼控制,以便您的團隊中的其他新開發人員可以快速建立您應用程式的初始資料庫結構。
遷移壓縮僅適用於 MariaDB、MySQL、PostgreSQL 和 SQLite 資料庫,並使用資料庫的命令列用戶端。
遷移結構
遷移類別包含兩個方法:up
和 down
。up
方法用於將新的資料表、資料行或索引新增到您的資料庫,而 down
方法應反轉 up
方法執行的操作。
在這兩個方法中,您都可以使用 Laravel schema 建構器來表達式地建立和修改資料表。若要了解 Schema
建構器上所有可用的方法,請查看其文件。例如,以下遷移會建立 flights
資料表
1<?php 2 3use Illuminate\Database\Migrations\Migration; 4use Illuminate\Database\Schema\Blueprint; 5use Illuminate\Support\Facades\Schema; 6 7return new class extends Migration 8{ 9 /**10 * Run the migrations.11 */12 public function up(): void13 {14 Schema::create('flights', function (Blueprint $table) {15 $table->id();16 $table->string('name');17 $table->string('airline');18 $table->timestamps();19 });20 }21 22 /**23 * Reverse the migrations.24 */25 public function down(): void26 {27 Schema::drop('flights');28 }29};
設定遷移連線
如果您的遷移將與應用程式預設資料庫連線以外的資料庫連線互動,您應設定遷移的 $connection
屬性
1/** 2 * The database connection that should be used by the migration. 3 * 4 * @var string 5 */ 6protected $connection = 'pgsql'; 7 8/** 9 * Run the migrations.10 */11public function up(): void12{13 // ...14}
執行遷移
若要執行所有未完成的遷移,請執行 migrate
Artisan 命令
1php artisan migrate
如果您想查看到目前為止已執行的遷移,您可以使用 migrate:status
Artisan 命令
1php artisan migrate:status
如果您想查看遷移將執行的 SQL 陳述式,而實際上不執行它們,您可以為 migrate
命令提供 --pretend
旗標
1php artisan migrate --pretend
隔離遷移執行
如果您要跨多個伺服器部署應用程式,並將遷移作為部署過程的一部分執行,您可能不希望兩台伺服器同時嘗試遷移資料庫。為了避免這種情況,您可以在調用 migrate
命令時使用 isolated
選項。
當提供 isolated
選項時,Laravel 將在使用應用程式的快取驅動程式取得原子鎖定後,再嘗試執行遷移。當持有該鎖定時,所有其他嘗試執行 migrate
命令的操作都將不會執行;但是,該命令仍將以成功結束狀態碼退出
1php artisan migrate --isolated
若要使用此功能,您的應用程式必須使用 memcached
、redis
、dynamodb
、database
、file
或 array
快取驅動程式作為應用程式的預設快取驅動程式。此外,所有伺服器都必須與相同的中央快取伺服器通訊。
強制遷移在生產環境中執行
某些遷移操作具有破壞性,這表示它們可能會導致您遺失資料。為了保護您免於對生產資料庫執行這些命令,系統會在執行命令之前提示您確認。若要強制命令在沒有提示的情況下執行,請使用 --force
旗標
1php artisan migrate --force
回滾遷移
若要回滾最新的遷移操作,您可以使用 rollback
Artisan 命令。此命令會回滾最後「批次」的遷移,其中可能包含多個遷移檔案
1php artisan migrate:rollback
您可以透過為 rollback
命令提供 step
選項來回滾有限數量的遷移。例如,以下命令將回滾最後五個遷移
1php artisan migrate:rollback --step=5
您可以透過為 rollback
命令提供 batch
選項來回滾特定「批次」的遷移,其中 batch
選項對應於應用程式 migrations
資料庫資料表中的批次值。例如,以下命令將回滾批次三中的所有遷移
1php artisan migrate:rollback --batch=3
如果您想查看遷移將執行的 SQL 陳述式,而實際上不執行它們,您可以為 migrate:rollback
命令提供 --pretend
旗標
1php artisan migrate:rollback --pretend
migrate:reset
命令將回滾您應用程式的所有遷移
1php artisan migrate:reset
使用單一命令回滾和遷移
migrate:refresh
命令將回滾您的所有遷移,然後執行 migrate
命令。此命令有效地重新建立您的整個資料庫
1php artisan migrate:refresh2 3# Refresh the database and run all database seeds...4php artisan migrate:refresh --seed
您可以透過為 refresh
命令提供 step
選項來回滾和重新遷移有限數量的遷移。例如,以下命令將回滾並重新遷移最後五個遷移
1php artisan migrate:refresh --step=5
刪除所有資料表並遷移
migrate:fresh
命令將從資料庫中刪除所有資料表,然後執行 migrate
命令
1php artisan migrate:fresh2 3php artisan migrate:fresh --seed
預設情況下,migrate:fresh
命令僅從預設資料庫連線中刪除資料表。但是,您可以使用 --database
選項來指定應遷移的資料庫連線。資料庫連線名稱應對應於應用程式 database
設定檔中定義的連線
1php artisan migrate:fresh --database=admin
無論資料表的前綴為何,migrate:fresh
命令都會刪除所有資料庫資料表。在與其他應用程式共用的資料庫上開發時,應謹慎使用此命令。
資料表
建立資料表
若要建立新的資料庫資料表,請使用 Schema
facade 上的 create
方法。create
方法接受兩個引數:第一個是資料表的名稱,而第二個是接收 Blueprint
物件的 closure,可用於定義新的資料表
1use Illuminate\Database\Schema\Blueprint;2use Illuminate\Support\Facades\Schema;3 4Schema::create('users', function (Blueprint $table) {5 $table->id();6 $table->string('name');7 $table->string('email');8 $table->timestamps();9});
建立資料表時,您可以使用 schema 建構器的任何資料行方法來定義資料表的資料行。
判斷資料表 / 資料行是否存在
您可以使用 hasTable
、hasColumn
和 hasIndex
方法來判斷資料表、資料行或索引是否存在
1if (Schema::hasTable('users')) { 2 // The "users" table exists... 3} 4 5if (Schema::hasColumn('users', 'email')) { 6 // The "users" table exists and has an "email" column... 7} 8 9if (Schema::hasIndex('users', ['email'], 'unique')) {10 // The "users" table exists and has a unique index on the "email" column...11}
資料庫連線和資料表選項
如果您想在不是應用程式預設連線的資料庫連線上執行 schema 操作,請使用 connection
方法
1Schema::connection('sqlite')->create('users', function (Blueprint $table) {2 $table->id();3});
此外,還可以使用一些其他屬性和方法來定義資料表建立的其他方面。engine
屬性可用於在使用 MariaDB 或 MySQL 時指定資料表的儲存引擎
1Schema::create('users', function (Blueprint $table) {2 $table->engine('InnoDB');3 4 // ...5});
charset
和 collation
屬性可用於在使用 MariaDB 或 MySQL 時指定已建立資料表的字元集和定序
1Schema::create('users', function (Blueprint $table) {2 $table->charset('utf8mb4');3 $table->collation('utf8mb4_unicode_ci');4 5 // ...6});
temporary
方法可用於指示資料表應為「臨時」。臨時資料表僅對目前連線的資料庫 session 可見,並在連線關閉時自動刪除
1Schema::create('calculations', function (Blueprint $table) {2 $table->temporary();3 4 // ...5});
如果您想將「註解」新增到資料庫資料表,您可以調用資料表實例上的 comment
方法。目前 MariaDB、MySQL 和 PostgreSQL 僅支援資料表註解
1Schema::create('calculations', function (Blueprint $table) {2 $table->comment('Business calculations');3 4 // ...5});
更新資料表
Schema
facade 上的 table
方法可用於更新現有的資料表。與 create
方法類似,table
方法接受兩個引數:資料表的名稱和接收 Blueprint
實例的 closure,您可以使用該實例將資料行或索引新增到資料表
1use Illuminate\Database\Schema\Blueprint;2use Illuminate\Support\Facades\Schema;3 4Schema::table('users', function (Blueprint $table) {5 $table->integer('votes');6});
重新命名 / 刪除資料表
若要重新命名現有的資料庫資料表,請使用 rename
方法
1use Illuminate\Support\Facades\Schema;2 3Schema::rename($from, $to);
若要刪除現有的資料表,您可以使用 drop
或 dropIfExists
方法
1Schema::drop('users');2 3Schema::dropIfExists('users');
重新命名具有外鍵的資料表
在重新命名資料表之前,您應驗證資料表上的任何外鍵約束在您的遷移檔案中是否具有明確的名稱,而不是讓 Laravel 指派基於慣例的名稱。否則,外鍵約束名稱將會參照舊的資料表名稱。
資料行
建立資料行
Schema
facade 上的 table
方法可用於更新現有的資料表。與 create
方法類似,table
方法接受兩個引數:資料表的名稱和接收 Illuminate\Database\Schema\Blueprint
實例的 closure,您可以使用該實例將資料行新增到資料表
1use Illuminate\Database\Schema\Blueprint;2use Illuminate\Support\Facades\Schema;3 4Schema::table('users', function (Blueprint $table) {5 $table->integer('votes');6});
可用的資料行類型
schema 建構器 blueprint 提供了各種方法,這些方法對應於您可以新增到資料庫資料表的不同資料行類型。下表列出了每個可用的方法
布林值類型
字串 & 文字類型
數值類型
bigIncrements bigInteger decimal double float id increments integer mediumIncrements mediumInteger smallIncrements smallInteger tinyIncrements tinyInteger unsignedBigInteger unsignedInteger unsignedMediumInteger unsignedSmallInteger unsignedTinyInteger
日期 & 時間類型
dateTime dateTimeTz date time timeTz timestamp timestamps timestampsTz softDeletes softDeletesTz year
二進制類型
物件 & Json 類型
UUID & ULID 類型
空間類型
關聯類型
特殊類型
bigIncrements()
bigIncrements
方法會建立自動遞增的 UNSIGNED BIGINT
(主鍵)等效資料行
1$table->bigIncrements('id');
bigInteger()
bigInteger
方法會建立 BIGINT
等效資料行
1$table->bigInteger('votes');
binary()
binary
方法會建立 BLOB
等效資料行
1$table->binary('photo');
當使用 MySQL、MariaDB 或 SQL Server 時,您可以傳遞 length
和 fixed
引數來建立 VARBINARY
或 BINARY
等效資料行
1$table->binary('data', length: 16); // VARBINARY(16)2 3$table->binary('data', length: 16, fixed: true); // BINARY(16)
boolean()
boolean
方法會建立 BOOLEAN
等效資料行
1$table->boolean('confirmed');
char()
char
方法會建立具有給定長度的 CHAR
等效資料行
1$table->char('name', length: 100);
dateTimeTz()
dateTimeTz
方法會建立 DATETIME
(帶時區)等效資料行,並具有可選的小數秒精確度
1$table->dateTimeTz('created_at', precision: 0);
dateTime()
dateTime
方法會建立 DATETIME
等效資料行,並具有可選的小數秒精確度
1$table->dateTime('created_at', precision: 0);
date()
date
方法會建立 DATE
等效資料行
1$table->date('created_at');
decimal()
decimal
方法會建立具有給定精確度(總位數)和小數位數(小數位數)的 DECIMAL
等效資料行
1$table->decimal('amount', total: 8, places: 2);
double()
double
方法會建立 DOUBLE
等效資料行
1$table->double('amount');
enum()
enum
方法會建立具有給定有效值的 ENUM
等效資料行
1$table->enum('difficulty', ['easy', 'hard']);
float()
float
方法會建立具有給定精確度的 FLOAT
等效資料行
1$table->float('amount', precision: 53);
foreignId()
foreignId
方法會建立 UNSIGNED BIGINT
等效資料行
1$table->foreignId('user_id');
foreignIdFor()
foreignIdFor
方法會為給定的模型類別新增 {column}_id
等效資料行。資料行類型將為 UNSIGNED BIGINT
、CHAR(36)
或 CHAR(26)
,具體取決於模型鍵類型
1$table->foreignIdFor(User::class);
foreignUlid()
foreignUlid
方法會建立 ULID
等效資料行
1$table->foreignUlid('user_id');
foreignUuid()
foreignUuid
方法會建立 UUID
等效資料行
1$table->foreignUuid('user_id');
geography()
geography
方法會建立具有給定空間類型和 SRID(空間參考系統識別碼)的 GEOGRAPHY
等效資料行
1$table->geography('coordinates', subtype: 'point', srid: 4326);
對空間類型的支援取決於您的資料庫驅動程式。請參閱您的資料庫文件。如果您的應用程式正在使用 PostgreSQL 資料庫,您必須先安裝 PostGIS 擴充功能,才能使用 geography
方法。
geometry()
geometry
方法會建立具有給定空間類型和 SRID(空間參考系統識別碼)的 GEOMETRY
等效資料行
1$table->geometry('positions', subtype: 'point', srid: 0);
對空間類型的支援取決於您的資料庫驅動程式。請參閱您的資料庫文件。如果您的應用程式正在使用 PostgreSQL 資料庫,您必須先安裝 PostGIS 擴充功能,才能使用 geometry
方法。
id()
id
方法是 bigIncrements
方法的別名。預設情況下,此方法將建立 id
資料行;但是,如果您想為資料行指派不同的名稱,可以傳遞資料行名稱
1$table->id();
increments()
increments
方法會建立自動遞增的 UNSIGNED INTEGER
等效資料行作為主鍵
1$table->increments('id');
integer()
integer
方法會建立 INTEGER
等效資料行
1$table->integer('votes');
ipAddress()
ipAddress
方法會建立 VARCHAR
等效資料行
1$table->ipAddress('visitor');
當使用 PostgreSQL 時,將會建立 INET
資料行。
json()
json
方法會建立 JSON
等效資料行
1$table->json('options');
當使用 SQLite 時,將會建立 TEXT
資料行。
jsonb()
jsonb
方法會建立 JSONB
等效資料行
1$table->jsonb('options');
當使用 SQLite 時,將會建立 TEXT
資料行。
longText()
longText
方法會建立 LONGTEXT
等效資料行
1$table->longText('description');
當使用 MySQL 或 MariaDB 時,您可以將 binary
字元集應用於資料行,以建立 LONGBLOB
等效資料行
1$table->longText('data')->charset('binary'); // LONGBLOB
macAddress()
macAddress
方法會建立一個旨在保存 MAC 位址的資料行。某些資料庫系統(例如 PostgreSQL)具有用於此類型資料的專用資料行類型。其他資料庫系統將使用字串等效資料行
1$table->macAddress('device');
mediumIncrements()
mediumIncrements
方法會建立自動遞增的 UNSIGNED MEDIUMINT
等效資料行作為主鍵
1$table->mediumIncrements('id');
mediumInteger()
mediumInteger
方法會建立 MEDIUMINT
等效資料行
1$table->mediumInteger('votes');
mediumText()
mediumText
方法會建立 MEDIUMTEXT
等效資料行
1$table->mediumText('description');
當使用 MySQL 或 MariaDB 時,您可以將 binary
字元集應用於資料行,以建立 MEDIUMBLOB
等效資料行
1$table->mediumText('data')->charset('binary'); // MEDIUMBLOB
morphs()
morphs
方法是一種便利方法,可新增 {column}_id
等效資料行和 {column}_type
VARCHAR
等效資料行。{column}_id
的資料行類型將為 UNSIGNED BIGINT
、CHAR(36)
或 CHAR(26)
,具體取決於模型鍵類型。
此方法旨在用於定義多態Eloquent 關聯所需的資料行。在以下範例中,將建立 taggable_id
和 taggable_type
資料行
1$table->morphs('taggable');
nullableMorphs()
此方法與 morphs 方法類似;但是,建立的資料行將為「可為空值」
1$table->nullableMorphs('taggable');
nullableUlidMorphs()
此方法與 ulidMorphs 方法類似;但是,建立的資料行將為「可為空值」
1$table->nullableUlidMorphs('taggable');
nullableUuidMorphs()
此方法與 uuidMorphs 方法類似;但是,建立的資料行將為「可為空值」
1$table->nullableUuidMorphs('taggable');
rememberToken()
rememberToken
方法會建立可為空值的 VARCHAR(100)
等效資料行,該資料行旨在儲存目前的「記住我」身份驗證權杖
1$table->rememberToken();
set()
set
方法會建立具有給定有效值清單的 SET
等效資料行
1$table->set('flavors', ['strawberry', 'vanilla']);
smallIncrements()
smallIncrements
方法會建立自動遞增的 UNSIGNED SMALLINT
等效資料行作為主鍵
1$table->smallIncrements('id');
smallInteger()
smallInteger
方法會建立 SMALLINT
等效資料行
1$table->smallInteger('votes');
softDeletesTz()
softDeletesTz
方法會新增可為空值的 deleted_at
TIMESTAMP
(帶時區)等效資料行,並具有可選的小數秒精確度。此資料行旨在儲存 Eloquent「軟刪除」功能所需的 deleted_at
時間戳記
1$table->softDeletesTz('deleted_at', precision: 0);
softDeletes()
softDeletes
方法會新增可為空值的 deleted_at
TIMESTAMP
等效資料行,並具有可選的小數秒精確度。此資料行旨在儲存 Eloquent「軟刪除」功能所需的 deleted_at
時間戳記
1$table->softDeletes('deleted_at', precision: 0);
string()
string
方法會建立具有給定長度的 VARCHAR
等效資料行
1$table->string('name', length: 100);
text()
text
方法會建立 TEXT
等效資料行
1$table->text('description');
當使用 MySQL 或 MariaDB 時,您可以將 binary
字元集應用於資料行,以建立 BLOB
等效資料行
1$table->text('data')->charset('binary'); // BLOB
timeTz()
timeTz
方法會建立 TIME
(帶時區)等效資料行,並具有可選的小數秒精確度
1$table->timeTz('sunrise', precision: 0);
time()
time
方法會建立 TIME
等效資料行,並具有可選的小數秒精確度
1$table->time('sunrise', precision: 0);
timestampTz()
timestampTz
方法會建立 TIMESTAMP
(帶時區)等效資料行,並具有可選的小數秒精確度
1$table->timestampTz('added_at', precision: 0);
timestamp()
timestamp
方法會建立 TIMESTAMP
等效資料行,並具有可選的小數秒精確度
1$table->timestamp('added_at', precision: 0);
timestampsTz()
timestampsTz
方法會建立 created_at
和 updated_at
TIMESTAMP
(帶時區)等效資料行,並具有可選的小數秒精確度
1$table->timestampsTz(precision: 0);
timestamps()
timestamps
方法會建立 created_at
和 updated_at
TIMESTAMP
等效資料行,並具有可選的小數秒精確度
1$table->timestamps(precision: 0);
tinyIncrements()
tinyIncrements
方法會建立自動遞增的 UNSIGNED TINYINT
等效資料行作為主鍵
1$table->tinyIncrements('id');
tinyInteger()
tinyInteger
方法會建立 TINYINT
等效資料行
1$table->tinyInteger('votes');
tinyText()
tinyText
方法會建立一個 TINYTEXT
相等的欄位
1$table->tinyText('notes');
當使用 MySQL 或 MariaDB 時,您可以將 binary
字元集應用於欄位,以建立一個 TINYBLOB
相等的欄位
1$table->tinyText('data')->charset('binary'); // TINYBLOB
unsignedBigInteger()
unsignedBigInteger
方法會建立一個 UNSIGNED BIGINT
相等的欄位
1$table->unsignedBigInteger('votes');
unsignedInteger()
unsignedInteger
方法會建立一個 UNSIGNED INTEGER
相等的欄位
1$table->unsignedInteger('votes');
unsignedMediumInteger()
unsignedMediumInteger
方法會建立一個 UNSIGNED MEDIUMINT
相等的欄位
1$table->unsignedMediumInteger('votes');
unsignedSmallInteger()
unsignedSmallInteger
方法會建立一個 UNSIGNED SMALLINT
相等的欄位
1$table->unsignedSmallInteger('votes');
unsignedTinyInteger()
unsignedTinyInteger
方法會建立一個 UNSIGNED TINYINT
相等的欄位
1$table->unsignedTinyInteger('votes');
ulidMorphs()
ulidMorphs
方法是一個方便的方法,它會新增一個 {column}_id
CHAR(26)
相等的欄位和一個 {column}_type
VARCHAR
相等的欄位。
此方法旨在用於定義多型 Eloquent 關聯 所需的欄位,該關聯使用 ULID 識別符。在以下範例中,將會建立 taggable_id
和 taggable_type
欄位
1$table->ulidMorphs('taggable');
uuidMorphs()
uuidMorphs
方法是一個方便的方法,它會新增一個 {column}_id
CHAR(36)
相等的欄位和一個 {column}_type
VARCHAR
相等的欄位。
此方法旨在用於定義多型 Eloquent 關聯 所需的欄位,該關聯使用 UUID 識別符。在以下範例中,將會建立 taggable_id
和 taggable_type
欄位
1$table->uuidMorphs('taggable');
ulid()
ulid
方法會建立一個 ULID
相等的欄位
1$table->ulid('id');
uuid()
uuid
方法會建立一個 UUID
相等的欄位
1$table->uuid('id');
vector()
vector
方法會建立一個 vector
相等的欄位
1$table->vector('embedding', dimensions: 100);
year()
year
方法會建立一個 YEAR
相等的欄位
1$table->year('birth_year');
資料行修飾符
除了上面列出的欄位類型外,還有幾種欄位「修飾詞」可以在將欄位新增到資料庫表格時使用。例如,要使欄位「可為空」,您可以使用 nullable
方法
1use Illuminate\Database\Schema\Blueprint;2use Illuminate\Support\Facades\Schema;3 4Schema::table('users', function (Blueprint $table) {5 $table->string('email')->nullable();6});
下表包含所有可用的欄位修飾詞。此列表不包含 索引修飾詞
修飾詞 | 描述 |
---|---|
->after('column') |
將欄位放置在另一個欄位「之後」(MariaDB / MySQL)。 |
->autoIncrement() |
將 INTEGER 欄位設定為自動遞增 (主鍵)。 |
->charset('utf8mb4') |
為欄位指定字元集 (MariaDB / MySQL)。 |
->collation('utf8mb4_unicode_ci') |
為欄位指定排序規則。 |
->comment('my comment') |
為欄位新增註解 (MariaDB / MySQL / PostgreSQL)。 |
->default($value) |
為欄位指定「預設」值。 |
->first() |
將欄位放置在表格中的「最前面」(MariaDB / MySQL)。 |
->from($integer) |
設定自動遞增欄位的起始值 (MariaDB / MySQL / PostgreSQL)。 |
->invisible() |
使欄位在 SELECT * 查詢中「不可見」(MariaDB / MySQL)。 |
->nullable($value = true) |
允許將 NULL 值插入欄位中。 |
->storedAs($expression) |
建立儲存的產生欄位 (MariaDB / MySQL / PostgreSQL / SQLite)。 |
->unsigned() |
將 INTEGER 欄位設定為 UNSIGNED (MariaDB / MySQL)。 |
->useCurrent() |
將 TIMESTAMP 欄位設定為使用 CURRENT_TIMESTAMP 作為預設值。 |
->useCurrentOnUpdate() |
將 TIMESTAMP 欄位設定為在記錄更新時使用 CURRENT_TIMESTAMP (MariaDB / MySQL)。 |
->virtualAs($expression) |
建立虛擬產生的欄位 (MariaDB / MySQL / SQLite)。 |
->generatedAs($expression) |
使用指定的序列選項建立身分欄位 (PostgreSQL)。 |
->always() |
定義身分欄位的序列值優先於輸入 (PostgreSQL)。 |
預設表達式
default
修飾詞接受值或 Illuminate\Database\Query\Expression
實例。使用 Expression
實例將防止 Laravel 將值包在引號中,並允許您使用資料庫特定的函數。當您需要為 JSON 欄位指定預設值時,這種情況特別有用
1<?php 2 3use Illuminate\Support\Facades\Schema; 4use Illuminate\Database\Schema\Blueprint; 5use Illuminate\Database\Query\Expression; 6use Illuminate\Database\Migrations\Migration; 7 8return new class extends Migration 9{10 /**11 * Run the migrations.12 */13 public function up(): void14 {15 Schema::create('flights', function (Blueprint $table) {16 $table->id();17 $table->json('movies')->default(new Expression('(JSON_ARRAY())'));18 $table->timestamps();19 });20 }21};
對預設表達式的支援取決於您的資料庫驅動程式、資料庫版本和欄位類型。請參閱您的資料庫文件。
欄位順序
當使用 MariaDB 或 MySQL 資料庫時,可以使用 after
方法在綱要中現有欄位之後新增欄位
1$table->after('password', function (Blueprint $table) {2 $table->string('address_line1');3 $table->string('address_line2');4 $table->string('city');5});
修改資料行
change
方法允許您修改現有欄位的類型和屬性。例如,您可能希望增加 string
欄位的大小。為了查看 change
方法的實際效果,讓我們將 name
欄位的大小從 25 增加到 50。為了實現這一點,我們只需定義欄位的新狀態,然後呼叫 change
方法
1Schema::table('users', function (Blueprint $table) {2 $table->string('name', 50)->change();3});
修改欄位時,您必須明確包含您想要保留在欄位定義中的所有修飾詞 - 任何遺失的屬性都將被刪除。例如,要保留 unsigned
、default
和 comment
屬性,您必須在變更欄位時明確呼叫每個修飾詞
1Schema::table('users', function (Blueprint $table) {2 $table->integer('votes')->unsigned()->default(1)->comment('my comment')->change();3});
change
方法不會變更欄位的索引。因此,您可以使用索引修飾詞在修改欄位時明確新增或刪除索引
1// Add an index...2$table->bigIncrements('id')->primary()->change();3 4// Drop an index...5$table->char('postal_code', 10)->unique(false)->change();
重新命名資料行
要重新命名欄位,您可以使用綱要建立器提供的 renameColumn
方法
1Schema::table('users', function (Blueprint $table) {2 $table->renameColumn('from', 'to');3});
刪除資料行
要刪除欄位,您可以使用綱要建立器上的 dropColumn
方法
1Schema::table('users', function (Blueprint $table) {2 $table->dropColumn('votes');3});
您可以將欄位名稱陣列傳遞給 dropColumn
方法,從表格中刪除多個欄位
1Schema::table('users', function (Blueprint $table) {2 $table->dropColumn(['votes', 'avatar', 'location']);3});
可用的命令別名
Laravel 提供了幾個與刪除常見欄位類型相關的便利方法。下表描述了這些方法中的每一個
命令 | 描述 |
---|---|
$table->dropMorphs('morphable'); |
刪除 morphable_id 和 morphable_type 欄位。 |
$table->dropRememberToken(); |
刪除 remember_token 欄位。 |
$table->dropSoftDeletes(); |
刪除 deleted_at 欄位。 |
$table->dropSoftDeletesTz(); |
dropSoftDeletes() 方法的別名。 |
$table->dropTimestamps(); |
刪除 created_at 和 updated_at 欄位。 |
$table->dropTimestampsTz(); |
dropTimestamps() 方法的別名。 |
索引
建立索引
Laravel 綱要建立器支援多種類型的索引。以下範例建立一個新的 email
欄位,並指定其值應為唯一值。要建立索引,我們可以將 unique
方法鏈接到欄位定義
1use Illuminate\Database\Schema\Blueprint;2use Illuminate\Support\Facades\Schema;3 4Schema::table('users', function (Blueprint $table) {5 $table->string('email')->unique();6});
或者,您可以在定義欄位後建立索引。為此,您應該在綱要建立器藍圖上呼叫 unique
方法。此方法接受應接收唯一索引的欄位名稱
1$table->unique('email');
您甚至可以將欄位陣列傳遞給索引方法,以建立複合 (或組合) 索引
1$table->index(['account_id', 'created_at']);
建立索引時,Laravel 將根據表格、欄位名稱和索引類型自動產生索引名稱,但您可以將第二個引數傳遞給方法來自行指定索引名稱
1$table->unique('email', 'unique_email');
可用的索引類型
Laravel 的綱要建立器藍圖類別提供了用於建立 Laravel 支援的每種索引類型的方法。每個索引方法都接受一個可選的第二個引數,以指定索引的名稱。如果省略,名稱將從用於索引的表格和欄位名稱以及索引類型衍生而來。下表描述了每個可用的索引方法
命令 | 描述 |
---|---|
$table->primary('id'); |
新增主鍵。 |
$table->primary(['id', 'parent_id']); |
新增複合鍵。 |
$table->unique('email'); |
新增唯一索引。 |
$table->index('state'); |
新增索引。 |
$table->fullText('body'); |
新增全文索引 (MariaDB / MySQL / PostgreSQL)。 |
$table->fullText('body')->language('english'); |
新增指定語言的全文索引 (PostgreSQL)。 |
$table->spatialIndex('location'); |
新增空間索引 (SQLite 除外)。 |
重新命名索引
要重新命名索引,您可以使用綱要建立器藍圖提供的 renameIndex
方法。此方法接受當前索引名稱作為其第一個引數,並接受所需的名稱作為其第二個引數
1$table->renameIndex('from', 'to')
刪除索引
要刪除索引,您必須指定索引的名稱。預設情況下,Laravel 會根據表格名稱、索引欄位的名稱和索引類型自動指派索引名稱。以下是一些範例
命令 | 描述 |
---|---|
$table->dropPrimary('users_id_primary'); |
從 "users" 表格中刪除主鍵。 |
$table->dropUnique('users_email_unique'); |
從 "users" 表格中刪除唯一索引。 |
$table->dropIndex('geo_state_index'); |
從 "geo" 表格中刪除基本索引。 |
$table->dropFullText('posts_body_fulltext'); |
從 "posts" 表格中刪除全文索引。 |
$table->dropSpatialIndex('geo_location_spatialindex'); |
從 "geo" 表格中刪除空間索引 (SQLite 除外)。 |
如果您將欄位陣列傳遞到刪除索引的方法中,則會根據表格名稱、欄位和索引類型產生慣用的索引名稱
1Schema::table('geo', function (Blueprint $table) {2 $table->dropIndex(['state']); // Drops index 'geo_state_index'3});
外鍵約束
Laravel 還支援建立外鍵約束,該約束用於在資料庫層級強制參考完整性。例如,讓我們在 posts
表格上定義一個 user_id
欄位,該欄位參考 users
表格上的 id
欄位
1use Illuminate\Database\Schema\Blueprint;2use Illuminate\Support\Facades\Schema;3 4Schema::table('posts', function (Blueprint $table) {5 $table->unsignedBigInteger('user_id');6 7 $table->foreign('user_id')->references('id')->on('users');8});
由於此語法相當冗長,Laravel 提供了額外的、更簡潔的方法,這些方法使用慣例來提供更好的開發人員體驗。當使用 foreignId
方法建立欄位時,上面的範例可以改寫如下
1Schema::table('posts', function (Blueprint $table) {2 $table->foreignId('user_id')->constrained();3});
foreignId
方法會建立一個 UNSIGNED BIGINT
相等的欄位,而 constrained
方法將使用慣例來確定要參考的表格和欄位。如果您的表格名稱與 Laravel 的慣例不符,您可以手動將其提供給 constrained
方法。此外,也可以指定應指派給產生的索引的名稱
1Schema::table('posts', function (Blueprint $table) {2 $table->foreignId('user_id')->constrained(3 table: 'users', indexName: 'posts_user_id'4 );5});
您也可以為約束的 "on delete" 和 "on update" 屬性指定所需的動作
1$table->foreignId('user_id')2 ->constrained()3 ->onUpdate('cascade')4 ->onDelete('cascade');
也為這些動作提供了另一種表達性語法
方法 | 描述 |
---|---|
$table->cascadeOnUpdate(); |
更新應串聯。 |
$table->restrictOnUpdate(); |
更新應受到限制。 |
$table->nullOnUpdate(); |
更新應將外鍵值設定為 null。 |
$table->noActionOnUpdate(); |
更新時不執行任何動作。 |
$table->cascadeOnDelete(); |
刪除應串聯。 |
$table->restrictOnDelete(); |
刪除應受到限制。 |
$table->nullOnDelete(); |
刪除應將外鍵值設定為 null。 |
$table->noActionOnDelete(); |
如果存在子記錄,則阻止刪除。 |
任何其他 欄位修飾詞 都必須在 constrained
方法之前呼叫
1$table->foreignId('user_id')2 ->nullable()3 ->constrained();
刪除外鍵
要刪除外鍵,您可以使用 dropForeign
方法,並將要刪除的外鍵約束的名稱作為引數傳遞。外鍵約束使用與索引相同的命名慣例。換句話說,外鍵約束名稱基於表格名稱和約束中的欄位,後跟 "_foreign" 後綴
1$table->dropForeign('posts_user_id_foreign');
或者,您可以將包含持有外鍵的欄位名稱的陣列傳遞給 dropForeign
方法。陣列將使用 Laravel 的約束命名慣例轉換為外鍵約束名稱
1$table->dropForeign(['user_id']);
切換外鍵約束
您可以使用以下方法在遷移中啟用或停用外鍵約束
1Schema::enableForeignKeyConstraints();2 3Schema::disableForeignKeyConstraints();4 5Schema::withoutForeignKeyConstraints(function () {6 // Constraints disabled within this closure...7});
SQLite 預設停用外鍵約束。當使用 SQLite 時,請確保在您的資料庫設定中啟用外鍵支援,然後再嘗試在遷移中建立它們。
事件
為了方便起見,每個遷移操作都會分派一個 事件。以下所有事件都擴展了基礎 Illuminate\Database\Events\MigrationEvent
類別
類別 | 描述 |
---|---|
Illuminate\Database\Events\MigrationsStarted |
即將執行一批遷移。 |
Illuminate\Database\Events\MigrationsEnded |
一批遷移已完成執行。 |
Illuminate\Database\Events\MigrationStarted |
即將執行單個遷移。 |
Illuminate\Database\Events\MigrationEnded |
單個遷移已完成執行。 |
Illuminate\Database\Events\NoPendingMigrations |
遷移命令未找到待處理的遷移。 |
Illuminate\Database\Events\SchemaDumped |
資料庫綱要轉儲已完成。 |
Illuminate\Database\Events\SchemaLoaded |
現有的資料庫綱要轉儲已載入。 |