微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PHP版Mysql数据库表结构差异性对比工具-数据库升级工具

此工具用于对比MysqL一个数据库的结构,可以对比出与另一个库的差异性。并能生成相关的sql语句。 

PS:主要完成了表结构中的字段名的差异性对比、索引差异性对比。

实现代码

<?PHP

/**

 * 数据库差异对比工具

 * 

 * @author 朱华<[email protected]>

 * @copyright www.joy999.com

 * @version v1.3

 */ 

 header(Content-Type: text/html;charset=utf-8);

?>

<html>

<title>数据库结构异同对比器</title>

<body>

<form method="POST">

<h3>源数据库信息(以此为母版):</h3>

主机:<input type="text" name="host1" value="<?PHP echo $_REQUEST[host1]?>"><br>

用户名:<input type="text" name="user1" value="<?PHP echo $_REQUEST[user1]?>"><br>

密码:<input type="password" name="pwd1" value="<?PHP echo $_REQUEST[pwd1]?>"><br>

库名:<input type="text" name="db1" value="<?PHP echo $_REQUEST[db1]?>"><br>

<h3>目标数据库信息(待更新的):</h3>

主机:<input type="text" name="host2" value="<?PHP echo $_REQUEST[host2]?>"><br>

用户名:<input type="text" name="user2" value="<?PHP echo $_REQUEST[user2]?>"><br>

密码:<input type="password" name="pwd2" value="<?PHP echo $_REQUEST[pwd2]?>"><br>

库名:<input type="text" name="db2" value="<?PHP echo $_REQUEST[db2]?>"><br>

<input type="submit" value="提交">

<input type="reset" value="重置">

<p><input type="checkBox" name="exec" value="1" <?PHP echo ( $_REQUEST[exec] == 1 ) ? checked : ?> >执行sql更新操作</p>

</form>

<?PHP

/**

* 数据库结构检查

*

*/

function getDB( $dbnum )

{

static $link = null;

if ( $link ) {

MysqL_close( $link );

$link = null;

}

$link = MysqL_connect( $_REQUEST[host . $dbnum ],$_REQUEST[user . $dbnum ],$_REQUEST[pwd . $dbnum ] )

or die( 数据库 . $dbnum . 连接失败!);

MysqL_select_db( $_REQUEST[db . $dbnum ],$link )

or die(数据库 . $dbnum . 选择失败 . MysqL_error() );

MysqL_query( set names "utf8";,$link )

or die(数据库 . $dbnum . 设置编码失败);

return array(dbnum=>$dbnum,link => $link );

}

function Query( $sql,$link = null )

{

if ( ! is_resource( $link[link] ) || ! @MysqL_ping( $link[link] ) ) {

$link = getDB( $link[dbnum] );

}

$ret = MysqL_query( $sql,$link[link] );

if ( ! $ret ) {

if ( MysqL_errno($link[link] ) == 2013 ) { //Lost Connect错误出现时重新进行数据库连接

$link = getDB( $link[dbnum] );

return Query( $sql,$link );

}

}

return $ret;

}

if ( ! isset( $_REQUEST[host1] ) || ! isset( $_REQUEST[host2] ) ) {

echo </form></body></html>;

exit;

}

echo <hr>;

set_time_limit( 0 );

//ignore_user_abort( true );

ob_implicit_flush( true );

//MysqL_select_db( $_REQUEST[db1],$link1 )

// or die( 数据库1 选择失败!);

//MysqL_select_db( $_REQUEST[db2],$link2 )

// or die( 数据库2 选择失败!);

$ts = array();

$tStruct = array();

$tCreate = array();

$tIndex = array();

