PHP系列 | ThinkPHP5数据库迁移工具 migration
了解更多,请关注微信公众号
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
命令查看是否安装成功
从图中我们可以看到 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) | 视频名称 |
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
,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, string $updateAtName) | 给表加上创建时间和编辑时间两个字段,默认字段名是: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系列 | ThinkPHP5数据库迁移工具 migration的更多相关文章
- Map工具系列-02-数据迁移工具使用说明
所有cs端工具集成了一个工具面板 -打开(IE) Map工具系列-01-Map代码生成工具说明 Map工具系列-02-数据迁移工具使用说明 Map工具系列-03-代码生成BySQl工具使用说明 Map ...
- flask-admin章节三:数据库迁移工具 alembic初步使用
1. 概述 基于flask框架构建web,一般会使用sqlchemy(在flask中使用sqlchemy可以参考这里)作为数据库引擎. 这样业务的逻辑就可以做到不跟具体的数据库类型相耦合,具体后端业务 ...
- Sql Server来龙去脉系列之四 数据库和文件
在讨论数据库之前我们先要明白一个问题:什么是数据库? 数据库是若干对象的集合,这些对象用来控制和维护数据.一个经典的数据库实例仅仅包含少量的数据库,但用户一般也不会在一个实例上创建太多 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(2)-数据库访问层的设计Demo
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(2)-数据库访问层的设计Demo ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1)框架搭建 前言:这 ...
- redis系列之数据库与缓存数据一致性解决方案
redis系列之数据库与缓存数据一致性解决方案 数据库与缓存读写模式策略 写完数据库后是否需要马上更新缓存还是直接删除缓存? (1).如果写数据库的值与更新到缓存值是一样的,不需要经过任何的计算,可以 ...
- Flask开发系列之数据库操作
Flask开发系列之数据库操作 Python数据库框架 我们可以在Flask中使用MySQL.Postgres.SQLite.Redis.MongoDB 或者 CouchDB. 还有一些数据库抽象层代 ...
- mycat数据库集群系列之数据库多实例安装
mycat数据库集群系列之数据库多实例安装 最近在梳理数据库集群的相关操作,现在花点时间整理一下关于mysql数据库集群的操作总结,恰好你又在看这一块,供一份参考.本次系列终结大概包括以下内容:多数据 ...
- Code First开发系列之数据库迁移
返回<8天掌握EF的Code First开发>总目录 本篇目录 开启并运行迁移 使用迁移API 应用迁移 给已存在的数据库添加迁移 EF的其他功能 本章小结 自我测试 本系列的源码本人已托 ...
- Flask系列:数据库
这个系列是学习<Flask Web开发:基于Python的Web应用开发实战>的部分笔记 对于用户提交的信息,包括 账号.文章 等,需要能够将这些数据保存下来 持久存储的三种方法: 文件: ...
随机推荐
- zookeeper的安装使用
转载从:https://blog.csdn.net/shenlan211314/article/details/6170717 一.zookeeper 介绍 ZooKeeper 是一个为分布式应用所设 ...
- 宿主机计划任务执行docker相关命令
这个问题拖了好几个月百思不解,或许是由于基础不牢的缘故;百度等等搜索一大篇,还真有人遇到了相似问题 问题:宿主机写好计划任务,是mongodump命令来备份mongo数据库,结果在计划任务里是执行不了 ...
- vue---axios实现数据交互与跨域问题
1. 通过axios实现数据请求 vue.js默认没有提供ajax功能的. 所以使用vue的时候,一般都会使用axios的插件来实现ajax与后端服务器的数据交互. 注意,axios本质上就是java ...
- Class.getDeclaredFields()和Class.getFields()的区别。 Class.getMethods()和Class.getDeclaredMethods()的区别。
package www.cn.extend; /** Animal * 2019/07/04 * @author Administrator * */ public class Animal { pu ...
- 调用office Word Com 组件,提示权限不足处理
最近一直在处理一个项目,项目主要功能与Office-Word 有关,主要涉及到文本内容编辑与样式设置等相关内容.因项目依赖office 相关dll,需要兼容多种Office 版本(office 200 ...
- xpath+多进程爬取八零电子书百合之恋分类下所有小说。
代码 # 需要的库 import requests from lxml import etree from multiprocessing import Pool import os # 请求头 he ...
- 函数式编程之pipeline——很酷有没有
Pipeline pipeline 管道借鉴于Unix Shell的管道操作——把若干个命令串起来,前面命令的输出成为后面命令的输入,如此完成一个流式计算.(注:管道绝对是一个伟大的发明,他的设哲学就 ...
- 如果在使用谷歌的gson的时候,在返回时间类型的数据的时候,
可能会出现在long类型的时间后面多3个0 如下图所示 可以自己创建一个json序列化的类 public class Date2LongSerializer extends JsonSerialize ...
- rocketmq那些事儿之本地调试环境搭建
上一篇文章中我们已经介绍过rocketmq的集群环境搭建,然而在源码的学习中我们还需要进行本地的调试和问题的定位查找,毕竟还是在本地方便些,今天就说一说如何进行源码的本地调试 下载编译 对于rocke ...
- Djiango-建立模型抽象基类
创建一个抽象模型基类 ‘ 然后 ’base_model.py from django.db import models from datetime import date class BaseMode ...