0

J'ai deux bases de données postgres, les mêmes tables doivent être synchronisées entre ces bases de données (pas toutes, seulement quelques unes). Cela crée un problème avec la synchronisation, si j'ai la table A et la table B (même structure, juste dans différentes bases de données), si quelqu'un insère dans la table A, l'identifiant pk peut être 5, mais quelqu'un peut insérer sur table B, en obtenant un ID de pk de 5 aussi. Au moment de la synchronisation des deux tables, je peux trouver deux registres avec le même PK, mais avec des contenus différents.Clé primaire Postgres synchronisée

Je suis assez sûr qu'il doit y avoir des solutions pour cela, il doit y avoir une façon intelligente de garder les ids synchronisés.

Jusqu'à présent, je pensais à la création d'un simple webservice qui fournira un nouvel identifiant pk valide, mais cela est problématique car

1 Il va ralentir le processus 2 Il se déplace simplement le problème à la webservice, comment le webservice trouvera-t-il quel est le prochain identifiant valide?

Est-ce que quelqu'un a déjà fait face à un problème similaire dans le passé?

L'environnement est postgres 9.1

Répondre

2

Oui, les gens ont dû faire face ce lot. La question que vous devez poser n'est pas "comment puis-je faire cela" mais "laquelle des méthodes existantes bien comprises et établies correspond le mieux à mes besoins".

Examinez les solutions utilisées pour générer des clés dans des bases de données partagées et réparties.

options comprennent:

  • Allouer des plages ne se chevauchant pas d'ID à chaque machine. Une approche courante consiste à incrémenter vos séquences en blocs de (disons) 100 et à donner à chaque machine un décalage unique, de sorte que la machine A génère 101, 201, 301, 401, etc. et que la machine B génère 102, 202, 302, 402 , ... Fonctionne génial jusqu'à ce que vous ayez besoin d'ajouter la machine # 101. Vous pouvez utiliser une clé bigint et laisser de la place pour 10 000 machines; De cette façon, au moment où vous atteignez cette limite, vous aurez de toute façon modifié le système entier trois fois.

    (Avant de dire « Je vais manquer de clés » ... max bigint est 9223372036854775807 donc avec une gamme de machine 10000 vous cherchez à environ 10 ou 2 clés par table par machine , ce qui correspond à une table de 21 pétaoctets à 25 octets par enregistrement incluant les frais généraux, c'est-à-dire des enregistrements vraiment minuscules). Utilisez une clé primaire composite telle que (machine_id, locally_generated_sequence_id). Idéal sauf si vous avez affaire à des ORM braindead qui insistent sur des clés primaires à valeur unique.

  • Utilisez huge random primary keys (UUIDs) avec le type de données uuid, ce qui donne un espace de 128 bits et une probabilité absolument infime de collision. Fonctionne bien dans la plupart des cas et malgré les collisions birthday paradox sont assez inhabituel. Le paranoïaque peut avoir des plans en place pour faire face aux collisions. Utilisez un service commun pour générer des gros blocs de clés. Appelez-le rarement et stockez les clés disponibles localement.Cela a tendance à gêner les performances d'écriture simultanées sur chaque nœud en raison de conflits de verrous sur la table de clés, donc je ne le recommande pas.

  • ... probablement plus je ne me suis pas souvenu ou n'ai jamais entendu parler de.

L'option la plus simple consiste généralement à allouer des ID qui ne se chevauchent pas. C'est facile, c'est transparent et ça marche.