数据库迁移是将数据库的sql进行代码式管理,并且提交到git上。
使用sql文件的弊端就是,团队协作开发的时候,数据库的sql文件在不断维护的过程,你想要将缺失的sql在本地补充上,但是面对诸多的sql文件也许根本无法快速的定位到,哪些sql文件是你没有本地执行的。
步骤
创建一个 Migration
php yii migrate create_user_table
编写 Migration 的内容
以 user 表为例
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL COMMENT '账号',
`password` varchar(60) NOT NULL COMMENT '密码',
`auth_key` varchar(40) NOT NULL COMMENT 'auth key用于cookie登录',
`status` tinyint(1) NOT NULL COMMENT '状态 0-正常',
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
使用 Migration 实现sql
<?php
use yii\db\Migration;
/**
* Class m191222_095042_init
*/
class m191222_095042_init extends Migration
{
/**
*
* {@inheritdoc}
*/
public function safeUp ()
{
$tableOptions = null;
if($this->db->driverName === 'mysql')
{
// http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
$tableOptions = 'ENGINE=InnoDB DEFAULT CHARSET=utf8';
}
$this->createTable('{{%user}}', [
'id' => $this->primaryKey(),
'username' => $this->string(30)
->notNull()
->unique()
->comment('账号'),
'password' => $this->string(60)
->notNull()
->comment('密码'),
'auth_key' => $this->string(40)
->notNull()
->comment('auth key用于cookie登录'),
'status' => $this->tinyInteger(1)
->notNull()
->comment('状态 0-正常')
], $tableOptions);
}
/**
*
* {@inheritdoc}
*/
public function safeDown ()
{
$this->dropTable('{{%user}}');
}
}
执行 Migration
就可以将上面的 Migration 执行转为sql在数据库中执行
yii migrate
封装 Migration
数据库一般都是固定的编码,所以将一些公共内容封装起来。
另外 yii2 的 Migration 仅提供了 int 的主键,以及 text,如果需要其他类型作为主键(smallint、tinyint),或者 mediumtext 类型,则需要自己自定义。
而且通过 $this->addPrimaryKey 的方式指定 (smallint、tinyint) 为主键,没有 auto_increment。
Migration
<?php
namespace common\base;
use common\traits\TextTypesTrait;
use common\traits\PrimaryTypesTrait;
/**
* 公共迁移类,增加表的时候指定表的相关属性
*
* @author vogin
*
*/
class Migration extends \yii\db\Migration
{
// 也可以直接 id=>'mediumtext'
use TextTypesTrait, PrimaryTypesTrait;
/**
* 创建引擎innodb的表单
*
* @param string $table
* 表名
* @param array $columns
* 字段
* @param string $tableComment
* 表名注释
*/
public function createInnoDBTable ($table, $columns, $tableComment = '')
{
// 表单的内容
$tableOptions = 'ENGINE=InnoDB DEFAULT CHARSET=utf8';
$this->createTable($table, $columns, $tableOptions);
// 添加表注释
if($tableComment)
{
$this->addCommentOnTable($table, $tableComment);
}
}
}
Traits
TextTypesTrait
<?php
namespace common\traits;
trait TextTypesTrait
{
/**
*
* @return \yii\db\Connection the database connection to be used for schema building.
*/
protected abstract function getDb ();
/**
* Creates a medium text column.
*
* @return \yii\db\ColumnSchemaBuilder the column instance which can be further customized.
*/
public function mediumText ()
{
return $this->getDb()->getSchema()->createColumnSchemaBuilder('mediumtext');
}
/**
* Creates a long text column.
*
* @return \yii\db\ColumnSchemaBuilder the column instance which can be further customized.
*/
public function longText ()
{
return $this->getDb()->getSchema()->createColumnSchemaBuilder('longtext');
}
/**
* Creates a tiny text column.
*
* @return \yii\db\ColumnSchemaBuilder the column instance which can be further customized.
*/
public function tinyText ()
{
return $this->getDb()->getSchema()->createColumnSchemaBuilder('tinytext');
}
}
PrimaryTypesTrait
<?php
namespace common\traits;
trait PrimaryTypesTrait
{
/**
*
* @return \yii\db\Connection the database connection to be used for schema building.
*/
protected abstract function getDb ();
/**
* Creates a medium text column.
*
* @return \yii\db\ColumnSchemaBuilder the column instance which can be further customized.
*/
public function tinyintPrimary ()
{
return 'TINYINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT';
}
/**
* Creates a long text column.
*
* @return \yii\db\ColumnSchemaBuilder the column instance which can be further customized.
*/
public function smallintPrimary ()
{
return 'SMALLINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT';
}
}
使用案例
<?php
use common\base\Migration;
/**
* Handles the creation of table `{{%banner}}`.
*/
class m200916_092357_create_banner_table extends Migration
{
/**
*
* {@inheritdoc}
*/
public function safeUp ()
{
$this->createInnoDBTable('{{%banner}}', [
'id' => $this->smallintPrimary(),
'name' => $this->string(20)
->notNull()
->defaultValue('')
->comment('banner名称'),
'url' => $this->string(100)
->notNull()
->defaultValue('')
->comment('banner链接'),
'sort' => $this->tinyInteger()
->notNull()
->defaultValue(0)
->comment('排序'),
'add_time' => $this->integer()
->notNull()
->comment('添加时间'),
'is_show' => $this->tinyInteger(1)
->notNull()
->defaultValue(1)
->comment('是否显示')
], 'banner表');
}
/**
*
* {@inheritdoc}
*/
public function safeDown ()
{
$this->dropTable('{{%banner}}');
}
}