如何使用PHP同步两个数据库表?

如何使用PHP同步两个数据库表?,php,mysql,synchronization,Php,Mysql,Synchronization,我需要使用PHP将数据从一个MySQL数据库复制到另一个数据库 我可以构建所有值的数组并将其放入另一个数据库中,但首先我要确保在插入之前数据库具有正确的字段 例如,假设我要将数据从表A复制到表B 我可以将tableB设置为类似于tableA,但将来我可能会将列添加到tableA中,而忘记将它们添加到tableB中,然后我的PHP脚本将尝试将数据插入到tableB中不存在的列中,结果会失败 所以我要做的是比较tableA和tableB,tableA中的任何列,tableB中没有的列,将它们添加到t

我需要使用PHP将数据从一个MySQL数据库复制到另一个数据库

我可以构建所有值的数组并将其放入另一个数据库中,但首先我要确保在插入之前数据库具有正确的字段

例如,假设我要将数据从表A复制到表B

我可以将tableB设置为类似于tableA,但将来我可能会将列添加到tableA中,而忘记将它们添加到tableB中,然后我的PHP脚本将尝试将数据插入到tableB中不存在的列中,结果会失败

所以我要做的是比较tableA和tableB,tableA中的任何列,tableB中没有的列,将它们添加到tableB中


有人能告诉我怎么做吗?

您可以编写一个函数,从表中返回列,如下所示:

SHOW COLUMNS FROM «table»
function columns($table) {

    $columns = array();
    $sql = "desc $table";
    $q = mysql_query($sql);

    while ($r = mysql_fetch_array($q)) {

       $columns[] = $r[0];

    }

    return $columns;

}
接下来,您可以比较两个表中的列:

function tables_different($table1, $table2) {

  $cols1 = columns($table1);
  $cols2 = columns($table2);

  return count(array_diff($cols1, $cols2)) ? true : false;

}
现在,您可以将tables_different()函数集成到数据传输脚本中,每次运行它以确保表是相同的


当然,您可以让它更有趣,让它告诉您两个表之间哪些列是不同的,这对同步它们更有用。

这是一项非常复杂的任务,据我所知,到目前为止,许多人都试图解决它(不幸的是,我不知道有任何100%保证的解决方案)

我想说的是,在开始实施您自己的解决方案之前,您应该通过阅读模式演变、模式重构、模式版本控制等内容来了解您将面临的挑战

之后,您可以看一看(本文中还有一些文档)

如果您不局限于PHP,那么您还可以看看它提供了一组高级模式重构

一旦你为你的应用程序获得了一个可靠的模式迁移工具,迁移数据将只是一项微不足道的任务


/alex

我不是100%确定这就是您要找的,但我以前做过一些数据库维护。我们需要一种方法来确保devDB和prodDB在结构上是相同的,我找到了这个漂亮的小工具。该工具将创建一个sql alter脚本,该脚本可以在要修补的数据库上运行。它是用perl编写的,所以我想它应该可以跨平台工作,但我只在linux上尝试过


该工具名为mySQLdiff,是免费软件,可在下载。

最简单的方法可能是

$sql = "SELECT * FROM tableA WHERE 1"

$results = mysql_fetch_assoc($sql);

$sql = "truncate table tableB";

// run truncate

foreach($result as $update){

   $sql = "Insert into table b VALUES(....)"

   // run insert
}
但是在这里你需要非常小心。确保唯一可以写入tableB的进程是从tableA进行复制的进程,否则会丢失数据。此外,还要确保一旦该过程开始,任何东西都不能写入tableA


最好的做法是不要在php中这样做,而是通过mysql复制

您可以查看一些为您提供此功能的PHPClass
谢谢大家,基于大家的帮助,我编写了一个PHP类,可以将表a中的任何列复制到表B中,如果它们还没有:

class MatchTable 
{
    var $_table_one_name;
    var $_table_two_name;

    var $_table_one_db_user;
    var $_table_one_db_pass;
    var $_table_one_db_host;
    var $_table_one_db_name;

    var $_table_two_db_user;
    var $_table_two_db_pass;
    var $_table_two_db_host;
    var $_table_two_db_name;

    var $_table_one_columns = array();
    var $_table_two_columns = array();
    var $_table_one_types = array();
    var $_table_two_types = array();

    var $_table_one_link;
    var $_table_two_link;

    var $_isTest;


    function MatchTable($isLive = true)
    {
        $this->_isTest = !$isLive;
    }

    function matchTables($table1, $table2)
    {
        $this->_table_one_name = $table1;
        $this->_table_two_name = $table2;

        if(isset($this->_table_one_db_pass))
        {
            $this->db_connect('ONE');
        }
        list($this->_table_one_columns,$this->_table_one_types) = $this->getColumns($this->_table_one_name);

        if(isset($this->_table_two_db_pass))
        {
            $this->db_connect('TWO');
        }
        list($this->_table_two_columns,$this->_table_two_types) = $this->getColumns($this->_table_two_name);

        $this->addAdditionalColumns($this->getAdditionalColumns());
    }

    function setTableOneConnection($host, $user, $pass, $name)
    {
        $this->_table_one_db_host = $host;
        $this->_table_one_db_user = $user;
        $this->_table_one_db_pass = $pass;
        $this->_table_one_db_name = $name;
    }

