참고: Yii는 버전 1.1.6부터 데이터베이스 마이그레이션 기능만 지원합니다.
소스 코드와 마찬가지로 데이터베이스 기반 애플리케이션을 개발하고 유지 관리함에 따라 데이터베이스 구조가 계속해서 커집니다. 프로덕션 환경에서 특정 열에 인덱스를 추가해야 한다는 것을 깨닫게 될 수 있습니다. 데이터베이스 구조에 대한 이러한 변경 사항(마이그레이션이라고 함)은 소스 코드와 데이터베이스가 동기화되지 않은 경우 작동하는 것만큼 중요합니다. 시스템이 중단될 수 있습니다. 이러한 이유로 Yii 프레임워크는 데이터베이스 마이그레이션 기록을 추적하고, 새로운 마이그레이션을 적용하거나, 이전 마이그레이션을 복원하기 위한 데이터베이스 마이그레이션 도구를 제공합니다.
다음 단계에서는 개발 중에 데이터베이스 마이그레이션을 사용하는 방법을 보여줍니다.
Tim이 새 마이그레이션을 추가합니다(예: 새 테이블 생성)
Tim이 버전 제어 도구(예: SVN, GIT)에 새 마이그레이션을 제출합니다.
Doug가 업데이트하고 버전 제어 도구에서 새 마이그레이션을 가져옵니다.
Doug는 데이터베이스의 로컬 개발 버전에 새로운 마이그레이션을 적용합니다.
Yii 프레임워크는 yiic migration 명령줄 도구를 통해 데이터베이스 마이그레이션을 지원합니다. 이 도구는 새로운 마이그레이션 생성, 마이그레이션 적용/되돌리기/취소 및 마이그레이션 표시를 지원합니다. 과거 및 새로운 마이그레이션.
다음으로 이 도구의 사용 방법을 설명하겠습니다.
참고: 명령줄 마이그레이션 도구를 사용하여 마이그레이션하는 경우 시스템 디렉터리 대신에 응용 프로그램 디렉터리(예: cd 경로/to/protected)에서 yiic를 사용하는 것이 가장 좋습니다. 또한 protected/config/console.php에 데이터베이스 연결이 구성되어 있는지 확인하십시오.
새 마이그레이션을 생성하려면(예: 뉴스 테이블 생성) 다음 명령을 실행할 수 있습니다.
yiic migrate create <name>
매개변수 name은 필수입니다. 이 마이그레이션에 대한 매우 간단한 설명을 지정합니다(예: create_news_table). 아래에서 볼 수 있듯이 name 매개변수는 PHP 클래스 이름의 일부입니다. 그리고 문자, 숫자, 밑줄만 포함할 수 있습니다.
yiic migrate create create_news_table
위 명령은 protected/migrations 경로 아래에 m101129_185401_create_news_table.php라는 새 파일을 생성합니다. 이 파일에는 다음 코드가 포함되어 있습니다.
class m101129_185401_create_news_table extends CDbMigration { public function up(){} public function down() { echo "m101129_185401_create_news_table does not support migration down.\n"; return false; } /* // implement safeUp/safeDown instead if transaction is needed public function safeUp(){} public function safeDown(){} */ }
클래스 이름과 파일 이름을 참고하세요. 둘 다 m
up() 메서드에는 데이터베이스 마이그레이션을 구현하는 코드가 포함되어야 하고, down() 메서드에는 up() 메서드의 작업을 복원하는 코드가 포함되어야 합니다.
때때로 down()에서 작업을 구현하는 것이 불가능합니다. 예를 들어, up() 메소드에서 테이블의 한 행을 삭제한 경우, down 메소드에서는 해당 행을 복원할 수 없습니다. 이 경우 마이그레이션을 되돌릴 수 없다고 하며 이는 데이터베이스의 이전 상태로 롤백할 수 없음을 의미합니다. 위에서 생성된 코드에서 down() 메서드는 false를 반환하여 마이그레이션을 되돌릴 수 없음을 나타냅니다.
정보: 버전 1.1.7부터 up() 또는 down() 메서드가 false를 반환하면 아래의 모든 마이그레이션이 취소됩니다. 버전 1.1.6에서는 다음 마이그레이션을 취소하려면 예외가 발생해야 합니다.
예제를 사용하여 뉴스 테이블 생성 마이그레이션을 보여드리겠습니다.
class m101129_185401_create_news_table extends CDbMigration { public function up() { $this->createTable('tbl_news', array( 'id' => 'pk', 'title' => 'string NOT NULL', 'content' => 'text', )); } public function down() { $this->dropTable('tbl_news'); } }
기본 클래스 CDbMigration은 데이터 및 데이터베이스를 작동하는 일련의 메소드를 제공합니다. 예를 들어 CDbMigration::createTable입니다. 데이터베이스 테이블에 CDbMigration::insert가 데이터 행을 삽입합니다. 이러한 메서드는 모두 CDbMigration::getDbConnection()에서 반환된 데이터베이스 연결을 사용하며 기본값은 Yii::app()->db입니다.
정보: CDbMigration에서 제공하는 데이터베이스 메서드는 CDbCommand의 데이터베이스 메서드와 매우 유사하다는 것을 알 수 있습니다. 실제로 CDbMigration 메서드가 실행하는 데 걸리는 시간을 계산하고 메서드 매개 변수에 대한 일부 정보를 인쇄한다는 점을 제외하면 기본적으로 동일합니다.
다음과 같이 데이터베이스 운영 방법을 확장할 수도 있습니다.
public function up() { $sql = "CREATE TABLE IF NOT EXISTS user( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, username VARCHAR(32) NOT NULL, password VARCHAR(32) NOT NULL, email VARCHAR(32) NOT NULL ) ENGINE=MyISAM"; $this->createTableBySql('user',$sql); } public function createTableBySql($table,$sql){ echo " > create table $table ..."; $time=microtime(true); $this->getDbConnection()->createCommand($sql)->execute(); echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n"; }
정보: 트랜잭션 마이그레이션 기능은 버전 1.1부터 지원됩니다. .7.
복잡한 데이터베이스 마이그레이션에서는 데이터베이스의 일관성과 무결성을 유지하기 위해 모든 마이그레이션의 성공 여부를 확인하려는 경우가 많습니다. 이 목표를 달성하기 위해 데이터베이스 트랜잭션을 사용할 수 있습니다.
데이터베이스 트랜잭션을 명시적으로 활성화하고 다른 데이터베이스 관련 트랜잭션 포함 코드를 첨부할 수 있습니다. 예를 들면 다음과 같습니다.
class m101129_185401_create_news_table extends CDbMigration { public function up() { $transaction=$this->getDbConnection()->beginTransaction(); try { $this->createTable('tbl_news', array( 'id' => 'pk', 'title' => 'string NOT NULL', 'content' => 'text', )); $transaction->commit(); }catch(Exception $e){ echo "Exception: ".$e->getMessage()."\n"; $transaction->rollback(); return false; } } // ...similar code for down() }
그러나 더 간단한 방법은 트랜잭션 지원을 얻는 방법은 up()을 대체하는 safeUp() 메소드와 down()을 대체하는 safeDown() 메소드를 구현하는 것입니다. 예:
class m101129_185401_create_news_table extends CDbMigration { public function safeUp() { $this->createTable('tbl_news', array( 'id' => 'pk', 'title' => 'string NOT NULL', 'content' => 'text', )); } public function safeDown() { $this->dropTable('tbl_news'); } }
Yii가 마이그레이션을 실행하면 데이터베이스 마이그레이션이 활성화되고 그런 다음 safeUp() 또는 safeDown()을 호출합니다. safeUp() 및 safeDown()에서 오류가 발생하면 데이터베이스의 일관성과 무결성을 유지하기 위해 트랜잭션이 롤백됩니다.
참고: 모든 DBMS가 그런 것은 아닙니다. 그리고 일부 DB 쿼리는 트랜잭션에 배치할 수 없습니다. 이 경우 대신 up() 및 down()을 구현해야 합니다. MySQL의 경우 일부 SQL 문이 충돌을 일으킬 수 있습니다.
유효한 새 마이그레이션을 모두 사용하려면(예: 로컬 데이터베이스를 최신 상태로 유지) 다음 명령을 실행하세요.
yiic migrate
这个命令会显示所有新迁移的列表. 如果你确定使用迁移, 它将会在每一个新的迁移类中运行up()方法, 一个接着一个, 按照类名中的时间戳的顺序.
在使用迁移之后, 迁移工具会在一个数据表tbl_migration中写一条记录——允许工具识别应用了哪一个迁移. 如果tbl_migration表不存在 ,工具会在配置文件中db指定的数据库中自动创建。
有时候, 我们可能指向应用一条或者几条迁移. 那么可以运行如下命令:
yiic migrate up 3
这个命令会运行3个新的迁移. 该表value的值3将允许我们改变将要被应用的迁移的数目。
我们还可以通过如下命令迁移数据库到一个指定的版本:
yiic migrate to 101129_185401
也就是我们使用数据库迁移名中的时间戳部分来指定我们想要迁移到的数据库的版本。如果在最后应用的数据库迁移和指定的迁移之间有多个迁移, 所有这些迁移都会被应用. 如果指定迁移已经使用过了, 所有之后应用的迁移都会恢复。
想要恢复最后一个或几个已应用的迁移,我们可以运行如下命令:
yiic migrate down [step]
其中选项 step 参数指定了要恢复的迁移的数目. 默认是1, 意味着恢复最后一个应用的迁移.
正如我们之前所描述的, 不是所有的迁移都能恢复. 尝试恢复这种迁移会抛出异常并停止整个恢复进程。
重做迁移意味着第一次恢复并且之后应用指定的迁移. 这个可以通过如下命令来实现:
yiic migrate redo [step]
其中可选的step参数指定了重做多少个迁移 . 默认是1, 意味着重做最后一个迁移.
除了应用和恢复迁移之外, 迁移工具还可以显示迁移历史和被应用的新迁移。
yiic migrate history [limit] yiic migrate new [limit]
其中可选的参数 limit 指定克显示的迁移的数目。如果limit没有被指定,所有的有效迁移都会被显示。
第一个命令显示已经被应用的迁移, 而第二个命令显示还没被应用的迁移。
有时候, 我们可能想要在没有应用和恢复相应迁移的时候编辑迁移历史来指定迁移版本. 这通常发生在开发一个新的迁移的时候. 我们使用下面的命令来实现这一目标.
yiic migrate mark 101129_185401
这个命令和yiic migrate to命令非常类似, 但它仅仅只是编辑迁移历史表到指定版本而没有应用或者恢复迁移。
有多种方式来自定义迁移命令。
使用命令行选项
迁移命令需要在命令行中指定四个选项:
interactive: boolean, specifies whether to perform migrations in an interactive mode. Defaults to true, meaning the user will be prompted when performing a specific migration. You may set this to false should the migrations be done in a background process. migrationPath: string, specifies the directory storing all migration class files. This must be specified in terms of a path alias, and the corresponding directory must exist. If not specified, it will use the migrations sub-directory under the application base path. migrationTable: string, specifies the name of the database table for storing migration history information. It defaults to tbl_migration. The table structure is version varchar(255) primary key, apply_time integer. connectionID: string, specifies the ID of the database application component. Defaults to 'db'. templateFile: string, specifies the path of the file to be served as the code template for generating the migration classes. This must be specified in terms of a path alias (e.g. application.migrations.template). If not set, an internal template will be used. Inside the template, the token {ClassName} will be replaced with the actual migration class name.
想要指定这些选项, 使用如下格式的迁移命令执行即可:
yiic migrate up --option1=value1 --option2=value2 ...
例如, 如果我们想要迁移一个论坛模块,它的迁移文件都放在模块的迁移文件夹中,可以使用如下命令:
yiic migrate up --migrationPath=ext.forum.migrations
注意在你设置布尔选项如interactive的时候,使用如下方式传入1或者0到命令行:
yiic migrate --interactive=0
配置全局命令
命令行选项允许我们快速配置迁移命令, 但有时候我们可能想要只配置一次命令. 例如, 我们可能想要使用不同的表来保存迁移历史, 或者我们想要使用自定义的迁移模板。我们可以通过编辑控制台应用的配置文件来实现,如下所示:
return array( ...... 'commandMap'=>array( 'migrate'=>array( 'class'=>'system.cli.commands.MigrateCommand', 'migrationPath'=>'application.migrations', 'migrationTable'=>'tbl_migration', 'connectionID'=>'db', 'templateFile'=>'application.migrations.template', ), ...... ), ...... );
现在如果我们运行迁移命令,上述配置将会生效,而不需要我们每一次在命令行中都输入那么多选项信息。
以上就是Yii框架官方指南系列增补版27——使用数据库:数据库迁移的内容,更多相关内容请关注PHP中文网(www.php.cn)!