foreach( array( $_REQUEST[db1] => 1,$_REQUEST[db2] => 2 ) as $db => $linkNo ) {

$link = getDB( $linkNo );

//查询表结构

$m = Query( show tables,$link )

or die ( $db . :show tables 执行失败!);

while( $r = MysqL_fetch_array( $m ) ) {

$tn = $r[0];

$rm = Query( show full columns from ` . $tn . `,$link )

or die( 失败! . $db . :show full columns from ` . $tn . ` );

while( $v = MysqL_fetch_assoc( $rm ) ) {

$ts[$db][$tn][] = $v[Field];

$tStruct[$db][$tn][$v[Field]] = $v;

}

if ( $db == $_REQUEST[db1] ) {

$rm = Query( show create table ` . $tn . `,$link )

or die( 失败! . $db . :show create table ` . $tn . ` );

$v = MysqL_fetch_array( $rm );

$tCreate[$v[0]] = $v[1] ;

}

//查询表结构

$rm = Query( SHOW INDEX FROM ` . $tn . `,$link )

or die( 失败! . $db . <br />ERROR: . MysqL_error() . <br />ENO: . MysqL_errno() . <br />SHOW INDEX FROM ` . $tn . ` );;

$t = array();

while( $v = MysqL_fetch_assoc( $rm ) ) {

if ( $v[Key_name] == PRIMARY ) {

//主键

$t[key][$v[Key_name]][] = $v[Column_name];

continue;

}

if ( $v[Non_unique] == 1 ) {

//索引

if ( $v[Index_type] == FULLTEXT ) {

//全文索引

$t[fulltext][$v[Key_name]][] = $v[Column_name];

} else {

//一般索引

$t[index][$v[Key_name]][] = $v[Column_name];

}

} else {

//唯一

$t[uni][$v[Key_name]][] = $v[Column_name];

}

}

// if ( $tn == access_log) {

// var_dump( $t );

// }

foreach( $t as $type => $ta ) {

foreach( $ta as $kn => $ka ) {

sort( $ka );

// var_dump( $ka );

$tmp = implode( `,`,$ka );

if ( ! empty( $tmp ) ) {

$tmp = ` . $tmp . ` ;

}

$ta[$kn] = $tmp;

}

$t[$type] = $ta;

}

$tIndex[$db][$tn] = $t;

}

}

$sql = array();

$msg = array();

$skipCheckIndex = array();

if ( is_array( $ts[$_REQUEST[db1]] ) ) foreach( $ts[$_REQUEST[db1]] as $tn => $tbs ) {

if ( ! isset( $ts[$_REQUEST[db2]][$tn] ) ) {

//创建新表

$sql[] = $tCreate[$tn];

}

$last = 首;

foreach( $tbs as $v ) {

if ( ! isset( $ts[$_REQUEST[db2]][$tn] ) ) {

$msg[$tn][] = 新添(表添加) . $v . 于 . $last . 之后;

$last = $v;

$skipCheckIndex[$tn] = 1;

continue;

}

$fieldUpdateMethod = ;

if ( ! in_array( $v,$ts[$_REQUEST[db2]][$tn] ) ) {

//新添字段

$msg[$tn][] = 新添 . $v . 于 . $last . 之后;

$fieldUpdateMethod = ADD;

} else {

//更新字段

if ( $tStruct[$_REQUEST[db2]][$tn][$v] != $tStruct[$_REQUEST[db1]][$tn][$v] ) {

$msg[$tn][] = 更新 . $v . 于 . $last . 之后;

$fieldUpdateMethod = CHANGE ` . $v . ` ;

}

}

if ( $fieldUpdateMethod ) {

$T = $tStruct[$_REQUEST[db1]][$tn];

$tt = $T[$v];

$tsql = alter table ` . $tn .` . $fieldUpdateMethod . ` . $v .` . $tt[Type] . ;

if ( $tt[Null] == NO ) {

$tsql .= NOT NULL ;

}

$tsql .= . $tt[Extra] . ;

if ( $tt[Default] != ) {

if ( $tt[Default] == CURRENT_TIMESTAMP ) {

$tsql .= default CURRENT_TIMESTAMP ;

} else {

$tsql .= default . addslashes( $tt[Default] ) . ;

}

}

$tsql .= COMMENT . MysqL_escape_string( $tt[Comment] ) . ;

if ( $last == 首 ) {

$tsql .= FirsT ;

} else {

if ( in_array( $last,$ts[$_REQUEST[db2]][$tn] ) ) {

$tsql .= AFTER ` . $last . `;

}

}

//由最后进行统一的索引更新,所以此处将注释掉

if ( ! empty( $tt[Extra] ) ) {

if ( $tt[Key] == PRI ) {

//主键,需要先放弃之前的主键,再重新创建

$tsql .=,DROP PRIMARY KEY ;

//查询当前的所有主键的字段名

$tsql .=,ADD PRIMARY KEY ( ;

foreach( $T as $tName => $vv ) {

$priKey = array();

if ( $vv[Key] == PRI ) {

$priKey[] = ` . $tName . `;

}

$tsql .= implode(,$priKey );

}

$tsql .= ) ;

}

if ( $tt[Key] == MUL ) {

//索引

$tsql .=,ADD INDEX ( . $v . );

}

if ( $tt[Key] == UNI ) {

//索一

$tsql .=,ADD UNIQUE ( . $v . );

}

}

$sql[] = $tsql;

}

$last = $v;

}

}

