Nasıl PHP ile iki veritabanı tabloları senkronize edebilirsiniz?

6 Cevap php

Ben başka bir MySQL veritabanı veri kopyalamak için PHP kullanmak gerekir.

Ben oluşturmak ve diğer veritabanına gitmek için tüm değerler dizi ama ilk ben veritabanı takmadan önce doğru alanlara sahiptir emin olmak istiyor olabilir.

Örneğin ben TABLEB için tableA veri kopyalama için gidiyorum söylüyorlar.

Ben sadece tableA gibi görünmek TABLEB kurabilirsiniz ama ileride ben tableA sütunlar eklemek ve TABLEB eklemek için unutmak olabilir, o benim PHP komut TABLEB bulunmayan bir sütuna veri eklemek için çalışacağız ve o olacak başarısız.

Peki ne yapmak istiyorum TABLEB ve tableA TABLEB TABLEB ekleyebilirsiniz sahip olmadığını sahip herhangi bir sütununa tableA karşılaştırmaktır.

Herkes bunu nasıl söyleyebilir?

6 Cevap

Teşekkürler Ben bir PHP sınıfı yazabildi tüm yardım dayanarak herkes, bu tablo B kopyalar tablo A herhangi bir sütun onlar zaten orada değilse:

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
     */
}

Bu sizin için ne arıyorsanız% 100 emin değilim ama ben bir süre önce küçük bir veritabanı bakımını yapmak için kullanılır. Biz devDB ve prodDB yapısı aynıdır vardı ve ben bu şık küçük aracı izini emin olmak için bir yol gerekli. Aracı yama istediğiniz veritabanı üzerinde çalıştırılabilir bir sql-alter-komut dosyası oluşturur. O yüzden çapraz platform çalışması gerekir sanırım perl ile yazılmış ama ben sadece linux üzerinde denedim.

Aracı mySQLdiff denir, ücretsiz ve www.mysqldiff.org indirilebilir.

Eğer bunun gibi tablodan sütun döndüren bir fonksiyon yazabiliriz:

function columns($table) {

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

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

       $columns[] = $r[0];

    }

    return $columns;

}

Sonra, iki tablodan, sütunları karşılaştırabilirsiniz:

function tables_different($table1, $table2) {

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

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

}

Şimdi, tablo aynı olduğundan emin olmak için bunu her zaman çalışan, veri aktarım komut içine tables_different () fonksiyonu entegre edebilirsiniz.

Tabii ki, bu meraklısı yapmak ve sütunlar onları eşitleme için daha kullanışlı hale iki tablo arasındaki farklı hangi söyleyebilirim olabilir.

Bu çok karmaşık bir iştir ve bildiğim kadarıyla pek çok (ne yazık ki herhangi bir% 100 garantili çözümü farkında değilim) şimdiye kadar çözmüş çalıştık.

Ben kendi çözümünüzü uygulamak için atlama önce bir göz atmalısınız ve vb şema evrim, Şema Refactoring, Şema sürüm, yaklaşık okuyarak dönük olacak zorlukları hakkında okumak olduğunu söyleyebilirim

Daha sonra, PHP MDB2_Schema de bir göz atabilirsiniz (bu biraz daha belgelerine article).

PHP bağlı değilseniz o zaman da gelişmiş şema refactorings bir kümesi sağlar Sundog bakmak olabilir.

Eğer uygulama için güvenilir bir şema göç aracı, veri sadece önemsiz bir görev olacaktır göç olsun.

. / Alex

Muhtemelen bunu yapmak için en kolay yol olurdu

$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
}

Ama burada son derece dikkatli olmak gerekir. TABLEB yazabilirsiniz sadece işlem tableA diğer akıllıca kaybetmiş olacak verilerinden kopyasını yapan biri olduğuna emin olun. Ayrıca, bu süreç başladıktan sonra hiçbir şey tableA yazabilirsiniz emin olun.

Bunun için en iyi uygulama php değil mysql çoğaltma yoluyla bunu yapamaz olacaktır.

MySQL Şema aracı karşılaştırmak için TOAD kullanın, bu masalarda bakacağız görsel farklılıkları göstermek ve tablo yapısını senkronize SQL sorguları oluşturmak. Ayrıca verileri karşılaştırmak gelmez.