mysql数据库字段对比工具php版本

发布于:2018-11-15 14:48     更新于:1970-01-01 08:00

更新商城由于没有数据库更新文件,导致代码文件更新后,访问全是数据库字段或者表缺失的错误

如果一个个表去对照这些字段工作量还是比较大的,所以找了一个php写的对比两个数据库之间表和字段的差异,

然后生成更新的sql文件,一键就更新了。下面是代码

<?php

define("DSN",'mysql:host=127.0.0.1;port=3306;dbname=wx');//gm数据库配置
define("SRC_DB","wx");//现有数据库
define("TARGET_DB","new_wx");//目标数据库
define("USER","root");
define("PASS","root");
define("FILE_NAME","updateSQL.sql");//生成sql文件

//获取数据库结构
//数据库名称,链接,返回所有表,所有表的结构<tableName,<tableName,fields>>,表的属性值
function getDBStructure($db_name,$pdo,&$tables,&$db_stru,&$table_status)
{
    # code...
    //获取SRC_DB 的数据库结构
    $pdo->query("use ".$db_name);
    print_r("<pre>");
    //表属性
    foreach ($pdo->query("show table status") as $key => $value) {
        # code...
        $table_status[$value[0]] = $value;

    }
    //echo PHP_EOL;

    foreach ($pdo->query("show tables") as $key => $value) {
        # code...
        $tables[$key] = $value[0];//表名
        //echo $value[0]."|";
    }
    //echo PHP_EOL;
    foreach ($tables as $key => $name) {
        # code...
        //echo $name .PHP_EOL;
        $table = null;//记得初始化
        foreach ($pdo->query("desc ".$name) as $key => $value) {
            # code...
            $table[$value[0]] = $value; //字段名 ——> 字段属性
            //echo $value[0] ."|";
        }
        //echo PHP_EOL;
        $db_stru[$name] = $table; //表名 -> 表结构
    }

}

//生成创建数据库的sql
// 表名  表结构

function createTableSQl($name,$table)
{
    # code...
    $pri_key =  array();
    $mul_key =  array();
    $sql = "CREATE TABLE `{$name}` (";
    foreach ($table as $key => $value) {
        # code...
        $field = $value[0];//字段名
        $type = $value[1]; //字段类型
        $null = $value[2]; //是否为空 YES NO
        $key = $value[3]; //PRI MUL
        $default = $value[4]; //字段类型 
        $extal = $value[5];//
        $isNUll = "";
        if ($null == "YES") {
            # code...
            $isNUll = "not null";
        }
        //$defaultMsg = $default;
        if (!is_null($default)) {
            # code...
			if($default == '')
			{
				$default = " default ''";
			}else
			{
				$default = " default {$default}";
			}
            
        }

        if ($key == "PRI") {
            # code...
            array_push($pri_key, $field);
        }
        else if ($key == "MUL") {
            # code...
            array_push ($mul_key, $field);
        }

        //拼接字符串
        $row = "`{$field}` {$type} {$isNUll} {$default},";

        $sql = $sql . PHP_EOL . $row  ;
    }

    //添加主键
    if (!empty($pri_key)) {
    # code...

        $sql = $sql . PHP_EOL."PRIMARY KEY (";
        foreach ($pri_key as $v) {
            # code...
            $sql = $sql."`{$v}`,";
        }
        $sql = substr($sql, 0,strlen($sql)-1);
        $sql = $sql . ")," ;
    }
        //拼接主键
    if (!empty($mul_key)) {
        # code...

        foreach ($mul_key as  $v) {
            # code...
            $sql = $sql . PHP_EOL . "key `{$v}` ({$v}),";
        }
    }

    $sql = substr($sql, 0,strlen($sql)-1);//去掉最后一个‘,’

    $sql = $sql . PHP_EOL . ");".PHP_EOL;
    return $sql;
}


//生成update文件
// $fields <tabName,field>
//ALTER TABLE `familyer`  ADD COLUMN   `joinfightdata` blob AFTER `ssfightblob`;
function genUpdateSQL($fields)
{
    $updateSql=null ;
    foreach ($fields as $tab_name => $value) {
        # code...
        foreach ($value as $key => $v) {
            # code...
            $isNUll = "";
            if ($v[2] == "YES") {
                # code...
                $isNUll = "NOT NULL";
            }
            $default = $v[4];
            if (!is_null($default)) {
                # code...
				if($default == '')
				{
					$default = " default ''";
				}else
				{
					$default = " default {$default}";
				}
            }
            $updateSql = $updateSql . "ALTER TABLE `{$tab_name}` ADD COLUMN `{$v[0]}` {$v[1]} {$isNUll} {$default};".PHP_EOL;
        }

        $updateSql = $updateSql.PHP_EOL;
    }
    return $updateSql;
}

//比价数据库结构
//dst_db 有 src_db 没有 返回表字段数组
function cmp($src_db,$dst_db)
{
    $tables =array();//dst有 但是src中没有的表 <tale>
    $fields = array();//表名 -> <字段名,字段属性>
    foreach ($dst_db as $key => $value) {
        # code...
        if ( array_key_exists($key,$src_db) ) {//如果存在比较字段
            # code...
            $tmp = array_diff_key($value,$src_db[$key]);
            if ( !empty($tmp) )  {
                # code...
                $fields[$key]=$tmp;
            }
        }
        else
            array_push($tables,$key);
    }


    return $fields;
}


$pdo = new PDO(DSN, USER, PASS);//创建数据库链接

//源数据库结构
$src_tables= NULL;//表名数组
$src_db = NULL;    //数据库结构 表名->表字段
$src_table_status = NULL; //表属性 name -> 属性
getDBStructure(SRC_DB,$pdo,$src_tables,$src_db,$src_table_status);

//目的数据库结构
$dst_tables =NULL;
$dst_db=null;
$dst_table_status=null;
getDBStructure(TARGET_DB,$pdo,$dst_tables,$dst_db,$dst_table_status);



$cmp_table = array_diff($dst_tables,$src_tables);

$cmp_fields = cmp($src_db,$dst_db);
//print_r($cmp_table);
$text = null;
foreach ($cmp_table as  $value) {
    # code...
    if ( !strchr($value,"pvprankreward") ) {
        # code...
        $text = $text.createTableSQl($value,$dst_db[$value]);
    }

}



$text = $text . genUpdateSQL($cmp_fields);
$myfile = fopen(FILE_NAME,"w");
fwrite($myfile, $text);
fclose($myfile);

//对比数据库结构 返回差异 表
//cmp($dst_db,$src_db);
//对比表结构返回有差异的表

//$str = createTableSQl($src_tables[0],$src_db[$src_tables[0]]);
//$myfile = fopen("SQL.sql","w");
//fwrite($myfile, $str);
//fclose($myfile);
// print_r("<pre>");
//print_r($src_db["pvprankreward170525"]);

//print_r($src_table_status["role"]);

?>

以上代码摘自网络,修复了一些小bug,验证运行后完全可用

阅读 83