if ( is_array( $ts[$_REQUEST[db2]] ) ) foreach( $ts[$_REQUEST[db2]] as $tn => $tbs ) {

if ( ! isset( $ts[$_REQUEST[db1]][$tn]) ) {

//表不存在,drop表

$msg[$tn][] = 删除(表删除) . $tn;

$sql[] = drop table ` . $tn . `;

$skipCheckIndex[$tn] = 1;

continue;

}

foreach( $tbs as $v ) {

if ( ! in_array( $v,(array) $ts[$_REQUEST[db1]][$tn] ) ) {

$msg[$tn][] = 删除 . $v;

$sql[] = alter table ` . $tn . ` drop column ` . $v . `;

}

}

}

$typeMap = array(

key => 主键,

index => 索引,

uni => 唯一,

fulltext => 全文索引,

);

//这里开始进行索引比对

echo <hr><h2>数据库的索引对比</h2>;

$indexmsg = array();

foreach( $tIndex[$_REQUEST[db2]] as $tableName => $indexs ) {

$str = ;

foreach( $indexs as $type => $arr ) {

foreach( $arr as $iName => $iVal ) {

if ( isset( $tIndex[$_REQUEST[db1]][$tableName][$type][$iName] ) ) {

$srcVal = $tIndex[$_REQUEST[db1]][$tableName][$type][$iName];

if ( $srcVal == $iVal || isset( $skipCheckIndex[$tableName]) ) { //值相等或是新添加、待删除的表,则不作索引检查

//相等,跳过

continue;

} else {

//不相等,重新生成

$msg[$tableName][] = <li> . $typeMap[$type] . [ . $iName . : . $iVal . ] 异同;

//删除原来的索引

switch( $type ) {

case key :

$sql[] = ALTER TABLE `. $tableName . ` DROP PRIMARY KEY ;

$sql[] = ALTER TABLE ` . $tableName . ` ADD PRIMARY KEY ( . $srcVal . );

break;

case index :

$sql[] = ALTER TABLE `. $tableName . ` DROP INDEX ` . $iName .`;

$sql[] = ALTER TABLE ` . $tableName . ` ADD INDEX ` . $iName .` ( . $srcVal . );

break;

case uni :

$sql[] = ALTER TABLE `. $tableName . ` DROP INDEX ` . $iName .`;

$sql[] = ALTER TABLE ` . $tableName . ` ADD UNIQUE ` . $iName .` ( . $srcVal . );

break;

case fulltext :

$sql[] = ALTER TABLE `. $tableName . ` DROP INDEX ` . $iName .`;

$sql[] = ALTER TABLE ` . $tableName . ` ADD FULLTEXT ` . $iName .` ( . $srcVal . );

break;

}

}

} else {

//不存在此键,删除

$msg[$tableName][] = <li>. $typeMap[$type] . [ . $iName . : . $iVal . ] 需要删除;

switch( $type ) {

case key :

$sql[] = ALTER TABLE `. $tableName . ` DROP PRIMARY KEY ;

break;

case index :

case uni :

case fulltext :

$sql[] = ALTER TABLE `. $tableName . ` DROP INDEX ` . $iName .`;

break;

}

}

}

}

}

