https://www.jianshu.com/p/5daa61fb3d46
## 通過本文你可以學到:
* Migration初識
* thinkphp5 使用 Migration
## Migration 初識
**什么是Migration?**
migration用谷歌翻譯是**移民**的意思,在PHP中我們將它理解為**遷移**,將Migration用在數據庫上就理解為**數據庫遷移**咯。在migration開發之前,我們都是手寫SQL創建表語句,創建成功之后需要手動在數據庫執行,項目初始化光數據庫的創建就花費很多時間。另外在多人團隊開發中,如果要求每個開發人員都在本地使用數據庫那么我們通常都是將數據庫備份成SQL文件互相傳遞,這還并不是很繁瑣,繁瑣的在于如果數據庫某個表的字段出現變動那么就需要將這個變動的SQL語句傳給每個開發小伙伴讓他們在本地都手動的更新下,一次可以這樣,但是多次呢?我想在開發團隊中這種事情肯定讓人頭疼咯,所以migration就誕生咯。Migration就是一些管理數據庫結構的文件,這些文件其實都是抽象化的SQL,可以通過命令行執行而改變數據庫的結構,這些文件都是存放在項目下的,隨著項目版本的迭代而迭代。在開發過程中,如果一位小伙伴改動了數據庫的表結構,她只需要生成一個migration文件并推送到版本控制系統中,如:Git,并通知其他小伙伴,其他小伙伴只需要pull然后在命令行執行下migration命令就可以了,簡化了傳統的數據庫變動流程,加快項目的開發。
**Migration文件作用**
migration 文件的主要作用就是用來管理數據庫的結構,其實它是一組SQL語句的抽象化,migration 文件可以創建表,刪除表,增加字段,刪除字段等等基本上所有的數據庫操作,其實這就像你自己手動寫SQL語句一樣,只不過在 migration 中你不需要手動的寫SQL語句,只需要按照它的規則語法調用一下就可以啦。
## thinkphp5 使用 migration
`thinkphp5` 為開發者提供了一整套的 migration 解決方案,不過默認情況下 migration 是沒有安裝的,需要我們手動安裝。將工作目錄切換到tp5項目下,執行:
~~~
composer require topthink/think-migration
~~~
安裝成功之后,我們執行:
~~~
php think
~~~
會看到:

thinkphp5 migration工具
> 從圖中我們可以看到 migration 和 seed,本文中我們只講解 migration, seed將會在下節講解。
### create 命令
~~~
php think migrate:create TableName
~~~
TableName 格式:首字母大寫的駝峰法。該命令是用來創建一個 migration 文件,比如這里我們創建一個 User 的 migration 文件:
~~~
php think migrate:create Users
~~~
migration 初次執行
第一次執行 Migraton 它會提示一些信息,這里全部統一 `yes` 就可以啦。創建成功如下:

migration 創建成功
在項目的根目錄下多了一個 database 目錄,其目錄結構如下:

migration 目錄結構
有一個Migration文件夾,該文件夾就是用來存放 Migration 文件,打開可以看到我們剛才創建的 User 的 migration 文件:

