Yii 的修行之路 - Migration 数据迁移

简述

数据迁移就是数据库表在团队建的迁移操做,达到团队相互间的信息同步,数据统一。php

数据库迁移

通常步骤:数据库

一、在 yii2 的 migrate 中,一般用来对数据库数据表进行修改操做,主要对结构和小部分数据进行操做(不多会遇到大数据,若是是面对数据量比较大的状况,采用数据表的直接导出导入)。后端

二、本地生成或修改数据库表,后端执行语句: ./yii migrate/create <create_table_name>缓存

三、后端执行 migrate 指令后会生成一个 migrate 脚本,这个脚本里面主要用来存放 SQL语句,也会随着代码发布而上传,以供其余成员同步数据库,实现真正的数据迁移。服务器

四、其余成员拉去最新代码回本地后,执行 ./yii migrate 更新数据迁移状态,把最新的数据迁移同步到本地。yii2

概念

在开发和维护一个数据库驱动的应用程序时,数据库的结构会随代码的改变而改变。app

例如,在开发应用程序的过程当中,会增长一张新表且必须得加进来; 在应用程序被部署到生产环境后,须要创建一个索引来提升查询的性能等等。 由于一个数据库结构发生改变的时候源代码也常常会须要作出改变,Yii 提供了一个 数据库迁移 功能,该功能能够记录数据库的变化, 以便使数据库和源代码一块儿受版本控制。框架

以下的步骤向咱们展现了数据库迁移工具是如何为开发团队所使用的:yii

  1. Tim 建立了一个新的迁移对象(例如,建立一张新的表单,改变字段的定义等)。工具

  2. Tim 将这个新的迁移对象提交到代码管理系统(例如,Git,Mercurial)。

  3. Doug 从代码管理系统当中更新版本并获取到这个新的迁移对象。

  4. Doug 把这个迁移对象提交到本地的开发数据库当中,这样一来,Doug 同步了 Tim 所作的修改。

以下的步骤向咱们展现了如何发布一个附带数据库迁移的新版本到生产环境当中:

  1. Scott 为一个包含数据库迁移的项目版本建立了一个发布标签。

  2. Scott 把发布标签的源代码更新到生产环境的服务器上。

  3. Scott 把全部的增量数据库迁移提交到生产环境数据库当中。

Yii 提供了一整套的迁移命令行工具,经过这些工具你能够:

  • 建立新的迁移(./yii migrate/create 迁移描述);

  • 提交迁移;

  • 恢复迁移;

  • 从新提交迁移;

  • 现实迁移历史和状态。

全部的这些工具均可以经过 yii migrate 命令来进行操做。
注意:迁移不只仅只做用于数据库表,它一样会调整现有的数据来适应新的表单、建立 RBAC 分层、又或者是清除缓存。

建立迁移

使用以下命令来建立一个新的迁移:

yii migrate/create <name>

必填参数 name 的做用是对新的迁移作一个简要的描述。

例如,若是这个迁移是用来建立一个叫作 news 的表单的,那么你可使用create_news_table 这个名称并运行以下命令:

yii migrate/create create_news_table

注意:由于 name 参数会被用来生成迁移的类名的一部分,因此该参数应当只包含字母、数字和下划线。

如上命令将会在 @app/migrations 目录下建立一个新的名为 m150101_185401_create_news_table.php 的 PHP 类文件。

该文件包含以下的代码,它们用来声明一个迁移类 m150101_185401_create_news_table,并附有代码框架:

<?php 
use yii\db\Schema; 
use yii\db\Migration; 
class m150101_185401_create_news_table extends Migration{ 
    public function up() { 
    
    } 
    public function down() { 
        echo "m101129_185401_create_news_table cannot be reverted.\n"; return false; 
    } 
}

每一个数据库迁移都会被定义为一个继承自 yiidbMigration 的 PHP 类。类的名称按照 m<YYMMDD_HHMMSS>_<Name> 的格式自动生成,其中

  • <YYMMDD_HHMMSS> 指执行建立迁移命令的 UTC 时间。

  • <Name> 和你执行命令时所带的 name 参数值相同。

在迁移类当中,你应当在 up() 方法中编写改变数据库结构的代码。你可能还须要在 down() 方法中编写代码来恢复由 up() 方法所作的改变。

当你经过 migration 升级数据库时, up() 方法将会被调用,反之, down() 将会被调用。以下代码展现了如何经过迁移类来建立一张 news 表:

use yii\db\Schema; 
use yii\db\Migration; 
class m150101_185401_create_news_table extends \yii\db\Migration{ 
    public function up() { 
        $this->createTable('news', [ 'id' => Schema::TYPE_PK, 'title' => Schema::TYPE_STRING . ' NOT NULL', 'content' => Schema::TYPE_TEXT, ]); 
    } 
    public function down() { 
        $this->dropTable('news'); 
    } 
}

注意:并非全部迁移都是可恢复的。

例如,若是 up() 方法删除了表中的一行数据,这将没法经过 down() 方法来恢复这条数据。有时候,你也许只是懒得去执行 down() 方法了,由于它在恢复数据库迁移方面并非那么的通用。在这种状况下,你应当在 down() 方法中返回 false 来代表这个 migration 是没法恢复的。

提交迁移

为了将数据库升级到最新的结构,你应该使用以下命令来提交全部新的迁移:

yii migrate

这条命令会列出迄今为止全部未提交的迁移。

若是你肯定你须要提交这些迁移,它将会按照类名当中的时间戳的顺序,一个接着一个的运行每一个新的迁移类里面的 up() 或者是 safeUp() 方法。若是其中任意一个迁移提交失败了,那么这条命令将会退出并中止剩下的那些还未执行的迁移。

