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 數據庫當中,以此類推。

相關文章
相關標籤/搜索