iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 6
1
自我挑戰組

Laravel 實戰經驗分享系列 第 6

Laravel 實戰經驗分享 - Day6 初探 Laravel - Migration

來到鐵人挑戰的第六天,今天要講的是 Laravel 提供的 Migration (遷移)功能,在以往只寫純 PHP 時,我們都是需要自行透過 SQL 語法或是 phpmyadmin 等工具建立資料表,但是 Laravel 提供的 Migration 功能,可以讓我們透過程式自行建構資料表,除此之外,它也提供了 rollbackresetrefreshfresh 等有點可怕的快速回滾、重設、重建資料表的指令。

建立/修改資料表

首先,我們透過昨天所提到的 artisan 語法建好 Migration 所需的程式檔案。

php artisan make:migration create_animals_table --create=animals

這個與指令會在 database/migrations 下建立一個檔案 2020_09_21_XXXXXX_create_animals_table.php,而這個檔案能夠幫助你建立 animals 這張資料表,--create=animals 則會幫助你在這個檔案內先將 Schema 指向 animals 資料表,我會建議這個檔案的命名規則依照此規範,若需要增加/修改某個元素也是如下所示。

php artisan make:migration add_species_column_to_table --table=animals
# 或是
php artisan make:migration alter_sex_column_of_table --table=animals

使用 --table 將要修改的資料表指向 animals,我自己在命名這個檔案會將對這個資料表的操作方式放在開頭,中段說明要如何執行,table 作為結尾,以此語意化的方式進行檔案命名,以便後續若需要重建資料表時了解自己之前幹了甚麼好事。

Migration 內的 up & down

建立資料表

進入到 Migration 檔案內,我們可以先大致看一下程式的結構,並以建立 animals 作為範例,至於其他資料表欄位如何建立,可參照官方文件

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateAnimalsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('animals', function (Blueprint $table) {
            $table->increments('id');
            $table->string('sex');
            $table->integer('number');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('animals');
    }
}

修改資料表

若是我們以上面的程式碼為例,執行修改資料表的指令。修改/刪除欄位參考

php artisan make:migration add_species_column_to_table --table=animals

程式碼如下

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddSpeciesColumnToTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('animals', function (Blueprint $table) {
            $table->string('species')->nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('animals', function (Blueprint $table) {
            $table->dropColumn('species');
        });
    }
}

資料表的 create (建立)以及 rollback (回滾)

程式碼 function 裡面 up 代表的是執行 Migrate 時的動作。
程式寫好後便可執行以下指令建立資料表囉!

php artisan migrate

而在 down 內則代表資料表的 rollback (回滾)時會執行的程式,執行 rollback 指令如下。

php artisan migrate:rollback

執行這個指令,資料表會批次的 rollback 至你上一次執行的 Migration 位置,Laravel 本身有將這個執行的順序紀錄在一張 migrations 的資料表內。

這邊建議若是 up 裡面執行甚麼程式,down 內就的操作就是將 up 反著執行,這樣才能正常執行資料表的建立以及回復,我有看過開發者不寫 down 函式,透過 phpmyadmin 直接刪除所有資料表,再重新執行 php artisan migrate,拜託大家不要這樣幹,因為這個指令並不會幫你保留已儲存的資料,你永遠不知道自己會不會操作錯誤,導致發生無法挽回的事情。

以下使用請注意

這個指令是會一次回復(執行 down)「所有」資料表,使用請小心。

php artisan migrate:reset

這個指令則是一次執行 reset + migrate,因此如果沒有好好寫 down 函式的人就會噴錯囉!

php artisan migrate:refresh

這個指令是「刪除」所有資料表後執行 migrate,恩,史上最危險。

php artisan migrate:fresh

修改資料表/資料結構的實務經驗

在某些情境中,當你建立的資料表有誤或是結構需要修改,通常會有兩種做法。

  1. 將資料表回滾,並且修改原有 Migration 的 PHP 檔案後,重新執行 migrate (較不建議)
    你可以先執行以下指令,資料表會藉由 down 內所編寫的程式執行,一般來說就是回復到上一次執行 migrate 前的步驟。
php artisan migrate:rollback

然後重新修改 Migration 檔案內 up 所執行的動作,並再次執行 Migration。

php artisan migrate

不建議使用這個方法的原因一樣同上,因為 Laravel 執行 Migration 以及 rollback 的方式都是從這次新建的「所有」檔案開始執行,因此你可能會一次執行多個 PHP 檔案,這樣會有已新增的資料被覆蓋的風險存在。

  1. 新建一個 migration 檔案,並直接執行
php artisan make:migration alter_sex_column_of_table --table=animals

檔案內程式碼

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AlterSexColumnOfTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('animals', function (Blueprint $table) {
            $table->string('sex')->nullable()->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('animals', function (Blueprint $table) {
            $table->string('sex')->nullable(false)->change();
        });
    }
}

執行以下指令

php artisan migrate

這個方法只需要執行一次 Migration 指令,不會受之前所建的檔案影響,風險相對小很多,只是若你在事前沒有好好規劃資料庫的欄位以及結構,你的 Migration 檔案會非常多,上到一個乾淨的環境執行會一次跑所有的檔案,看起來會很壯觀XD,所以最正確的做法還是先進行開發前資料庫欄位、結構的規劃,再來撰寫 Migration 檔案唷!

想不到今天篇幅這麼長,那這樣 ERD 的規劃就留給明天吧 ╮(╯∀╰)╭ (懶)


上一篇
Laravel 實戰經驗分享 - Day5 初探 Laravel - Artisan
下一篇
Laravel 實戰經驗分享 - Day7 初探 Laravel - 如何規劃資料庫關聯
系列文
Laravel 實戰經驗分享30

尚未有邦友留言

立即登入留言