数据库迁移工具是干嘛的?
我们都知道我们写的代码可以用git或者svn进行代码的版本控制,那么数据库有没有版本控制的呢?答案是有的。数据库迁移工具就是用来干这个的
think-migration简介
这是Thinkphp 提供扩展用户数据库的迁移和数据填充的扩展库(也是数据库迁移工具)
think-migration 安装
通过 composer 安装
composer require topthink/think-migration=2.0.*
注意事项,不支持修改文件配置目录
在命令行下运行查看帮助,可以看到新增的命令
php think
migrate
migrate:create Create a new migration
migrate:rollback Rollback the last or to a specific migration
migrate:run Migrate the database
migrate:status Show migration status
optimize
optimize:autoload Optimizes PSR0 and PSR4 packages to be loaded wit
h classmaps too, good for production.
optimize:config Build config and common file cache.
optimize:route Build route cache.
optimize:schema Build database schema cache.
seed
seed:create Create a new database seeder
seed:run Run database seeders
think-migration 的使用
创建迁移类
注意:首字母必须为大写
命令格式如下
php think migrate:create 迁移类名
migrate中的三个方法
up:在migrate:run时执行(前提是文件中不存在change方法)
down:在migrate:rollback时执行(前提是文件中不存在change方法)
change:migrate:run 和migrate:rollback时执行 (如果存在该方法 则不会去执行up 与down)
所以一般在创建完文件类过后删除里面的change方法
一般情况下我一般将migrate文件中的change方法删除,up方法专门放置新增和更新表的操作,down方法放置删除表和删除字段操作
change方法注意事项
迁移类里面的change()方法,主要是用来创建或者更新(修改)表,但是在change()方法内部创建或更新表时,必须使用表create()和update()方法并且使用 change 方法后,up 和 down 方法将被忽略
migrate 的命令
# 执行数据迁移操作,注意执行之前必须配好数据库,也就是database.php
php think migrate:run
//回滚
php thin migrate:rollback -t
使用迁移类在数据库中创建一张表
1.配置数据库
2.创建数据迁移类
例:
php think migrate:create Test
3.数据迁移类中写入要创建表的字段和字段设置
对表的操作的几个方法
更多的使用方法:https://book.cakephp.org/phinx/0/en/migrations.html
#注意:Table API完成以下操作是可逆的,并且将自动被逆转
#migrate插件会自动id为每个表创建一个自动递增的主键列,所以无需自己添加主键
table(创建表)
dropTable (删除表)
renameTable(重命名表)
hasTable (判断表是否存在)
addColumn(添加字段)
renameColumn(重命名字段)
addIndex(添加索引)
addForeignKey(添加外键)
表的array数组参数
| Option | Description |
|---|---|
| comment | set a text comment on the table(表注释) |
| row_format | set the table row format(行格式) |
| engine | define table engine (defaults to InnoDB)(表引擎) |
| collation | define table collation (defaults to utf8_general_ci)(表的排序规则) |
| signed | whether the primary key is signed (defaults to true)(是否将主键设置为无符号,默认为true,也就是有符号) |
字段的array数组参数
For any column type:
对于任意的列,最常用
| Option | Description |
|---|---|
| limit | set maximum length for strings, also hints column types in adapters (see note below)(设置字符串的最大长度) |
| length | alias for limit(设置字符串的最大长度,跟limit一样) |
| default | set default value or action(设置默认值) |
| null | allow NULL values, defaults to false (should not be used with primary keys!) (see note below)(允许“NULL”值,默认为false(不应该与主键一起使用!)) |
| after | specify the column that a new column should be placed after (only applies to MySQL)(指定新列应该放在后面的列) |
| comment | set a text comment on the column(注释) |
For decimal columns:
对于小数
| Option | Description |
|---|---|
| precision | combine with scale set to set decimal accuracy |
| scale | combine with precision to set decimal accuracy |
| signed | enable or disable the unsigned option (only applies to MySQL)
|
For enum and set columns:
用于\' enum \'和\' set \'列
| Option | Description |
|---|---|
| values | Can be a comma separated list or an array of values |
For integer and biginteger columns:
| Option | Description |
|---|---|
| identity | enable or disable automatic incrementing |
| signed | enable or disable the unsigned option (only applies to MySQL)
|
For timestamp columns:
| Option | Description |
|---|---|
| default | set default value (use with CURRENT_TIMESTAMP) |
| update | set an action to be triggered when the row is updated (use with CURRENT_TIMESTAMP) (only applies to MySQL)
|
| timezone | enable or disable the with time zone option for time and timestamp columns (only applies to Postgres)
|
up方法示例
例:
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class Test extends Migrator
{
public function up()
{
// 表名
$table = $this->table(\'Test\',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();
}
}
4.执行数据迁移
执行命令
php think migrate:run
迁移成功后会生成两个表一个是你写入up方法生成的表,一个是migrations表,migrations表用于记录本次操作的记录
更新表字段数据
1.创建修改的的迁移类
php think migrate:create ChangeTest
2.将需要更新的内容写到 change 方法中
#使用up方法也可以
public function change()
{
//表名
$table = $this->table(\'test\');
//修改字段类型,注意修改用的是save方法
$table->changeColumn(\'password\', \'char\', [\'limit\' => 50])
->addColumn(\'test_Cloumn\', \'varchar\', array(\'limit\' => 32, \'default\' => \'\'))
->save();
}
3.执行数据迁移操作
自动会执行最近一次创建的数据迁移了
php think migrate:run
而且这时候你打开migrations会发现多了一条操作记录
执行回滚
执行 migrate:rollback 功能会调用down 方法
1.创建回退数据迁移类
php think migrate:create Back
2.写down()方法
public function down(){
$this->dropTable(\'test2\');
}
3.执行回退
#默认执行最新的数据迁移类的down里面的方法
php think migrate:rollback
#php think migrate:rollback -t 回滚到指定的版本
例:php think migrate:rollback -t 20200531080828
seed数据填充
1.创建seed
$ php think seed:create AddTest
2.编辑seed文件的run()方法
public function run()
{
$data = [
[
\'username\' => \'testUesr1\',
\'password\' => \'11111\',
\'login_status\' => 0,
],
[
\'username\' => \'testUesr2\',
\'password\' => \'11111\',
\'login_status\' => 0,
],
];
$this->table(\'test2\')->insert($data)->save();
}
}
3. 开始进行数据库填充
$ php think seed:run
结果如下
可指定一个或多个 seed
$ php think seed:run -s Third
$ php think seed:run -s Third -s member
使用假数据生成器
参考 fzaninotto/faker:https://packagist.org/packages/fzaninotto/faker
安装 faker 类库
$ composer require fzaninotto/faker
使用 faker 生成数据
public function run()
{
$faker = Faker\Factory::create(\'zh_CN\');//选择中文库
$data = [];
for ($i = 0; $i < 100; $i++) {
$data[] = [
\'member_id\' => $faker->randomDigit,
\'thirdid\' => $faker->randomDigit,
\'platform\' => $faker->word,
\'openid\' => sha1($faker->password),
\'content\' => $faker->realText(50),
];
}
$this->table(\'third\')->insert($data)->save();
}
结果如下:
insert方式数据填充
除了上面的seed数据填充方式,就是insert()方式,这种方式一般在数据直接将要插入的数据放在数据迁移类中
如:
$table->insert([
\'uid\'=>1,
\'group_id\'=>1
]);
$table->save();
php 7.4.5 执行创建迁移类报错的问题
http://www.thinkphp.cn/bug/5056.html
执行 :
php think migrate:create Admin
报错:
[think\exception\ErrorException]
implode(): Passing glue string after array is deprecated. Swap the parameters
解决办法
找到下面路径的文件
vendor/topthink/think-migration/phinx/src/Phinx/Util/Util.php
搜索implode
将 implode($arr, \'_\') 这个修改为 implode(\'_\',$arr)
再次执行
php think migrate:create Admin
就没问题了
实际使用Demo
安装
composer require topthink/think-migration=2.0.*
创建迁移类
注意:首字母必须为大写
命令格式如下
php think migrate:create 迁移类名
例:
php think migrate:create Admin
php think migrate:create User
生成的文件位置如
写入管理员表和用户表的字段信息和数据
找到刚才用命令生成的两个迁移类文件,在change方法中写入你要生成的字段信息和数据
20201022090610_admin.php
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class Admin extends Migrator
{
public function change()
{
$table = $this->table(\'admin\');
$table->addColumn(\'username\', \'string\', [\'limit\'=>50, \'default\'=>\'\', \'comment\'=>\'登陆账号\']);
$table->addColumn(\'nickname\', \'string\', [\'limit\'=>50, \'default\'=>\'\', \'comment\'=>\'昵称\']);
$table->addColumn(\'mobile\', \'string\', [\'limit\'=>11, \'default\'=>\'\', \'comment\'=>\'手机号\']);
$table->addColumn(\'password\', \'string\', [\'limit\'=>255, \'default\'=>\'\']);
$table->addColumn(\'avatar\', \'string\', [\'limit\'=>255, \'default\'=>\'\', \'comment\'=>\'头像\']);
$table->addColumn(\'register_ip\', \'string\', [\'limit\'=>20, \'default\'=>\'\', \'comment\'=>\'IP\']);
$table->addColumn(\'login_time\', \'integer\', [\'default\'=>0, \'comment\'=>\'最后登陆时间\']);
$table->addColumn(\'login_ip\', \'string\', [\'default\'=>20, \'comment\'=>\'最后登陆IP\']);
$table->addColumn(\'login_num\', \'integer\', [\'limit\'=>4, \'default\'=>0, \'comment\'=>\'登陆次数\']);
$table->addColumn(\'status\', \'boolean\', [\'default\'=>1, \'comment\'=>\'用户状态(0:禁用,1:开启)\']);
$table->addColumn(\'register_time\', \'integer\', [\'default\'=>0]);
$table->addColumn(\'update_time\', \'integer\', [\'default\'=>0]);
$table->insert([
\'username\'=>\'root\',
\'nickname\'=>\'root\',
\'mobile\'=>\'13000000000\',
\'password\'=>md5(\'123456\'),
\'avatar\'=>\'/uploads/product/2018-11-08/5be3de5c38d63.png\',
\'register_ip\'=>\'127.0.0.1\',
\'login_ip\'=>\'0.0.0.0\',
\'register_time\'=>$_SERVER[\'REQUEST_TIME\']
]);
$table->save();
}
}
20201022090859_user.php
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class User extends Migrator
{
public function change()
{
$table = $this->table(\'user\');
$table->addColumn(\'username\', \'string\', [\'limit\'=>50, \'default\'=>\'\', \'comment\'=>\'登陆账号\']);
$table->addColumn(\'nickname\', \'string\', [\'limit\'=>50, \'default\'=>\'\', \'comment\'=>\'昵称\']);
$table->addColumn(\'mobile\', \'string\', [\'limit\'=>11, \'default\'=>\'\', \'comment\'=>\'手机号\']);
$table->addColumn(\'password\', \'string\', [\'limit\'=>255, \'default\'=>\'\']);
$table->addColumn(\'avatar\', \'string\', [\'limit\'=>255, \'default\'=>\'\', \'comment\'=>\'头像\']);
$table->addColumn(\'register_ip\', \'string\', [\'limit\'=>20, \'default\'=>\'\', \'comment\'=>\'IP\']);
$table->addColumn(\'login_time\', \'integer\', [\'default\'=>0, \'comment\'=>\'最后登陆时间\']);
$table->addColumn(\'login_ip\', \'string\', [\'default\'=>20, \'comment\'=>\'最后登陆IP\']);
$table->addColumn(\'login_num\', \'integer\', [\'limit\'=>4, \'default\'=>0, \'comment\'=>\'登陆次数\']);
$table->addColumn(\'status\', \'boolean\', [\'default\'=>1, \'comment\'=>\'用户状态(0:禁用,1:开启)\']);
$table->addColumn(\'register_time\', \'integer\', [\'default\'=>0]);
$table->addColumn(\'update_time\', \'integer\', [\'default\'=>0]);
$table->insert([
\'username\'=>\'张三\',
\'nickname\'=>\'张三\',
\'mobile\'=>\'13000000000\',
\'password\'=>md5(\'123456\'),
\'avatar\'=>\'/uploads/product/2018-11-08/5be3de5c38d63.png\',
\'register_ip\'=>\'127.0.0.1\',
\'login_ip\'=>\'0.0.0.0\',
\'register_time\'=>$_SERVER[\'REQUEST_TIME\']
]);
$table->save();
}
}
配置好数据库连接
如
执行数据迁移
php think migrate:run
连接数据库,查看效果