# ThinkPHP6數據庫遷移工具
[TOC]
## 介紹
> 本篇文章均可適用于`tp5`,`tp5.1`,`tp6`.
### 依賴
~~~
composer require topthink/think-migration
~~~
### 官方文檔
可以先閱讀一下官方文檔,再來這里看實例用法.
[數據庫遷移工具](http://www.hmoore.net/manual/thinkphp6_0/1118028)
### 有什么好處
- 數據庫自動創建,數據自動初始化
- 數據庫跟隨代碼版本保留和更新
- 一份代碼,多種數據庫(Mysql,Sqlite,SqlServer,PostgreSQL,MongoDb)
### 什么是數據庫遷移工具
有一個庫叫[Phinx](http://docs.phinx.org/en/latest/),可以用php代碼建立數據表結構.
我們設計數據表的時候,可能是用圖形化軟件來設計,比如`MySQL-Front`,`Dbeaver`.也有可能有人直接寫sql語句.還有一種方式就是用`Phinx`來設計數據表結構.
`Phinx`的用法類似如下:
~~~
<?php
use Phinx\Migration\AbstractMigration;
class CreateUserLoginsTable extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-change-method
*
* Uncomment this method if you would like to use it.
*/
public function change()
{
// create the table
$table = $this->table('user_logins');
$table->addColumn('user_id', 'integer')
->addColumn('created', 'datetime')
->create();
}
/**
* Migrate Up.
*/
public function up()
{
}
/**
* Migrate Down.
*/
public function down()
{
}
}
~~~
`Phinx`本身是一個完整的功能強大的類庫,在ThinkPHP中,并沒有依賴這個庫,而是將它核心的代碼二次開發成適應tp架構的`think-migration`庫.
### 主要功能
- 創建數據表
- 修改數據表
- 初始化數據
## 基本用法
需要結合ThinkPHP命令行使用,有的人可能不熟悉,請先看一下文檔[命令行](http://www.hmoore.net/manual/thinkphp6_0/1037640).
### 操作一次數據庫
當我們想操作一次數據庫的時候,就要用命令行創建一個執行文件.
操作數據庫是指:創建表,修改表.
可以在一個執行文件里操作多個表,但我個人建議,一個文件只操作一個表.
執行命令:
~~~
php think migrate:create AnyClassNameYouWant
~~~
此時會在項目下生成如下文件:
~~~
/database/migrations/20190615151716_any_class_name_you_want.php
~~~
我們要把自己對數據庫的操作寫到這個文件里.
### 執行操作
我們可能會創建多個文件,每個文件操作一個表,我們在每個文件里都寫好數據庫結構之后,就執行操作,真正的創建數據表.
執行命令:
~~~
php think migrate:run
~~~
此時數據庫就會多出你剛剛操作的表,不管是創建還是更新,都已經生效了.
> 數據表的名字會有配置文件里設置的前綴
## 例子
### 定義一個`users`表
執行命令:
```
php think migrate:create CreateTableUsers
```
會生成相應的文件,修改文件內容如下:
~~~
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class CreateTableUsers 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()
{
// create the table
$table = $this->table('users',array('engine'=>'MyISAM'));
$table->addColumn('username', 'string',array('limit' => 15,'default'=>'','comment'=>'用戶名,登陸使用'))
->addColumn('password', 'string',array('limit' => 32,'default'=>md5('123456'),'comment'=>'用戶密碼'))
->addColumn('login_status', 'boolean',array('limit' => 1,'default'=>0,'comment'=>'登陸狀態'))
->addColumn('login_code', 'string',array('limit' => 32,'default'=>0,'comment'=>'排他性登陸標識'))
->addColumn('last_login_ip', 'integer',array('limit' => 11,'default'=>0,'comment'=>'最后登錄IP'))
->addColumn('last_login_time', 'datetime',array('default'=>0,'comment'=>'最后登錄時間'))
->addColumn('is_delete', 'boolean',array('limit' => 1,'default'=>0,'comment'=>'刪除狀態,1已刪除'))
->addIndex(array('username'), array('unique' => true))
->create();
}
}
~~~
在上面這個文件中,會定義一個`users`表,給這個表添加字段`addColumn`,給這個表添加索引`addIndex`,最后執行創建方法`create`.
### 創建這個表
執行命令:
```
php think migrate:run
```
此時數據庫便創建了這個表.
### 修改這個表
現在給這個表增加`avatar`字段
新建一個執行文,
執行命令:
```
php think migrate:create UpdateTableUsers
```
修改內容文件如下:
~~~
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class CreateTableUsers 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()
{
// create the table
$table = $this->table('users');
$table->addColumn('avatar', 'string',array('limit' => 100,'default'=>'','comment'=>'用戶頭像'))
$table->update();
}
}
~~~
執行命令,寫入數據庫:
```
php think migrate:run
```
此時`users`表就多了一個`avatar`字段.
> 語法具體可參考手冊或`Phinx`文檔.
### 其他操作
如果你希望給刪除字段,重命名字段,刪除表等其他操作,不能寫在`change`方法里.
`change`方法里的操作都是可以自動升級/還原的,只支持一部分操作.
如果你不打算使用這個特性,那就可以隨便使用所有方法,具體的可以參考`Phinx`文檔.