サイトの更新、データベーススキーマの更新(MySQL)

問題-サイトの更新(別名「svn up」)に加えて、データベーススキーマの更新-テーブル、インデックスなどの追加が必要です。

SQLデータベースの更新リクエストはリポジトリに保存されます。アプリケーションコードを更新した後、目的のSQLを実行する必要があります。



複雑さ:1)同じSQLを2回実行することは不可能です。 2)特定の順序でクエリを実行する必要があります(作成前にALTER TABLEを実行することはできません)。







どうやって?





1.データベース構造を変更するためのSQLクエリの規制-開発者は、SQLがすべての結果でLIVEサーバーで実行されることを知っています。



2. SQLクエリを使用したファイルの命名規則



0034.users_added_balance_column.sql



実行順序が一意に維持されるようにファイルに番号が付けられます



3. SQLクエリ(テンプレート)を使用した特別なファイル形式が使用されます。



SET @version= 'users_added_balance_column' ;



CREATE TABLE IF NOT EXISTS `dbversions` (`version` varchar (200) NOT NULL ,`dt_applied` datetime default NULL , UNIQUE KEY `version` (`version`)) ENGINE=InnoDB DEFAULT CHARSET=latin1; DROP PROCEDURE IF EXISTS prc_update;

DELIMITER //

CREATE PROCEDURE prc_update(version_to_check VARCHAR (200)) BEGIN SET @isversion=( SELECT `version` FROM `dbversions` WHERE `version`=version_to_check); IF ISNULL(@isversion) THEN

INSERT SQL HERE (BELOW)



ALTER TABLE `user_groups` ADD INDEX ( `userId` );



ALTER TABLE `user_groups`

ADD CONSTRAINT `user_groups_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ;



END , DO NOT INSERT SQL BELOW THIS LINE

INSERT INTO `dbversions` SET `version`=version_to_check, dt_applied=NOW(); SET @echo_string = CONCAT( 'Executed ' , version_to_check);

ELSE SET @echo_string = CONCAT( 'Skipped ' , version_to_check); END IF ; SELECT @echo_string AS '' ;

END //

DELIMITER;

CALL prc_update(@version); DROP PROCEDURE IF EXISTS prc_update; SET @version= NULL ;




* This source code was highlighted with Source Code Highlighter .








つまり、「ヘッダー」と「地下」が常に使用され、実際には、SQLが1回実行されることが保証されます。 ファイルの先頭にラベルが入力されます(ファイル名と一致)。



何が起こっているかの本質:dbversionsテーブルは、実行されたすべてのリクエストのラベルを保存します。 毎回、ストアドプロシージャは、特定のSQLクエリがこのデータベースで起動されているかどうかを確認します。



4.すべてのクエリを自動的に起動するupdatedb.phpスクリプトがあります(各.sqlファイルのストアドプロシージャが原因で実行されなかったクエリのみが実行されます)。



#!/usr/bin/php

<?php



require( dirname(__FILE__). '/../bootstrap_cli.php' );



$dir = dirname(__FILE__);



list($dbName, $dbUser, $dbPassword, $dbHost) = split( '/', Config::$databasesConnections['main']);



if (!empty($dbPassword)) {

$dbPassword_cmdln = '-p'.$dbPassword;

} else {

$dbPassword_cmdln = '';

}



foreach (glob($dir. '/*.sql') as $sqlFile) {



system( "mysql -u {$dbUser} {$dbPassword_cmdln} {$dbName} < {$sqlFile}" );

}




* This source code was highlighted with Source Code Highlighter .








これにより、サーバーの更新(ステージング、ライブ、作業コピー)-svn up、続いてupdatedb.php-を更新することを忘れたり、データベースを壊したりすることを恐れることなく、素早く更新できます。



このような組織のおかげで、アプリケーションは数分でほとんどすべてのマシンに「立ち上がり」ます-データベースダンプは不要です-アプリケーションは完全にリポジトリ(SVN)にあります。



All Articles