Laravel Migrate可以用來做資料庫版本控制,對開發團隊來說,可以快速修改Schema,了解每個工程師做了什麼change,比如新增、修改哪些欄位、表格等等,是非常實用的功能。
在開始之前,須先建立好DB,並設定好.env中的DB連線config。
建立migrate指令:
$ php artisan make:migration {name}
比如建立一個migrate 目的是要建立user table:
$ php artisan make:migration create_user_table
database/migrations下會產生如下圖的檔案: prefix會自動加上建立datetime
- 可以理解成: up()就是要對資料庫做什麼操作,down()就是把up()做的事情還原。比如若up() method用來建立table: 新增欄位、index、unique、nullable等等設定,down() method則要用來刪除table。
- 如果再執行一次 $ php artisan make:migration create_user_table,會show已存在的error:
接著寫好up, down程式邏輯:
執行所有migrate:
$ php artisan migrate
- 這個指令會執行所有尚未migrate的檔案中的up() method,會依建立時間順序執行。
若只想migrate某個檔案,可以指定檔案路徑:
$ php artisan migrate --path=/database/migrations/xxx.php
接著從DB中就可以看到user表建立了:
也會在DB中自動建立一張migrations表,把這次執行migrate的紀錄寫上去:
- batch是執行順序的意思,如果有batch數字一樣的情況,表示當時是一起做migrate的,若執行rollback也會一起。
- 假設剛剛還有一個migrate是create_product_table,一起執行migrate的話,這邊就會有兩筆紀錄,batch都是1。
有時候執行migrate會發現出現這個訊息: Nothing to migrate.
這表示已經所有migrate都有執行過了,可以查詢一下migrate狀態:
$ php artisan migrate:status
接著試試rollback: 這個指令會還原上一次的migrate,以程式碼來看就是會刪除user table,原本migrations table上的那行紀錄也會被清除。
$ php artisan migrate:rollback
- 這邊需特別注意,即使table中有資料,執行rollback一樣會把整張table砍掉。
執行rollback後,從status上來看,會恢復成未執行的狀態:
然後再建立一個migrate,for新增產品表格:
$ php artisan make:migration create_product_table
接著執行migrate,如上述,會執行所有尚未執行migrate檔案的up(),會把user跟product表都依序建立起來:
$ php artisan migrate
由於user表結構剛剛看過了,這邊只show product:
再試試看rollback:
$ php artisan migrate:rollback
如上述,rollback會還原上一次的migrate,也就是會執行create_user_table和create_product_table的down() method,所以這時候會發現user跟product表都不見了。
先rollback所有migrate(從時間最新到最舊依序還原),再重新執行所有migrate(從最舊到最新): 也就是執行所有migrate的down method,再執行所有migrate的up method。
$ php artisan migrate:refresh
rollback所有migrate(從最新到最舊): 也就是執行所有migrate的down method。
$ php artisan migrate:reset
以上介紹了migrate的用法,對一個新加入團隊的發開者來說,一個指令就能夠馬上建置完整的local DB環境,真的是非常強大啊!
不難發現,其實Laravel是透過migrations這張表來記錄migrate狀態的,下migrate指令的時候會比對判斷table中的migration名稱,多出來的migrate檔案就是新的,要trigger up() method,並insert記錄。下rollback指令的時候,會抓table中batch數字最大的去trigger該組的down() method,然後把這組batch的data row從table中移除。