​ThinkPHP5数据库迁移工具 migration (原文链接)

什么是Migration?

migration用谷歌翻译是移民的意思,在PHP中我们将它理解为迁移,将Migration用在数据库上就理解为数据库迁移咯。在migration开发之前,我们都是手写SQL创建表语句,创建成功之后需要手动在数据库执行,项目初始化光数据库的创建就花费很多时间。

另外在多人团队开发中,如果要求每个开发人员都在本地使用数据库那么我们通常都是将数据库备份成SQL文件互相传递,这还并不是很繁琐,繁琐的在于如果数据库某个表的字段出现变动那么就需要将这个变动的SQL语句传给每个开发小伙伴让他们在本地都手动的更新下,一次可以这样,但是多次呢?我想在开发团队中这种事情肯定让人头疼咯,所以migration就诞生咯。

Migration就是一些管理数据库结构的文件,这些文件其实都是抽象化的SQL,可以通过命令行执行而改变数据库的结构,这些文件都是存放在项目下的,随着项目版本的迭代而迭代。

在开发过程中,如果一位小伙伴改动了数据库的表结构,她只需要生成一个migration文件并推送到版本控制系统中,如:Git,并通知其他小伙伴,其他小伙伴只需要pull然后在命令行执行下migration命令就可以了,简化了传统的数据库变动流程,加快项目的开发。

Migration文件作用

migration 文件的主要作用就是用来管理数据库的结构,其实它是一组SQL语句的抽象化,migration 文件可以创建表,删除表,增加字段,删除字段等等基本上所有的数据库操作,其实这就像你自己手动写SQL语句一样,只不过在 migration 中你不需要手动的写SQL语句,只需要按照它的规则语法调用一下就可以啦。

migrate 命令介绍

  • migrate:breakpoint 管理断点
  • migrate:create 创建一个迁移文件
  • migrate:rollback 回滚最后一个或特定的迁移
  • migrate:run 迁移数据库
  • migrate:status 显示迁移状态

Thinkphp5.1 使用 migration

thinkphp5 为开发者提供了一整套的 migration 解决方案,不过默认情况下 migration 是没有安装的,需要我们手动安装。将工作目录切换到tp5项目下,执行:

composer require topthink/think-migration v2.0.3


默认安装的TP6版本,这里指定安装tp5.1 的版本为V2.0.3,更多版本地址:​​https://packagist.org/packages/topthink/think-migration​

执行​​php think​​命令查看是否安装成功

ThinkPHP5数据库迁移工具 migration(转)_字段

 

 

 

从图中我们可以看到 migration 和 seed ,表示安装成功了

create 命令

语法格式:​​php think migrate:create TableName​

​TableName​​ 格式:首字母大写的驼峰法。该命令是用来创建一个 migration 文件,比如这里我们创建一个 ​​Video​​ 的 migration 文件:

php think migrate:create Video


第一次执行 Migraton 它会提示一些信息,这里全部统一 yes 就可以啦。创建成功如下:

# php think migrate:create Video
PHP Warning: Module 'redis' already loaded in Unknown on line 0
Create migrations directory? [y]/n (yes/no) [yes]:
> yes

created ./database/migrations/20190804032741_video.php


在项目的根目录下多了一个 database 目录,有一个migration文件夹,该文件夹就是用来存放 migration文件,打开可以看到我们刚才创建的 Video 的 migration 文件:

文件格式命名规则:​​时间 + 随机数 + _ + 文件名​

文件创建好之后,来看下它的内容:

<?php

use think\migration\Migrator;
use think\migration\db\Column;

class Video 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()
{

}
}


这里我需要给我上面创建的 Video 文件增加字段

​Video​​ 表结构如下


字段

类型

说明

id

int

主键

nickname

varchar(16)

视频名称

email

varchar(32)

邮箱

password

varchar64)

密码


删除默认自带的 ​​change​​ 方法,创建 ​​up()​​ 方法和 ​​down()​​ 方法。​​up()​​ 方法是在执行 ​​run​​ 命令执行的,​​down()​​ 是在执行 ​​rollback​​ 命令执行的。

​up()​​ 方法如下 :

public function up()
{
$table = $this->table('video');
$table->addColumn('name', 'string', ['limit' => 16, 'null' => false,'comment'=>'视频名称'])
->addColumn('email', 'string', ['limit' => 32, 'null' => false,'comment'=>'邮箱'])
->addColumn('password', 'string', ['limit' => 64, 'null' => false,'comment'=>'密码'])
->create();
}


​down()​​ 方法如下:

public function down()
{
$this->dropTable('video');
}


文件整体内容

<?php

use think\migration\Migrator;
use think\migration\db\Column;

class Video extends Migrator
{
// migrate:run 时执行
public function up()
{
$table = $this->table('video');
$table->addColumn('name', 'string', ['limit' => 16, 'null' => false,'comment'=>'名称'])
->addColumn('email', 'string', ['limit' => 32, 'null' => false,'comment'=>'邮箱'])
->addColumn('password', 'string', ['limit' => 64, 'null' => false,'comment'=>'密码'])
->create();
}

// migrate:rollback 时执行
public function down()
{
$this->dropTable('video');
}
}


这样,一个可以创建 video 表的 migration 文件就创建完毕了,接下来,来学习下一个命令。

migrate:run 命令

migration 文件创建完毕,还需要执行 ​​run​​ 命令才可以修改数据库:

注意,执行此步骤之前请正确配置了 ​​config/database.php​​ 。 在这里的数据库是有前缀的​​iot_​​。

php think migrate:run


执行成功之后,查看数据库,多了两个表​​iot_migrations​​和​​iot_video​

​iot_video​​表结构如下

