Yii自带了一个非常方便的命令行工具,可以帮助我们自动创建数据库维护脚本。使用迁移脚本,我们可以使用svn,git等版本控制工具对数据库的更改进行版本控制,方便团队之间数据库更改的同步,以及开发环境、测试环境、生产环境之间的数据库同步,回退等。这里要插句嘴,就是migration脚本的功能虽然非常实用,但是并非必须步骤,如果你熟悉数据库开发,完全可以直接跳过这步,直接使用sql进行数据库的更新维护,只要保存好sql脚本,使用版本控制做维护其实道理也是一样的。或者你可以直接操作数据库,Yii框架并不依赖migrate脚本才能工作,只要有数据库,链接正常就好。
首先在数据库中创建数据库,
create database blog;
修改common\config\main-local.php中的数据库配置
'components' => [ 'db' => [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=blog', 'username' => 'root', 'password' => '', 'charset' => 'utf8', ], ...
准备工作都做好后,我们就讲讲如何使用migrate命令行工具。我们使用命令行工具cd到yii的项目目录,在windows下就是有yii.bat的根目录,执行命令yii migrate/create <迁移名>
c:\projects\learnyii\blog>yii migrate/create create_admin_table Yii Migration Tool (based on Yii v2.0.8) Create new migration 'C:\projects\learnyii\blog\console/migrations\m160627_032238_create_admin_table.php'? (yes|no) [no]:yes New migration created successfully. c:\projects\learnyii\blog>yii migrate/create create_admin_table
执行完以上代码后我们就可以在console\migrations目录下看到yii为我们自动生成的迁移文件名称按照 m<YYMMDD_HHMMSS>_<Name> 的格式自动生成
打开文件我们可以看到一个Yii为我们自动生成好的类,其中up方法是升级或创建时执行的方法,down是降级回滚时执行的方法。除了up和down,我们还可以把代码都放到 safeUp() 和 safeDown() 方法里面。它们与 up() 和 down() 的不同点就在于它们是被隐式的封装到事务当中的。如此一来,只要这些方法里面的任何一个操作失败了,那么所有之前的操作都会被自动的回滚。
class m160627_032238_create_admin_table extends Migration { public function safeUp() { $this->createTable('admin', [ 'id' => $this->primaryKey(), 'username' => $this->string()->notNull()->unique(), 'auth_key' => $this->string(32)->notNull(), 'password_hash' => $this->string()->notNull(), 'password_reset_token' => $this->string()->unique(), 'email' => $this->string()->unique(), 'wechat_id' => $this->string(100), 'status' => $this->smallInteger()->defaultValue(10), 'created_at' => $this->integer(), 'updated_at' => $this->integer(), ]); //创建默认的管理员账号用户名admin密码123456 $this->insert('admin', [ 'username'=>'admin', 'password_hash'=>'$2y$13$yeCwq5lfMzse3rYGrX2cZOKXTmJ8.945Npt9TO2.nQ8h8xKUUkVua', 'email'=>'lhx880619@163.com', 'wechat_id'=>'8888', 'status'=>10 ]); } /** * @inheritdoc */ public function safeDown() { $this->dropTable('admin'); } }
通过以上步骤我们就为管理员表创建了一个迁移脚本,脚本创建了管理员表,同时创建了一个默认的管理员账号。
同理我们创建文章分类表(category)、文章表(post)、标签表(tag)、文章标签关系表(post_tag)
<span class="redactor-invisible-space">class m160517_025408_create_category_table extends Migration { /** * @inheritdoc */ public function safeUp() { $this->createTable('category', [ 'id' => $this->primaryKey(), 'pid'=> $this->integer(), 'name' => $this->string(200)->notNull(), 'created_at' => $this->datetime(), 'updated_at' => $this->datetime(), 'sort'=> $this->integer()->defaultValue(0), ]); $this->addForeignKey('fk_category_pid', 'category', 'pid', 'category', 'id', 'CASCADE'); $this->insert('category',['name'=>'PHP','sort'=>1]); $this->insert('category',['name'=>'.NET','sort'=>2]); $this->insert('category',['name'=>'DataBase','sort'=>3]); $this->insert('category',['name'=>'前端','sort'=>4]); $this->insert('category',['name'=>'生活随笔','sort'=>5]); } /** * @inheritdoc */ public function safeDown() { $this->dropForeignKey('fk_category_pid','category'); $this->dropTable('category'); } }<span class="redactor-invisible-space"><span class="redactor-invisible-space"></span></span></span>
文章表(post)
<?php use yii\db\Migration; /** * Handles the creation for table `post_table`. */ class m160517_083707_create_post_table extends Migration { /** * @inheritdoc */ public function up() { $this->createTable('post', [ 'id' => $this->primaryKey(), 'title' => $this->string(128)->notNull(), 'lead_photo' => $this->string(500), 'lead_text' => $this->text(), 'content' => $this->text()->notNull(), 'created_at' => $this->datetime(), 'updated_at' => $this->datetime(), 'category_id' => $this->integer()->notNull(), 'view_count'=> $this->integer()->defaultValue(1), 'on_top'=> $this->integer()->defaultValue(0), 'comments_count'=> $this->integer()->defaultValue(0), 'status'=> $this->integer()->defaultValue(0), 'sort'=> $this->integer()->defaultValue(0), ]); $this->addForeignKey('fk_post_category', 'post', 'category_id', 'category', 'id', 'CASCADE'); } public function down() { $this->dropForeignKey('fk_post_category', 'post'); $this->dropTable('post'); } }
标签表(tag)
<?php use yii\db\Migration; /** * Handles the creation for table `tag`. */ class m160524_084946_create_tag_table extends Migration { /** * @inheritdoc */ public function safeUp() { $this->createTable('tag', [ 'id' => $this->primaryKey(), 'name' => $this->string(200)->notNull(), 'created_at' => $this->datetime(), 'updated_at' => $this->datetime(), 'sort'=> $this->integer()->defaultValue(0), ]); $this->insert('tag',['name'=>'YII2','sort'=>1]); $this->insert('tag',['name'=>'MySql','sort'=>2]); $this->insert('tag',['name'=>'Linux','sort'=>3]); $this->insert('tag',['name'=>'Nginx','sort'=>4]); $this->insert('tag',['name'=>'运维','sort'=>5]); $this->insert('tag',['name'=>'测试','sort'=>6]); $this->insert('tag',['name'=>'API','sort'=>7]); $this->insert('tag',['name'=>'REST','sort'=>8]); $this->insert('tag',['name'=>'消息队列','sort'=>9]); } /** * @inheritdoc */ public function safeDown() { $this->dropTable('tag'); } }
文章标签关系表(post_tag)
<?php use yii\db\Migration; /** * Handles the creation for table `post_tag_table`. */ class m160524_085001_create_post_tag_table extends Migration { /** * @inheritdoc */ public function safeUp() { $this->createTable('post_tag', [ 'id' => $this->primaryKey(), 'post_id' => $this->integer()->notNull(), 'tag_id' => $this->integer()->notNull() ]); $this->createIndex('post_tag_index', 'post_tag', ['post_id', 'tag_id']); $this->addForeignKey('fk_post_tag_post', 'post_tag', 'post_id', 'post', 'id', 'CASCADE', 'CASCADE'); $this->addForeignKey('fk_post_tag_tag', 'post_tag', 'tag_id', 'tag', 'id', 'CASCADE', 'CASCADE'); } /** * @inheritdoc */ public function safeDown() { $this->dropForeignKey('fk_post_tag_post', 'post_tag'); $this->dropForeignKey('fk_post_tag_tag', 'post_tag'); $this->dropTable('post_tag'); } }
脚本全部创建完成了之后,我们可以执行命令提交脚本
yii migrate
提交之后还可以回退迁移
yii migrate/down # revert the most recently applied migration 还原最近一次提交的迁移