laravel中有個數據庫遷移功能,migration。基本用法就是在database/migrations/的文件夾下面創建遷移數據庫的類,在這個類中實現兩個方法:
up() 和 down()
up表示運行這個數據庫遷移你要做些什么,down表示你回滾這次數據庫遷移你要做些什么。
這樣你就可以使用 php artisan migrate 就可以進行數據庫遷移, php artisan migrate:rollback 就可以進行遷移回滾。
我一直在想,這個東西到底是雞肋還是銀彈呢?
這個功能發明出來的大致功能是為了讓各個環境更好同步數據庫。比如一個人A開發一個評論模塊,需要做兩個動作,那么A就創建一個migrate類,在里面用創造一個評論表,然后可能在文章表那里增加一個評論數的字段。當A把代碼同步到主干分支的時候,B這個時候獲取到了代碼,那么就很簡單實用php artisan migrate就能使用代碼增加評論表和修改文章表字段。甚至於,在測試環境修改后到線上環境運行就可以同步表修改了。
但是總是覺得這里有幾個問題:
首先是這個功能在項目上線之后很難使用。他至多只能同步各個人的開發環境,而不能同步線上環境。因為你想啊,我們平時線上修改是先改表還是先上代碼?一般是先改表的。才上代碼的。那么這樣,我們就不大會選擇在線上直接運行php artisan migrate的行為。一旦不會選擇在上線后使用這個功能,就代表這個功能的使用場景大打折扣了。
其次是,這個行為安全性得不到保障。migrate的行為說到底是使用代碼來控制數據庫,和php里面執行alter table命令一樣。一般來說,改表行為是一個非常危險的行為,越危險行為做的安全路子就是讓鏈條變短。我們使用了php來執行一個改表命令,萬一,數據量大的時候,改表非常慢,鎖表,甚至於觸發到php的命令耗時上限等行為?具體這個改表行為會有何后續行為?你如何回滾?這個時候,你就會懵了...用代碼來管理數據庫,我的結論就是一個,不純正!!什么東西都有其專業的領域,用最專業的工具來做最專業的事情。
還有就是,migrate的rollback簡直就是一個定時炸彈。我們一般往migrate的down里面寫的是droptable的操作。一旦,萬一,這種命令在線上被執行了。那么,就相當於是一個rm -rf的命令啊。把所有數據都給刪除了。所以,安全起見,還是離這個rollback操作遠一點好。
下面來說說開發階段,在開發階段我們會頻繁修改數據庫,那么這個時候,如果你想要維護一個很完善的migrate列表,你會很痛苦地發現你的migrate下的文件何其多啊。但最后,我們真的關注數據庫是如何變化的么?其實,不關注。這些migrate的命令到最后確實沒有多大用處。筆者的實踐經歷,到了一個項目准備上線的時候,我都恨不得把這些migrate的文件匯聚成一個migrate文件呢。。所以呢,在開發階段,維護一個migrate列表,我感覺倒不如維護一個db.sql,外加laravel的初始化數據工具。每次有數據表改動,讓大家source表,再初始化數據更好。
所以,綜上所訴,結論是:框架的數據庫遷移是個雞肋。