mysql> desc iot_video;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(16) | NO | | NULL | |
| email | varchar(32) | NO | | NULL | |
| password | varchar(64) | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.07 sec)


之前我定义了 migration 只指定了 ​​nickname​​, ​​email​​, ​​password​​ 三个字段,但是执行 ​​run​​ 命令创建的表中有四个字段,多了一个 ​​id​​ 主键?这是 ​​thinkphp5​​ 为我们默认添加的!小伙伴注意啦!如果你的主键字段名为 ​​id​​ 就不需要自己手动的指定了。

​iot_video​​设计表结构查看注释

​iot_migrations​​表中的内容是什么?

mysql> select * from iot_migrations G;
+----------------+----------------+---------------------+---------------------+------------+
| version | migration_name | start_time | end_time | breakpoint |
+----------------+----------------+---------------------+---------------------+------------+
| 20190804032741 | Video | 2019-08-04 11:49:49 | 2019-08-04 11:49:50 | 0 |
+----------------+----------------+---------------------+---------------------+------------+
1 row in set (0.08 sec)


可以看出是刚才执行run命名成功后的一条记录,版本20190804032741是和文件名一一对应的

migrate:status 命令

说明:显示迁移状态

# php think migrate:status
Status Migration ID Started Finished Migration Name
----------------------------------------------------------------------------------
up 20190804032741 2019-08-04 11:49:49 2019-08-04 11:49:50 Video


列表的形式展示了 migration 的执行情况

migrate:roolback 命令

说明:回滚最后一个或特定的迁移

语法:​​php think migrate:rollback​

# php think migrate:rollback --help
Help:
The migrate:rollback command reverts the last migration, or optionally up to a specific version

php console migrate:rollback
php console migrate:rollback -t 20111018185412 //指定版本
php console migrate:rollback -d 20111018
php console migrate:rollback -v


执行回滚操作

# php think migrate:rollback
PHP Warning: Module 'redis' already loaded in Unknown on line 0

== 20190804032741 Video: reverting
== 20190804032741 Video: reverted 0.1992s

All Done. Took 0.6151s


这时候查看数据库和表结构,数据库表已经被删除,不存在了

mysql> desc iot_video;
1146 - Table 'iot.tinywan.com.iot_video' doesn't exist
mysql> select * from iot_migrations;
Empty set


iot_migrations 表中的数据也不存在,一并 删除了

新增表字段

对表进行二次操作,不能在同一个脚本中二次编辑,只能新建脚本。

下面给表​​iot_video​​增加新字段,重新生成表结构

​Video​​ 表增加字段如下


字段

类型

说明

upload_time

int(11)

上传时间

user_id

int(11)

上传用户ID


创建新脚本

# php think migrate:create Video2
created ./database/migrations/20190804082737_video2.php


Video2 文件内容

<?php

use think\migration\Migrator;

class Video2 extends Migrator
{
public function up()
{
$table = $this->table('video');
$table->addColumn('upload_time', 'string', ['limit' => 11, 'null' => false,'comment'=>'上传时间'])
->addColumn('user_id', 'string', ['limit' => 11, 'null' => false,'comment'=>'上传用户ID'])
->save();
}
}


数据迁移

# php think migrate:run

== 20190804082737 Video2: migrating
== 20190804082737 Video2: migrated 0.3345s

All Done. Took 0.7070s


查看表结构

mysql> desc iot_video;
+-------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(16) | NO | | NULL | |
| email | varchar(32) | NO | | NULL | |
| password | varchar(64) | NO | | NULL | |
| upload_time | varchar(11) | NO | | NULL | |
| user_id | varchar(11) | NO | | NULL | |
+-------------+-------------+------+-----+---------+----------------+
6 rows in set (0.08 sec)


附录

表的方法


方法 名

描述

setId(string $id)

设置主键字段名

setPrimaryKey(string $key)

设置主键

setEngine(string $engine)

设置存储引擎,有:InnoDB,MyISAM

setComment(string $comment)

设置表注释

addTimestamps(string ????????????????????????????????????????????????,????????????????????????createAtName,stringupdateAtName)

给表加上创建时间和编辑时间两个字段,默认字段名是:create_time,update_time

addColumn(????????????????????????????????????????,columnName,type, $options)

给表增加一个字段

changeColumn(????????????????????????????????????????,columnName,newType, $options)

改变表的某一个字段的属性

create()

创建表

save()

保存表

rename($newTableName)

重命名表名

hasTable($tableName) | exists()

判断表是否存在

setIndexes(array $indexs)

批量设置索引

drop()

删除当前表

setForeignKeys(array $foreignKeys)

设置外键

removeColumn($columnName)

删除字段

renameColumn(????????????????????????????,oldName,newName)

字段重命名

insert(array $data)

插入数据


列类型


类型

​biginteger​

​binary​

​boolean​

​date​

​datetime​

​decimal​

​float​

​integer​

​string​

​text​

​time​

​timestamp​

​uuid​


可选参数


参数

说明

​limit​

长度限制,整数

​length​

同 ​​limit​​,整数

​default​

默认值,mixed

​null​

是否可空,bool

​after​

在哪个字段后

​comment​

注释


下面是针对 decimal 类型:


参数

说明

​precision​

长度,整数

​scale​

小数位长度,整数

​signed​

是否无符号,bool


下面是针对 enum 和 set 类型:


参数

说明

​values​

默认值

 


 数据填充示例

php think seed:create Users

编辑文件

public function run()

{

$data[] = [

'username' => 111,

'password' => 'dadsadsa',

];

$this->table('users')->insert($data)->save();

}

数据填充

php think seed:run




ThinkPHP5数据库迁移工具 migration(转)_字段_02



作者:Tinywan