我需要使用PHP将数据从一个MySQL数据库复制到另一个MySQL数据库。
我可以构建所有值的数组并将其放入另一个数据库中,但首先我要确保数据库在插入之前具有正确的字段。
例如,假设我要将数据从tableA复制到tableB。
我可以设置tableB看起来就像tableA但是将来我可能会向tableA添加列并忘记将它们添加到tableB,然后我的PHP脚本将尝试将数据插入到tableB中不存在的列中它会失败。
所以我要做的是将tableA与tableB进行比较,以及tableA具有的tableB没有将它们添加到tableB的任何列。
谁能告诉我怎么做?
答案 0 :(得分:5)
感谢大家,基于您的所有帮助,我能够编写一个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
*/
}
答案 1 :(得分:1)
SHOW COLUMNS FROM «table»
答案 2 :(得分:1)
我不是100%肯定这是你正在寻找的东西,但我过去常常做一些小数据库维护。我们需要一种方法来确保devDB和prodDB在结构上是相同的,并且我追踪了这个漂亮的小工具。该工具创建一个sql-alter-script,可以在要修补的数据库上运行。它是用perl编写的,所以我猜它应该可以跨平台工作,但我只在linux上试过它。
该工具名为mySQLdiff,是免费软件,可以在www.mysqldiff.org下载。
答案 3 :(得分:1)
您可以查看一些为您执行此操作的phpclasses http://www.phpclasses.org/search.html?words=mysql+sync&x=0&y=0&go_search=1
答案 4 :(得分:0)
您可以编写一个函数来返回表中的列,如下所示:
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()函数集成到数据传输脚本中,每次运行它以确保表格相同。
当然,你可以让它变得更加漂亮,并让它告诉你两个表之间哪些列不同,使它们同步更有用。
答案 5 :(得分:0)
这是一项非常复杂的任务,据我所知,到目前为止,许多人都试图解决它(不幸的是我不知道任何100%保证的解决方案)。
我想说在开始实现自己的解决方案之前,你应该先阅读一下Schema evolution,Schema Refactoring,Schema versioning等,来了解你将面临的挑战。
之后,您可以查看PHP MDB2_Schema(此article中的更多文档)。
如果您不依赖于PHP,那么您也可以查看提供一组高级架构重构的Sundog。
为您的应用获得可靠的架构迁移工具后,迁移数据将只是一项微不足道的任务。
./亚历
答案 6 :(得分:0)
可能最简单的方法是
$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复制。
答案 7 :(得分:0)
使用TOAD for MySQL Schema比较工具,它将查看表格,以可视方式显示差异并生成SQL查询以同步表格结构。它也进行数据比较。