UserMigration 文件
> 有沒有注意它的文件名格式?是這樣的:時間 + 隨機數 + \_ + 文件名。為什么這樣設置?當然有它的道理啦,深入學習你就知道啦!
文件創建好之后,我們來看下它的內容:
~~~
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class Users extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
}
}
~~~
文件結構很簡單,就一個類,但是怎么使用它呢?下面看我舉一個 DEMO,這里我需要給我上面創建的 User 文件增加創建 users 表的功能,我該這樣做:
**users 表結構如下:**
| 字段 | 類型 | 注釋 |
| --- | --- | --- |
| `id` | `int(11)` | 主鍵 |
| `nickname` | `varchar(16)` | 呢稱 |
| `email` | `varchar(32)` | 郵箱 |
| `password` | `varchar(64)` | 密碼 |
刪除默認自帶的 `change` 方法,創建 `up()` 方法和 `down()` 方法。`up()` 方法是在執行 `run` 命令執行的,`down()` 是在執行 `rollback` 命令執行的。
`up()` 方法如下:
~~~
public function up()
{
$table = $this->table('users');
$table->addColumn('nickname', 'string', ['limit' => 16, 'null' => false])
->addColumn('email', 'string', ['limit' => 32, 'null' => false])
->addColumn('password', 'string', ['limit' => 64, 'null' => false])
->create();
}
~~~
`down()` 方法如下:
~~~
public function down()
{
$this->dropTable('users');
}
~~~
文件整體內容如下:
~~~
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class Users extends Migrator
{
public function up()
{
$table = $this->table('users');
$table->addColumn('nickname', 'string', ['limit' => 16, 'null' => false])
->addColumn('email', 'string', ['limit' => 32, 'null' => false])
->addColumn('password', 'string', ['limit' => 64, 'null' => false])
->create();
}
public function down()
{
$this->dropTable('users');
}
}
~~~
這樣,一個可以創建 users 表的 migration 文件就創建完畢了,接下來,我們來學習下一個命令。
### run 命令
migration 文件創建完畢,還需要執行 `run` 命令才可以修改數據庫:
> 注意,執行此步驟之前請正確配置了 `application/database.php` 。
~~~
php think migrate:run
~~~
執行成功之后,查看數據庫:

執行 run 命令之后
users 表結構如下:

users 表結構
> 可能有的小伙伴注意到,之前我定義了 migration 只指定了 `nickname`, `email`, `password` 三個字段,但是執行 `run` 命令創建的表中有四個字段,多了一個 `id` 主鍵?這是 `thinkphp5` 為我們默認添加的!小伙伴注意啦!如果你的主鍵字段名為 `id` 就不需要自己手動的指定啦!!!
### rollback 命令
現在呢,我突然不想創建 users 表啦,那怎么辦呢?`thinkphp5` 為我們提供了回滾的命令:
~~~
php think migrate:rollback
~~~
該命令默認會回滾所有的已執行的migration文件,也就一夜回到解放前啦。
### status 命令
~~~
php think migrate:status
~~~
執行該命令結果如下:

執行 status 命令的結果
列表的形式展示了 migration 的執行情況。
### breakpoint 命令
`rollback` 默認是回滾全部的 `migration` 操作,但是項目開發中每個表中都需要一些模擬的數據,如果回滾所有的 migration, 那么表中的模擬數據全都刪除了,重新執行 `run` 之后又需要重新填充數據,那就非常的麻煩咯,這顯然不是我們想要得。所以,斷點機制就是解決這個問題。它允許我們在創建某個表之后打上斷點,這樣 `rollback` 執行到這個表的時候如果是斷點就停止繼續運行下去了(得排除強制刪除的情況)。具體命令如下:
~~~
php think migrate:breakpoint
~~~
舉個例子,我首先創建了 UserMigration 文件,且執行了 `run` 命令,users 表也創建了,這個時候呢,老板說,users 的表結構設計的非常合理,暫時就這么定了!此時:
#### 一無所知【不了解斷點機制】
首先,我在 users 表中填充個了 500 個用戶,完成一系列的測試后,接下來我著手創建 ArticleMigration 文件,并執行了 `run` 在數據庫創建了 `articles` 表,但是由于一些原因,必須得刪除這個 `articles` 表,于是我執行了 `rollback` 命令,就這樣數據庫給清空了...于是老板

搞事情
我也是:

一臉懵B
#### 早有準備【了解斷點機制】
執行了:
~~~
php think migrate:breakpoint
~~~
之后接著下面得操作,接下來同樣出現錯誤,但是完美的解決。

走向人生巔峰
**Q:那怎么取消斷點呢?**
A:再執行一次 `breakpoint` 就可以啦。
好了今天的教程就到這里啦。此篇是小滕的《Thinkphp5入門系列課程》第十一課:Migration(一)。
喜歡的給個訂閱唄!
**由于作者水平有限,如有錯誤請歡迎指正。**
作者:小滕Tt
鏈接:https://www.jianshu.com/p/5daa61fb3d46
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。