2009-09-30 10 views
4

Je suis en train de migrer d'un système à un autre et, en cours de route, j'exécuterai les deux systèmes simultanément. J'ai besoin de pouvoir me synchroniser de façon unidirectionnelle d'une table à l'autre tout en conservant les clés primaires de chaque table.Comment synchroniser deux tables MySQL ayant des structures différentes?

Dans cet exemple, j'ai deux tables (A) et (B). Je dois synchroniser value1 et value2 (ci-dessous) de la table B à la table A basée sur une clé étrangère commune (match1 et match2 ci-dessous). Le tableau A aura des champs supplémentaires que le tableau B, et certains champs de B ne seront pas synchronisés.

Comment puis-je faire ce qui suit:

  1. Insérer dans une des valeurs qui a été ajouté à B
  2. Retirer du les enregistrements qui ont été retirés de B
  3. Mise à jour A la changé champs de B

Voici quelques données de démonstration:

DROP TABLE IF EXISTS `a`; 
CREATE TABLE IF NOT EXISTS `a` (
    `id1` int(10) unsigned NOT NULL, 
    `match1` int(10) unsigned NOT NULL, 
    `value1` varchar(255) NOT NULL, 
    PRIMARY KEY (`id1`) 
); 

INSERT INTO `a` (`id1`, `match1`, `value1`) VALUES 
(1, 1, 'A'), 
(2, 2, 'A'), 
(3, 3, 'B'), 
(4, 4, 'C'), 
(5, 5, 'C'); 

DROP TABLE IF EXISTS `b`; 
CREATE TABLE IF NOT EXISTS `b` (
    `id2` int(10) unsigned NOT NULL, 
    `match2` int(10) unsigned NOT NULL, 
    `value2` varchar(255) NOT NULL, 
    PRIMARY KEY (`id2`) 
); 

INSERT INTO `b` (`id2`, `match2`, `value2`) VALUES 
(1, 1, 'A'), 
(2, 2, 'A'), 
(3, 3, 'B'), 
(4, 5, 'D'), 
(5, 6, 'D'), 
(6, 7, 'F'); 

La direction que je vais actuellement est de créer une table fusionnée entre les deux tables, et de construire les requêtes en conséquence. Par exemple:

create table ab as (select * from a, b); 

Que suggérez-vous?

+0

Que voulez-vous dire par "faire ressembler les données dans A"? Voulez-vous que A contienne les mêmes données que B, juste avec des champs supplémentaires? – MBillock

+0

Je suis d'accord avec MBillock. Précisez s'il vous plaît. – exhuma

+0

J'ai édité pour clarifier ce que j'essaie d'accomplir. Le problème principal est de maintenir les clés primaires dans la fusion. – Dooltaz

Répondre

4

1.Engager en A tout ce qui a été ajouté à B

INSERT INTO a(id1, match1, value1) 
SELECT id2, match2, value2 
FROM b WHERE NOT EXISTS (SELECT 1 FROM a WHERE a.match1 = b.match2) 

2.Retirer de A tout ce qui a été retiré de B

DELETE FROM a 
WHERE match1 IN (SELECT match1 FROM a INNER JOIN B ON A.match1 = B.match2) 

A avec les 3.Mettre à jour les champs modifiés de B

UPDATE a 
SET value1 = (SELECT value2 FROM b WHERE a.match1 = b.match2) 
+0

Je vérifie la vôtre comme la meilleure réponse parce que vous m'avez commencé. Je vous remercie. Il y a quelques "faute de frappe" dans les requêtes ci-dessus, et j'ai décidé de faire une boucle de procédure stockée WHILE pour les suppressions. La suppression que vous avez là donne une erreur. Vous ne pouvez pas avoir 'a' dans le sous-select d'une instruction delete. Merci! – Dooltaz

0
TRUNCATE TABLE A; 

INSERT INTO A (id1, match1, value1) 
    SELECT id2, match2, value2 FROM B; 
3

I Buil t une procédure stockée pour tout fusionner correctement. Merci pour les réponses. C'est ce que je vais faire avec.

BEGIN 

DECLARE loop_done INT; 
DECLARE orphan varchar(255); 
DECLARE CONTINUE HANDLER FOR NOT FOUND SET loop_done=1; 

INSERT INTO a(id1, match1, value1) 
SELECT '', match2, value2 
FROM b WHERE NOT EXISTS (SELECT 1 FROM a WHERE a.match1 = b.match2); 

UPDATE a SET value1 = (SELECT value2 FROM b WHERE a.match1 = b.match2); 

/* This Delete statement works better for MySQL. */ 
SET loop_done=0; 
SET orphan=null; 
SELECT id1 INTO orphan FROM a left join b on (b.match2 = a.match1) where b.id2 is null LIMIT 1; 
WHILE (loop_done=0) DO 
DELETE FROM a WHERE id1=orphan; 
SELECT id1 INTO orphan FROM a left join b on (b.match2 = a.match1) where b.id2 is null LIMIT 1; 
END WHILE; 

END 
Questions connexes