6 votes

Comment puis-je synchroniser deux tables de base de données avec PHP ?

J'ai besoin d'utiliser PHP pour copier des données d'une base de données MySQL à une autre.

Je peux créer un tableau de toutes les valeurs à insérer dans l'autre base de données, mais je veux d'abord m'assurer que la base de données contient les bons champs avant de les insérer.

Par exemple, disons que je vais copier des données de la table A à la table B.

Je peux configurer la table B pour qu'elle ressemble à la table A mais, à l'avenir, je peux ajouter des colonnes à la table A et oublier de les ajouter à la table B, alors mon script PHP essaiera d'insérer des données dans une colonne qui n'existe pas dans la table B et il échouera.

Donc ce que je veux faire, c'est comparer la table A à la table B et toutes les colonnes que la table A possède et que la table B n'a pas, les ajouter à la table B.

Quelqu'un peut-il me dire comment faire ?

5voto

JD Isaacks Points 14540

Merci à tous, grâce à votre aide, j'ai pu écrire une classe PHP qui copie toutes les colonnes de la table A vers la table B si elles n'y sont pas déjà :

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

1voto

Sakkle Points 998

Je ne suis pas sûr à 100% que ce soit ce que vous recherchez, mais j'ai fait un peu de maintenance de base de données il y a quelque temps. Nous avions besoin d'un moyen de nous assurer que la structure de la devDB et de la prodDB était identique et j'ai trouvé ce petit outil très pratique. L'outil crée un sql-alter-script qui peut être exécuté sur la base de données que vous souhaitez corriger. Il est écrit en perl et devrait donc fonctionner sur plusieurs plateformes, mais je ne l'ai essayé que sur linux.

L'outil s'appelle mySQLdiff, est gratuit et peut être téléchargé à l'adresse suivante www.mysqldiff.org .

1voto

solomongaby Points 5608

Vous pouvez chercher des classes php qui font cela pour vous. http://www.phpclasses.org/search.html?words=mysql+sync&x=0&y=0&go_search=1

0voto

vartec Points 53382
SHOW COLUMNS FROM «table»

0voto

jonstjohn Points 23326

Vous pourriez écrire une fonction qui renvoie les colonnes du tableau comme ceci :

function columns($table) {

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

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

       $columns[] = $r[0];

    }

    return $columns;

}

Ensuite, vous pouvez comparer les colonnes des deux tableaux :

function tables_different($table1, $table2) {

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

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

}

Maintenant, vous pouvez intégrer la fonction tables_different() dans votre script de transfert de données, en l'exécutant à chaque fois pour vous assurer que les tables sont les mêmes.

Bien sûr, vous pouvez rendre cela plus sophistiqué et faire en sorte qu'il vous dise quelles colonnes sont différentes entre les deux tables, ce qui rendrait leur synchronisation plus utile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X