    function setTableTwoConnection($host, $user, $pass, $name)
    {
        $this->_table_two_db_host = $host;
        $this->_table_two_db_user = $user;
        $this->_table_two_db_pass = $pass;
        $this->_table_two_db_name = $name;
    }

    function db_connect($table)
    {
        switch(strtoupper($table))
        {
            case 'ONE':
                $host = $this->_table_one_db_host;
                $user = $this->_table_one_db_user;
                $pass = $this->_table_one_db_pass;
                $name = $this->_table_one_db_name;
                $link = $this->_table_one_link = mysql_connect($host, $user, $pass, true);
                mysql_select_db($name) or die(mysql_error());
            break;
            case 'TWO';
                $host = $this->_table_two_db_host;
                $user = $this->_table_two_db_user;
                $pass = $this->_table_two_db_pass;
                $name = $this->_table_two_db_name;
                $link = $this->_table_two_link = mysql_connect($host, $user, $pass, true);
                mysql_select_db($name) or die(mysql_error());
            break;
            default:
                die('Improper parameter in MatchTable->db_connect() expecting "one" or "two".');
            break;
        }
        if (!$link) {
            die('Could not connect: ' . mysql_error());
        }
    }

    function getColumns($table_name)
    {
        $columns = array();
        $types = array();
        $qry = 'SHOW COLUMNS FROM '.$table_name;
        $result = mysql_query($qry) or die(mysql_error());
        while($row = mysql_fetch_assoc($result))
        {
            $field = $row['Field'];
            $type = $row['Type'];
            /*
            $column = array('Field' => $field, 'Type' => $type);
            array_push($columns, $column);
            */
            $types[$field] = $type;
            array_push($columns, $field);
        }
        $arr = array($columns, $types);
        return $arr;
    }

    function getAdditionalColumns()
    {
        $additional = array_diff($this->_table_one_columns,$this->_table_two_columns);
        return $additional;
    }

    function addAdditionalColumns($additional)
    {
        $qry = '';
        foreach($additional as $field)
        {
            $qry = 'ALTER TABLE '.$this->_table_two_name.' ADD '.$field.' '.$this->_table_one_types[$field].'; ';

            if($this->_isTest)
            {
                echo $qry.'<br><br>';
            }
            else
            {
                mysql_query($qry) or die(mysql_error());
            }
        }
    }

    /**
     * End of Class
     */
}
类匹配表
{
var$\表\一个\名称;
var$\表\两个\名称;
var$\表\一个\数据库\用户;
var$\表\单\数据库\通行证;
var$\表\一个\数据库\主机;
var$\表\一个\数据库\名称;
var$\表\两个\数据库\用户;
var$\表\两个\数据库\通道;
var$\表\两个\数据库\主机;
var$\表\两个\数据库\名称;
var$_table_one_columns=array();
var$_table_两列=array();
var$_table_one_types=array();
var$_table_two_types=array();
var$\表\一个\链接;
var$\表\两个\链接;
var$isTest;
函数匹配表($isLive=true)
{
$this->_isTest=!$isLive;
}
函数匹配表($table1,$table2)
{
$this->\u table\u one\u name=$table1;
$this->\u table\u two\u name=$table2;
如果(isset($this->\表\单\数据库\通行证))
{
$this->db_connect('ONE');
}
列表($this->u table\u one\u columns,$this->u table\u one\u types)=$this->getColumns($this->u table\u one\u name);
如果(isset($this->\表\两个\数据库\通行证))
{
$this->db_connect('TWO');
}
列表($this->\u table\u two\u columns,$this->\u table\u two\u types)=$this->getColumns($this->\u table\u two\u name);
$this->addAdditionalColumns($this->getAdditionalColumns());
}
函数setTableOneConnection($host、$user、$pass、$name)
{
$this->\u table\u one\u db\u host=$host;
$this->\u table\u one\u db\u user=$user;
$this->\u table\u one\u db\u pass=$pass;
$this->\u table\u one\u db\u name=$name;
}
函数setTableTwoConnection($host、$user、$pass、$name)
{
$this->\u table\u two\u db\u host=$host;
$this->\u table\u two\u db\u user=$user;
$this->\u table\u two\u db\u pass=$pass;
$this->\u table\u two\u db\u name=$name;
}
函数db_connect($table)
{
交换机(strtoupper($table))
{
案例一:
$host=$this->\u table\u one\u db\u host;
$user=$this->\u table\u one\u db\u user;
$pass=$this->\u table\u one\u db\u pass;
$name=$this->\u table\u one\u db\u name;
$link=$this->\u table\u one\u link=mysql\u connect($host、$user、$pass,true);
mysql_选择_db($name)或die(mysql_error());
打破
个案"二",;
$host=$this->\u table\u two\u db\u host;
$user=$this->\u table\u two\u db\u user;
$pass=$this->\u table\u two\u db\u pass;
$name=$this->\u table\u two\u db\u name;
$link=$this->\u table\u two\u link=mysql\u connect($host、$user、$pass,true);
mysql_选择_db($name)或die(mysql_error());
打破
违约:
die('MatchTable->db_connect()中的参数不正确,应为“一”或“两”);
打破
}
如果(!$link){
die('无法连接:'.mysql_error());
}
}
函数getColumns($table\u name)
{