数据库迁移是将数据库的sql进行代码式管理,并且提交到git上。
使用sql文件的弊端就是,团队协作开发的时候,数据库的sql文件在不断维护的过程,你想要将缺失的sql在本地补充上,但是面对诸多的sql文件也许根本无法快速的定位到,哪些sql文件是你没有本地执行的。

步骤

创建一个 Migration

  1. php yii migrate create_user_table

编写 Migration 的内容

以 user 表为例

  1. CREATE TABLE `user` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `username` varchar(30) NOT NULL COMMENT '账号',
  4. `password` varchar(60) NOT NULL COMMENT '密码',
  5. `auth_key` varchar(40) NOT NULL COMMENT 'auth key用于cookie登录',
  6. `status` tinyint(1) NOT NULL COMMENT '状态 0-正常',
  7. PRIMARY KEY (`id`),
  8. UNIQUE KEY `username` (`username`)
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8

使用 Migration 实现sql

  1. <?php
  2. use yii\db\Migration;
  3. /**
  4. * Class m191222_095042_init
  5. */
  6. class m191222_095042_init extends Migration
  7. {
  8. /**
  9. *
  10. * {@inheritdoc}
  11. */
  12. public function safeUp ()
  13. {
  14. $tableOptions = null;
  15. if($this->db->driverName === 'mysql')
  16. {
  17. // http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
  18. $tableOptions = 'ENGINE=InnoDB DEFAULT CHARSET=utf8';
  19. }
  20. $this->createTable('{{%user}}', [
  21. 'id' => $this->primaryKey(),
  22. 'username' => $this->string(30)
  23. ->notNull()
  24. ->unique()
  25. ->comment('账号'),
  26. 'password' => $this->string(60)
  27. ->notNull()
  28. ->comment('密码'),
  29. 'auth_key' => $this->string(40)
  30. ->notNull()
  31. ->comment('auth key用于cookie登录'),
  32. 'status' => $this->tinyInteger(1)
  33. ->notNull()
  34. ->comment('状态 0-正常')
  35. ], $tableOptions);
  36. }
  37. /**
  38. *
  39. * {@inheritdoc}
  40. */
  41. public function safeDown ()
  42. {
  43. $this->dropTable('{{%user}}');
  44. }
  45. }

执行 Migration

就可以将上面的 Migration 执行转为sql在数据库中执行

  1. yii migrate

封装 Migration

数据库一般都是固定的编码,所以将一些公共内容封装起来。

另外 yii2 的 Migration 仅提供了 int 的主键,以及 text,如果需要其他类型作为主键(smallint、tinyint),或者 mediumtext 类型,则需要自己自定义。

而且通过 $this->addPrimaryKey 的方式指定 (smallint、tinyint) 为主键,没有 auto_increment。

Migration

  1. <?php
  2. namespace common\base;
  3. use common\traits\TextTypesTrait;
  4. use common\traits\PrimaryTypesTrait;
  5. /**
  6. * 公共迁移类,增加表的时候指定表的相关属性
  7. *
  8. * @author vogin
  9. *
  10. */
  11. class Migration extends \yii\db\Migration
  12. {
  13. // 也可以直接 id=>'mediumtext'
  14. use TextTypesTrait, PrimaryTypesTrait;
  15. /**
  16. * 创建引擎innodb的表单
  17. *
  18. * @param string $table
  19. * 表名
  20. * @param array $columns
  21. * 字段
  22. * @param string $tableComment
  23. * 表名注释
  24. */
  25. public function createInnoDBTable ($table, $columns, $tableComment = '')
  26. {
  27. // 表单的内容
  28. $tableOptions = 'ENGINE=InnoDB DEFAULT CHARSET=utf8';
  29. $this->createTable($table, $columns, $tableOptions);
  30. // 添加表注释
  31. if($tableComment)
  32. {
  33. $this->addCommentOnTable($table, $tableComment);
  34. }
  35. }
  36. }

Traits

TextTypesTrait

  1. <?php
  2. namespace common\traits;
  3. trait TextTypesTrait
  4. {
  5. /**
  6. *
  7. * @return \yii\db\Connection the database connection to be used for schema building.
  8. */
  9. protected abstract function getDb ();
  10. /**
  11. * Creates a medium text column.
  12. *
  13. * @return \yii\db\ColumnSchemaBuilder the column instance which can be further customized.
  14. */
  15. public function mediumText ()
  16. {
  17. return $this->getDb()->getSchema()->createColumnSchemaBuilder('mediumtext');
  18. }
  19. /**
  20. * Creates a long text column.
  21. *
  22. * @return \yii\db\ColumnSchemaBuilder the column instance which can be further customized.
  23. */
  24. public function longText ()
  25. {
  26. return $this->getDb()->getSchema()->createColumnSchemaBuilder('longtext');
  27. }
  28. /**
  29. * Creates a tiny text column.
  30. *
  31. * @return \yii\db\ColumnSchemaBuilder the column instance which can be further customized.
  32. */
  33. public function tinyText ()
  34. {
  35. return $this->getDb()->getSchema()->createColumnSchemaBuilder('tinytext');
  36. }
  37. }

PrimaryTypesTrait

  1. <?php
  2. namespace common\traits;
  3. trait PrimaryTypesTrait
  4. {
  5. /**
  6. *
  7. * @return \yii\db\Connection the database connection to be used for schema building.
  8. */
  9. protected abstract function getDb ();
  10. /**
  11. * Creates a medium text column.
  12. *
  13. * @return \yii\db\ColumnSchemaBuilder the column instance which can be further customized.
  14. */
  15. public function tinyintPrimary ()
  16. {
  17. return 'TINYINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT';
  18. }
  19. /**
  20. * Creates a long text column.
  21. *
  22. * @return \yii\db\ColumnSchemaBuilder the column instance which can be further customized.
  23. */
  24. public function smallintPrimary ()
  25. {
  26. return 'SMALLINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT';
  27. }
  28. }

使用案例

  1. <?php
  2. use common\base\Migration;
  3. /**
  4. * Handles the creation of table `{{%banner}}`.
  5. */
  6. class m200916_092357_create_banner_table extends Migration
  7. {
  8. /**
  9. *
  10. * {@inheritdoc}
  11. */
  12. public function safeUp ()
  13. {
  14. $this->createInnoDBTable('{{%banner}}', [
  15. 'id' => $this->smallintPrimary(),
  16. 'name' => $this->string(20)
  17. ->notNull()
  18. ->defaultValue('')
  19. ->comment('banner名称'),
  20. 'url' => $this->string(100)
  21. ->notNull()
  22. ->defaultValue('')
  23. ->comment('banner链接'),
  24. 'sort' => $this->tinyInteger()
  25. ->notNull()
  26. ->defaultValue(0)
  27. ->comment('排序'),
  28. 'add_time' => $this->integer()
  29. ->notNull()
  30. ->comment('添加时间'),
  31. 'is_show' => $this->tinyInteger(1)
  32. ->notNull()
  33. ->defaultValue(1)
  34. ->comment('是否显示')
  35. ], 'banner表');
  36. }
  37. /**
  38. *
  39. * {@inheritdoc}
  40. */
  41. public function safeDown ()
  42. {
  43. $this->dropTable('{{%banner}}');
  44. }
  45. }