对于每个成功提交的迁移,这条命令都会在一个叫作 migration 的数据库表中插入一条包含应用程序成功提交迁移的记录,该记录将帮助迁移工具判断哪些迁移已经提交, 哪些尚未提交。

提示:迁移工具将会自动在数据库当中建立 migration 表,该数据库是在该命令的 yiiconsolecontrollersMigrateController::db 选项当中指定的。默认状况下,是由 db application component 指定的。

有时,你可能只须要提交一个或者少数的几个迁移,你可使用该命令指定须要执行的条数,而不是执行全部的可用迁移。例如,以下命令将会尝试提交前三个可用的迁移:

yii migrate 3

你也能够指定一个特定的迁移,按照以下格式使用 migrate/to 命令来指定数据库应该提交哪个迁移:

yii migrate/to 150101_185401 # using timestamp to specify the migration 使用时间戳来指定迁移 
yii migrate/to "2015-01-01 18:54:01" # using a string that can be parsed by strtotime() 使用一个能够被 strtotime() 解析的字符串 
yii migrate/to m150101_185401_create_news_table # using full name 使用全名 
yii migrate/to 1392853618 # using UNIX timestamp 使用 UNIX 时间戳

若是在指定要提交的迁移前面还有未提交的迁移,那么在执行这个被指定的迁移以前,这些还未提交的迁移会先被提交。

若是被指定提交的迁移在以前已经被提交过,那么在其以后的那些迁移将会被还原。

还原迁移

你可使用以下命令来还原其中一个或多个意见被提交过的迁移:

yii migrate/down # revert the most recently applied migration 还原最近一次提交的迁移 
yii migrate/down 3 # revert the most 3 recently applied migrations 还原最近三次提交的迁移

注意:并非全部的迁移都能被还原。尝试还原这类迁移将可能致使报错甚至是终止全部的还原进程。

重作迁移

重作迁移的意思是先还原指定的迁移,而后再次提交。以下所示:

yii migrate/redo # redo the last applied migration 重作最近一次提交的迁移 
yii migrate/redo 3 # redo the last 3 applied migrations 重作最近三次提交的迁移

注意:若是一个迁移是不能被还原的,那么你将没法对它进行重作。

列出迁移

你可使用以下命令列出那些提交了的或者是还未提交的迁移:

yii migrate/history # 显示最近10次提交的迁移 
yii migrate/history 5 # 显示最近5次提交的迁移 
yii migrate/history all # 显示全部已经提交过的迁移 
yii migrate/new # 显示前10个还未提交的迁移 
yii migrate/new 5 # 显示前5个还未提交的迁移 
yii migrate/new all # 显示全部还未提交的迁移

修改迁移历史

有时候你也许须要简单的标记一下你的数据库已经升级到一个特定的迁移,而不是实际提交或者是还原迁移。这个常常会发生在你手动的改变数据库的一个特定状态,而又不想相应的迁移被重复提交。那么你可使用以下命令来达到目的:

yii migrate/mark 150101_185401 # 使用时间戳来指定迁移 
yii migrate/mark "2015-01-01 18:54:01" # 使用一个能够被 strtotime() 解析的字符串 
yii migrate/mark m150101_185401_create_news_table # 使用全名 
yii migrate/mark 1392853618 # 使用 UNIX 时间戳

该命令将会添加或者删除 migration 表当中的某几行数据来代表数据库已经提交到了指定的某个迁移上。

执行这条命令期间不会有任何的迁移会被提交或还原。

全局配置命令

在运行迁移命令的时候每次都要重复的输入一些一样的参数会很烦人,这时候,你能够选择在应用程序配置当中进行全局配置,一劳永逸:

return [
    'controllerMap' => [
        'migrate' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationTable' => 'backend_migration',
        ],
    ],
];

如上所示配置,在每次运行迁移命令的时候,backend_migration 表将会被用来记录迁移历史。你不再须要经过migrationTable 命令行参数来指定这张历史纪录表了。

迁移多个数据库

默认状况下,迁移将会提交到由 db application component 所定义的同一个数据库当中。若是你须要提交到不一样的数据库,你能够像下面那样指定 db 命令行选项,

yii migrate --db=db2

上面的命令将会把迁移提交到 db2 数据库当中。

偶尔有限时候你须要提交 一些 迁移到一个数据库,而另一些则提交到另外一个数据库。为了达到这个目的,你应该在实现一个迁移类的时候指定须要用到的数据库组件的 ID , 以下所示:

use yii\db\Schema;
use yii\db\Migration;

class m150101_185401_create_news_table extends Migration{
    public function init()
    {
        $this->db = 'db2';
        parent::init();
    }
}

即便你使用 db 命令行选项指定了另一个不一样的数据库,上面的迁移仍是会被提交到 db2 当中。须要注意的是这个时候迁移的历史信息依然会被记录到 db 命令行选项所指定的数据库当中。

若是有多个迁移都使用到了同一个数据库,那么建议你建立一个迁移的基类,里面包含上述的 init() 代码。而后每一个迁移类都继承这个基类就能够了。

提示:除了在 yiidbMigration::db 参数当中进行设置之外,你还能够经过在迁移类中建立新的数据库链接来操做不一样的数据库。而后经过这些链接再使用 DAO 方法 来操做不一样的数据库。

另一个可让你迁移多个数据库的策略是把迁移存放到不一样的目录下,而后你能够经过以下命令分别对不一样的数据库进行迁移:

yii migrate --migrationPath=@app/migrations/db1 --db=db1
yii migrate --migrationPath=@app/migrations/db2 --db=db2
...

第一条命令将会把 @app/migrations/db1 目录下的迁移提交到 db1 数据库当中,第二条命令则会把 @app/migrations/db2 下的迁移提交到 db2 数据库当中,以此类推。

相关文章
相关标签/搜索