foreach( $tIndex[$_REQUEST[db1]] as $tableName => $indexs ) {

foreach( $indexs as $type => $arr ) {

foreach( $arr as $iName => $iVal ) {

if ( isset( $tIndex[$_REQUEST[db2]][$tableName][$type][$iName] ) ) {

} else {

//不存在此键,需要添加

$msg[$tableName][] = <li>. $typeMap[$type] . [ . $iName . : . $iVal . ] 需要添加;

if ( ! isset( $skipCheckIndex[$tableName]) ) {

switch( $type ) {

case key :

$sql[] = ALTER TABLE ` . $tableName . ` ADD PRIMARY KEY ( . $iVal . );

break;

case index :

$sql[] = ALTER TABLE ` . $tableName . ` ADD INDEX ` . $iName .` ( . $iVal . );

break;

case uni :

$sql[] = ALTER TABLE ` . $tableName . ` ADD UNIQUE ` . $iName .` ( . $iVal . );

break;

case fulltext :

$sql[] = ALTER TABLE ` . $tableName . ` ADD FULLTEXT ` . $iName .` ( . $iVal . );

break;

}

}

}

}

}

}

//索引比对结束

foreach( $msg as $tn => $arr ) {

echo <hr><p>表名: . $tn . </p><ul>;

if ( !empty( $arr ) ) foreach( $arr as $v ) {

echo <li> . $v . </li>;

} else {

echo <li>没有更新</li>;

}

echo </ul>;

}

if ( ! empty( $sql ) ) {

echo <textarea width:100%;height:500px">;

$result = ;

foreach( $sql as $s ) {

echo htmlspecialchars( $s . ";

" );

// if ( $_REQUEST[exec] == 1 ) {

// echo <p><b>执行:</b> . $s . . ( MysqL_query( $s,$link2 ) ? <font color=green>成功</font> : <font color=red>失败</font> );

// $result .= "</p>

";

// }

}

echo </textarea>;

if ( $_REQUEST[exec] == 1 ) {

$totalsqls = count( $sql );

$link2 = getDB( 2 );

foreach( $sql as $i => $s ) {

echo ===========================完成度: . ( $i + 1 ) . / . $totalsqls .=================================<br />;

echo <p><b>执行:</b> . $s . . ( Query( $s,$link2 ) ? <font color=green>成功</font> : <font color=red>失败</font> );

echo "</p>

";

}

}

?>

<table><tr><td>

<form method="POST">

<input type="hidden" name="exec" value="1">

<input type="hidden" name="host1" value="<?PHP echo $_REQUEST[host1]?>"><br>

<input type="hidden" name="user1" value="<?PHP echo $_REQUEST[user1]?>"><br>

<input type="hidden" name="pwd1" value="<?PHP echo $_REQUEST[pwd1]?>"><br>

<input type="hidden" name="db1" value="<?PHP echo $_REQUEST[db1]?>"><br>

<input type="hidden" name="host2" value="<?PHP echo $_REQUEST[host2]?>"><br>

<input type="hidden" name="user2" value="<?PHP echo $_REQUEST[user2]?>"><br>

<input type="hidden" name="pwd2" value="<?PHP echo $_REQUEST[pwd2]?>"><br>

<input type="hidden" name="db2" value="<?PHP echo $_REQUEST[db2]?>"><br>

<input type="submit" value="执行sql以便更新表结构">

</form>

</td><td>

<form method="POST">

<input type="hidden" name="host1" value="<?PHP echo $_REQUEST[host1]?>"><br>

<input type="hidden" name="user1" value="<?PHP echo $_REQUEST[user1]?>"><br>

<input type="hidden" name="pwd1" value="<?PHP echo $_REQUEST[pwd1]?>"><br>

<input type="hidden" name="db1" value="<?PHP echo $_REQUEST[db1]?>"><br>

<input type="hidden" name="host2" value="<?PHP echo $_REQUEST[host2]?>"><br>

<input type="hidden" name="user2" value="<?PHP echo $_REQUEST[user2]?>"><br>

<input type="hidden" name="pwd2" value="<?PHP echo $_REQUEST[pwd2]?>"><br>

<input type="hidden" name="db2" value="<?PHP echo $_REQUEST[db2]?>"><br>

<input type="submit" value="再次查询(不执行sql)">

</form>

</td></tr></table>

<?PHP

} else {

echo <font color=green>数据库之间没有差异!</font>;

}

?>

</body>

</html>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