IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Algorithmes et structures de données Discussion :

Comparaison de tables de bases de données


Sujet :

Algorithmes et structures de données

  1. #1
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    927
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 927
    Par défaut Comparaison de tables de bases de données
    Bonjour,

    J'aimerais avoir vos avis sur la méthode que j'utilise pour comparer deux tables ayant une même structure d'une base de données ou de deux bases de données différentes, qui peuvent appartenir à différents SGBD. Par comparer, je veux dire : détecter les enregistrements qui existent dans les deux tables et ceux qui n'existent que dans une des deux tables.

    J'ai posté un message dans le forum Langage SQL (ici), mais il n'y a pas récolté beaucoup de réponses, probablement parce que cela n'a pas un grand rapport avec le langage SQL.

    La méthode est de sélectionner tous les enregistrements des deux tables, dans un même ordre, et de parcourir les enregistrements comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    - Sélection du premier enregistrement des deux tables
    - Comparaison de la rubrique sur laquelle on a trié les enregistrements
         - Si la valeur de la rubrique en question est identique pour les deux enregistrements
              - Les deux enregistrements se trouvent dans les deux tables...
              - Sélection des enregistrements suivant
         - Sinon, si la valeur de la rubrique est plus grande dans la table A
              - Il y a un enregistrement dans la table B qui ne se trouve pas dans la table A
              - Sélection de l'enregistrement suivant de la table B
         - Sinon, si la valeur de la rubrique est plus petite dans la table A
              - L'enregistrement de la table A ne se trouve pas dans la table B
              - Sélection de l'enregistrement suivant de la table A.
    Cette méthode est utile car il n'y a que deux requêtes pour récupérer tous les enregistrements, et qu'une seule lecture (qu'un seul parcours) des enregistrements sélectionnés.

    Cependant devoir récupérer les enregistrements dans un même ordre pour deux tables peut être embêtant.

    A part cette façon, je n'ai pensé qu'à un autre moyen, plus lourd :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    - Sélection du premier enregistrement d'une des deux tables (A)
    - Recherche d'un enregistrement équivalent dans l'autre table (B) (avec une requête SQL)
         - Si on trouve l'enregistrement
              - Les deux enregistrements se trouvent dans les deux tables...
              - Sélection de l'enregistrement suivant de la table A
         - Si on ne le trouve pas
              - L'enregistrement de la table A ne se trouve pas dans la table B
              - Sélection de l'enregistrement suivant de la table A
    - Même chose pour tous les enregistrements
    - Arrivé à la fin de la table A, il faudrait faire une opération similaire dans l'autre sens (on prend un enregistrement de la table B et on recherche son équivalent dans la table A), pour récupérer les enregistrements qui ne se trouvent pas dans la table A mais bien dans la table B.
    Cette méthode implique qu'il faille faire beaucoup de requêtes.

    La méthode que j'utilise doit être la plus courrante à mon avis, mais en fait, je n'en sais rien du tout.

    Merci de vous intéresser à mon cas , pour me dire ce que vous savez ou pensez de la méthode que j'utilise.

    Salut.

  2. #2
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    comparer deux tables identiques
    Si elles sont identiques, il n'y a rien à comparer ....
    Je suppose que vous voulez dire 'ayant même structure'.
    Les champs à comparer doivent donc avoir les mêmes types, et de préférence les mêmes noms.
    Y-a-t-il une clé primaire ?
    Si oui indexez les deux tables suivant cette clé. Sinon, indexez les sur le champ le plus significatif, qu'on prendra comme clé.
    L'indexation étant faite on prend le premier enregistrement de A le premier enregistrement de B et on compare les clefs.
    Si les clés sont les mêmes on compare les premiers enregistrements champ par champ.
    Si la première clé de B est < à celle de A on déplace le curseur de B à la première position de clé qui est >= à celle de A.
    Si la première clé de B est > à cele de A, on déplace le curseur de la table A jusqu'à la première position qui est >= à celle de B.
    Cela fait on poursuit le processus jusqu'à épuisement d'une des deux tables, en stockant à chaque fois les enregistrements trouvés identiques.
    Cela dit, si vous êtes interessés seulement par le résultat, un produit comme ACCESS fournit une requête built-in 'trouver les doublons' qui vous donne immédiatemment le résultat. Il y a fort à parier que les autres SGBD fournissent ce service en standard. Sinon, exporter vos tables au format texte et réimportez les dans une base ACCESS vide.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  3. #3
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    927
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 927
    Par défaut
    Merci pour votre réponse.

    Citation Envoyé par Zavonen
    Si elles sont identiques, il n'y a rien à comparer ....
    Je suppose que vous voulez dire 'ayant même structure'.
    Je voulais bien dire ayant une même structure.

    Citation Envoyé par Zavonen
    Y-a-t-il une clé primaire ?
    Si oui indexez les deux tables suivant cette clé. Sinon, indexez les sur le champ le plus significatif, qu'on prendra comme clé.
    Il y a un attribut qui se retrouve dans les deux tables à comparer et qui aura la même valeur pour des enregistrements équivalents.
    Ex : les deux tables sont des tables servant à stoquer des clients. Elles contiennent toutes les deux le client Jean-Marcel Du Grand Moulinjaune, né le 10/10/1910, à 10 h 10 (donc c'est bien le même client dans les deux tables), on pourrait imaginer un attribut NumClient qui vaudra 12345 pour ce client dans les deux tables. C'est sur cet attribut que l'on triera les enregistrements et c'est bien grâce à cet attribut que l'on saura quels enregistrements sont équivalents.

    Citation Envoyé par Zavonen
    L'indexation étant faite on prend le premier enregistrement de A le premier enregistrement de B et on compare les clefs.
    Si les clés sont les mêmes on compare les premiers enregistrements champ par champ.
    Si la première clé de B est < à celle de A on déplace le curseur de B à la première position de clé qui est >= à celle de A.
    Si la première clé de B est > à cele de A, on déplace le curseur de la table A jusqu'à la première position qui est >= à celle de B.
    Cela fait on poursuit le processus jusqu'à épuisement d'une des deux tables, en stockant à chaque fois les enregistrements trouvés identiques.
    Je pense que c'est exactement ce que je fais. Au début, j'ai cru que cette solution ne permettait pas de détecter les enregistrements (les clients) qui n'existent que dans une des deux tables, mais en fait l'algorithme n'impose pas de "zapper" ces enregistrements. Il est possible de les sauvegarder, d'en tenir compte.

    Citation Envoyé par Zavonen
    Cela dit, si vous êtes interessés seulement par le résultat, un produit comme ACCESS fournit une requête built-in 'trouver les doublons' qui vous donne immédiatemment le résultat. Il y a fort à parier que les autres SGBD fournissent ce service en standard.
    En fait, je compare deux tables pour les synchroniser, pour qu'elles soient identiques (identique dans le sens 'même données' cette fois-ci, et non pas 'même structure'). Et donc, je recherche les doublons (les clients (enregistrements) qui se trouvent dans les deux tables, c'est bien ça ?) mais aussi les clients qui ne se trouvent que dans une des deux tables.
    Un autre problème est que les tables peuvent faire partie de deux bases de données de type différent. Il aurait fallu que la solution soit compatible avec plusieurs SGBD.

    Pensez-vous qu'il y ait d'autres solutions possibles pour connaître les enregistrements qui existent dans les deux tables et ceux qui n'existent que dans une des deux tables ?

  4. #4
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Voici la marche à suivre en SQL:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    //Au début Tab3 est vide avec la même structure que Tab1 et Tab2
    //Insérer  Tab2 dans Tba3
    INSERT INTO Table3 ( Id, nom )
    SELECT Table2.id, Table2.nom
    FROM Table2;
     
    //Insérer Tab1 dans Tab3
    INSERT INTO Table3 ( Id, nom )
    SELECT Table1.id, Table1.nom
    FROM Table1;
     
    //Rechercher les doublons dans Tab3 qui sont donc les enregistrements //strictement identiques dans Tab1 et Tab2
    //La table crée s'appelle 'doublons'
    SELECT First(Table3.Id) AS IdChamps, First(Table3.nom) AS nomChamps, Count(Table3.Id) AS NombreDeDbls
    FROM Table3
    GROUP BY Table3.Id, Table3.nom
    HAVING (((Count(Table3.Id))>1) AND ((Count(Table3.nom))>1));
     
    //Rechercher les elements de Tab1 qui ne sont pas dans doublons
    //Rechercher les elements de Tab1 qui ne sont pas dans Tab2
    SELECT Table1.*
    FROM Table1 LEFT JOIN doublons ON Table1.id = doublons.IdChamps
    WHERE (((doublons.IdChamps) Is Null));
     
    //Idem pour Tab2 mutatis mutandis.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  5. #5
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    927
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 927
    Par défaut
    Merci pour cette marche à suivre. C'est intéressant, il n'y a pas beaucoup de code. Mon code pour effectuer la "synchronisation" prend plusieurs pages... Je remarque que j'ai peut-être choisis une solution barbare, mes requêtes sont de simples SELECT WHERE.

    Cependant, si l'on devait ajouter à votre marche à suivre le code permettant de mettre à jour les bases de données (ajouter les enregistrements manquant, supprimer les enregistrements en trop et comparer et modifier les enregistrements doublons), il faudrait sélectionner les doublons (quelques requêtes) et ensuite les parcourir pour les comparer et les mettre à jour. Mon implémentation de l'algorithme que j'ai cité effectue la détection des doublons et leur comparaison, mise à jour, en même temps.
    Le stockage des doublons dans une nouvelle table est inutile je pense, vu que l'on souhaite uniquement effectuer les mises à jour citées (ajout, supp et comp pour maj).

    Voila l'algorithme plus détaillé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    - (début du parcour des résultats des enregistrements sélectionnés) Sélection du premier enregistrement des deux tables
         - Comparaison de leur valeur pour la rubrique sur laquelle on a trié les enregistrements
              - Si la valeur de la rubrique en question est identique pour les deux enregistrements
                   - Les deux enregistrements se trouvent dans les deux tables... 
                   - Les deux enregistrements sont comparés et l'enregistrement B est mis à jour en fonction des données de l'enregistrement A
                   - On passe aux enregistrements suivants
               - Sinon, si la valeur de la rubrique est plus grande dans la table A
                   - Il y a un enregistrement dans la table B qui ne se trouve pas dans la table A
                   - L'enregistrement B est supprimé de B
                   - On garde l'enregistrement A et on passe à l'enregistrement B suivant
               - Sinon, si la valeur de la rubrique est plus petite dans la table A
                   - L'enregistrement de la table A ne se trouve pas dans la table B
                   - L'enregistrement A est ajouté dans B
                   - On garde l'enregistrement B et on passe à l'enregistrement A suivant
    - Et on recommence avec les nouvelles rubriques sélectionnées

Discussions similaires

  1. table et base de données
    Par stachus dans le forum SWT/JFace
    Réponses: 17
    Dernier message: 21/04/2009, 16h29
  2. Génération de formulaire à partir de table de base de données
    Par Webosaurus dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 07/11/2006, 09h48
  3. [VB.NET] Comment créer une table dans base de données ?
    Par ptitesouris dans le forum VB.NET
    Réponses: 3
    Dernier message: 03/05/2006, 08h46
  4. Réponses: 4
    Dernier message: 25/01/2006, 11h17
  5. Transfert de table entre base de données sous delphi
    Par gregcommune dans le forum Bases de données
    Réponses: 3
    Dernier message: 27/07/2004, 07h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo