数据库迁移是将数据库的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
<?phpuse 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
<?phpnamespace 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
<?phpnamespace 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
<?phpnamespace 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';}}
使用案例
<?phpuse 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}}');}}
