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

Linq Discussion :

Effectuer une requête entre 2 bases de données


Sujet :

Linq

  1. #1
    Membre averti Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    927
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 927
    Points : 312
    Points
    312
    Par défaut Effectuer une requête entre 2 bases de données
    Bonjour,

    Avant de trouver une réponse toutes faites, je vais rechercher par moi même, mais j'aimerais que vous m'indiquiez si je suis dans la bonne voie.

    Etant débutant dans les bases de données et LINQ, j'utilise pour le moment des commandes relativement simple sous C#.

    J'ai une base de données Local en SQLite et une base distante en MySQL (ou oracle), Je doit faire une synchronisation entre plusieurs tables, mais notamment l'une d'entre elle qui est montante et descendante.
    Je peux récupérer les 2 requêtes dans 2 DATABASE: SELECT * FROM APPAREILS

    DataTable_MySQL et DataTable_SQlite

    Et a l'aide de Linq je dois chercher dans les colonnes "Numero" et "Update_Time" de chaque DataTable afin de les incérer ou de les mettre à jour:

    Incertion:
    La liste des numéro présent uniquement dans MySQL pour les incérer ensuite dans SQLite.
    La liste des numéro présent uniquement dans SQLite pour les incérer ensuite dans MYSQL.

    Ensuite rechercher dans la colonne 'Update_Time".
    Update:
    La liste des numéro dont l'Update_Time est > dans SQLite par rapport à MySQL, afin de mettre à jour MySQL.
    Et inversement, la liste des numéro dont l'Update_Time est > dans MySQL par rapport ) SQLite, afin de mettre à jour SQLite.

    Voila, Est-ce faisable avec les commandes LINQ?

    Merci

  2. #2
    Membre émérite
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Points : 2 533
    Points
    2 533
    Par défaut
    Oui, mais tu ne pourras pas faire des requêtes qui utilisent les 2 BDD en même temps.

    Si tes tables sont "petites" et que tu es certains qu'elle ne deviendront pas traitable en 1 passe (ce qui sous entends que tu peux rapatrier la totalité des enregistrements des 2 BDD en mémoire), c'est relativement simple.
    - Tu requêtes les 2 BDD
    - Tu compares les 2 listes résultantes
    - Tu effectues les traitements

    Sinon grosses tables (là c'est beaucoup plus lourd)

    Il est préférable de faire les requêtes avec un critère correspondant à la dernière date de synchro (Tu stockes la date de synchro dans une table options par exemple)
    Pourquoi ce choix ? si ta synchro génère des millions d'enregistrements, tu ne pourras pas le faire en 1 passe, tu coup tu seras obligé de faire des lots et la méthode avec la comparaison sur les id avec les lots ne fonctionne pas. (enfin du moins je ne l'ai jamais utilisé et sa me paraît difficile de prime abord)


    - Donc récupération de la précédente date de synchro -> prevSynchro
    - Stocker date système en UTC dans -> dateNouvelleSyncrho
    - Requête sur la 1iere BDD :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from item in mysqlite.table where creation_time > prevSynchro select item
    - Mise à jour de la 2ième BDD
    - Mise à jour de la date de synchro des enregistrements de la BDD1 avec dateNouvelleSynchro
    - stockage de la nouvelle date de synchro dans la table option <- dateNouvelleSynchro

    Par contre plein de piège possible :
    - Déjà si tes id sont des int, tu peux te retrouver avec l'id 1 créer sur les 2 BDD, les 2 étant nouveaux et la c'est mort. Il est donc préférable de passer par des id de type Guid
    - Sur la date de synchro, vu que tu utilises une date locale à ton PC, il est possible que les serveurs de BDD qui alimente le creation_time ne soient pas à la même heure et du coup tu vas perdre des enregistrements.
    Pour sécuriser cela il est préférable de prendre une marge lors de la requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from item in mysqlite.table where creation_time > prevSynchro.AddDays(-1) select item
    Par contre cela va te ramener des enregistrements déjà traiter, il faudra donc lors de la mise à jour vérifier que les enregistrements sont effectivement à traiter.

    - l'autre solution possible pour éviter les dateDeSynchro, c'est à chaque fois que tu ajoutes ou modifies un enregistrement dans une des 2 BDD, tu poses un flag aSynchro = true sur l'enregistrement
    du coup ta requête devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from item in mysqlite.table where aTraiter select item
    mais du coup il faut pas oublier de poser le flag !!!! (si ton code est centralisé c'est gérable, si tu créer des enregistrements avec un code spécifique à chaque fois, c'est sûr que tu vas oublier le flag un jour)
    - un problème sur lequel il faut arbitrer c'est : que faire quand on a une mise à jour d'un même enregistrement sur les 2 BDDs.
    - penser à gérer les enregistrements supprimés
    - Bien sûr penser à faire des traitements par lots, si ta synchro génère 1 000 000 d'enregistrement à traiter, il faudra le découper en lots.
    - Il y a sûrement d'autres pièges à éviter, mais sa fait un moment que je n'ai pas eu à faire de synchro moi même !!
    Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !

    On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.

  3. #3
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 146
    Points : 7 388
    Points
    7 388
    Billets dans le blog
    1
    Par défaut
    Bonjour, voici quelques pistes pour gérer :
    - Les conflits d'ID
    - Les conflits de mise à jour

    Utiliser un GUID comme clé primaire, personnellement ne me plaît guère.
    En effet, généralement les données sont stockées physiquement dans la table dans l'ordre de cette clé.
    Hors, GUID était totalement aléatoire, cela signifie qu'on va passer notre temps à intercaler des données avant des données déjà existantes.
    Ceci a deux effets de bord néfastes :
    - Quelque soit le taux de remplissage de la table, ça va forcément finir, à un moment où à un autre, par provoquer un très coûteux déplacement des lignes dans le fichier, afin de refaire de la place en début de fichier
    - Les lignes sont homogénement réparties dans tout le fichier de la table, ce qui signifie que les "anciennes" lignes "mortes" sont mélangées avec les "nouvelles" lignes "actives". Le fonctionnement des disques (ainsi que des pages internes des SGBD) sont ainsi faits que ceci risque de provoquer une lecture complète du fichier pour retrouver les 10 dernières lignes créées, c'est vraiment très domage.

    Fort de ça, je propose deux solutions alternatives :
    - Utiliser un compteur spécifique à chaque machine : le serveur part par exemple de 1, et chaque application mobile compte dans sa base locale à partir de "identifiant client * 1000000". Un outil avec lequel je travaille utilise un INT64 pour gérer les ID. Les 32 bits de poids fort correspondent au numéro de machine qui a généré la ligne, et les 32 bits de poids faible sont un simple incrément à partir de 1. Ca résoud que partiellement le problème, car dans le fichier, on autant de zone "vivante" que d'applications clientes, ce qui peut poser les mêmes travers que GUID (un peu moins quand même).
    - Ou alors maintenir sur chaque application client une table de correspondance entre numéro local et numéro serveur. Ceci permet d'avoir les données correctement ordonnées dans la base, aussi bien côté serveur que côté client. En revanche, attention à la maintenance de cette table, ça peut faire quelques noeuds au cerveau...


    Ensuite, pour les conflits du type "c'est qui qu'à tout pété mes données ?" là il y a un mécanisme pas trop lourd qui peut être aisément mis en place.
    Aussi bien sur le serveur que dans les bases locales, conserver dans un colonne dédiée (format binaire pour la performance, ou JSON pour la lisibilité) qui va stocker la date de dernière modification de chaque colonne de la table.

    Ainsi, mettons une table "personne" avec les colonnes suivantes "nom, prenom, date naissance"

    Si sur le serveur je crée une ligne le 21/12/2022 à 15h28 :
    "Molière";"Jean";15-01-1922
    => Dans ma colonne de suivi des dates pour chaque colonne j'ai "Nom=21/12/2022 15:28;Prenom=21/12/2022 15:28;Naissance=21/12/2022 15:28"

    Ensuite, l'utilisateur 1 récupère sur son poste la ligne telle qu'elle.
    Il modifie à 15h30 le nom :
    "Poquelin";"Jean-Baptiste";15-01-1922
    => Dans ma colonne de suivi des dates pour chaque colonne j'ai "Nom=21/12/2022 15:30;Prenom=21/12/2022 15:30;Naissance=21/12/2022 15:28"

    L'utilisateur 2, qui a récupéré en même temps que utilisateur 2 modifie la date de naissance à 15h31:
    "Molière";"Jean";15-01-1622
    => Dans ma colonne de suivi des dates pour chaque colonne j'ai "Nom=21/12/2022 15:28;Prenom=21/12/2022 15:28;Naissance=21/12/2022 15:31"

    Maintenant, l'utilisateur 2 synchronise.
    Pas de modif côté serveur, sa date est plus à jour, il envoie au serveur sa modif, avec sa date de modif.
    Sur le serveur on a donc :
    "Molière";"Jean";15-01-1622
    => Dans ma colonne de suivi des dates pour chaque colonne j'ai "Nom=21/12/2022 15:28;Prenom=21/12/2022 15:28;Naissance=21/12/2022 15:31"

    Utilisateur 1 synchronise.
    Il récupère la date mise à jour. Elle est postérieure à la version qu'il connait : on la met à jour.
    Il a donc :
    "Poquelin";"Jean-Baptiste";15-01-1622
    => Dans ma colonne de suivi des dates pour chaque colonne j'ai "Nom=21/12/2022 15:30;Prenom=21/12/2022 15:30;Naissance=21/12/2022 15:31"
    Puis il envoie au serveur, les modifications nom et prenom, car elles sont plus récentes que celles connues par le serveur.
    Sur le serveur on a donc :
    "Poquelin";"Jean-Baptiste";15-01-1622
    => Dans ma colonne de suivi des dates pour chaque colonne j'ai "Nom=21/12/2022 15:30;Prenom=21/12/2022 15:30;Naissance=21/12/2022 15:31"

    Utilisateur 2 synchronise à nouveau.
    Nom et prénom sont plus à jour que sa version : il les réupère.
    "Poquelin";"Jean-Baptiste";15-01-1622
    => Dans ma colonne de suivi des dates pour chaque colonne j'ai "Nom=21/12/2022 15:30;Prenom=21/12/2022 15:30;Naissance=21/12/2022 15:31"

    Certes, c'est un peu usine à gaz sur les bords, mais ça permet de résoudre la plupart des cas de conflits sans trop de risque d'erreur.
    On ne jouit bien que de ce qu’on partage.

  4. #4
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 150
    Points : 25 066
    Points
    25 066
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

Discussions similaires

  1. Réponses: 1
    Dernier message: 12/06/2009, 00h39
  2. Réponses: 4
    Dernier message: 11/01/2008, 13h18
  3. [MySQL] requête entre deux Bases de données
    Par kokoroko dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 27/06/2007, 16h14
  4. [MySQL] Faire une requête recourant à deux bases de données
    Par bourvil dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 02/04/2006, 16h35

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