Quels sont les inconvénients d'utiliser UUID ou GUID comme clé primaire?

61

Je voudrais construire un système distribué. J'ai besoin de stocker des données dans des bases de données et il serait utile d'utiliser un UUID ou un GUID comme clé primaire sur certaines tables. Je suppose que c'est un inconvénient avec cette conception puisque l'UUID / GUID est assez grand et qu'ils sont presque aléatoires. L'alternative consiste à utiliser un INT ou LONG auto-incrémenté.

Quels sont les inconvénients liés à l'utilisation de l'UUID ou du GUID en tant que clé primaire pour mes tables?

J'utiliserai probablement Derby / JavaDB (sur les clients) et PostgreSQL (sur le serveur) en tant que SGBD.

Jonas
la source
Pourquoi cela serait-il utile? Sur quels inconvénients êtes-vous le plus concentré? La réponse à chaque question DB cette vague est "ça dépend." Pouvez-vous nous donner plus de détails? Êtes-vous plus intéressé par la performance en lecture ou en écriture? de quel niveau de distribution parle-t-on?
Brian Ballsun-Stanton
@Brian: les UUID dans les systèmes distribués sont utiles car vous pouvez créer la clé primaire sur les clients, puis télécharger les données de manière asynchrone sur le serveur. Je pense surtout aux inconvénients des performances de lecture. Utiliser beaucoup de jointures sur des UUID n'est peut-être pas si bon? Par exemple, un client ajoute un élément (UUID, nom, fournisseur, créateur) à un système d'inventaire, puis la base de données locale est synchronisée avec la base de données centrale sur le serveur.
Jonas
1
Je pense que sans quelques clarifications supplémentaires à ce sujet, cela va tout au plus être "ça dépend". Sans ceux-ci, je vais aller pour VtC.
jcolebrand
Il existe un article traitant d'affectation de GUID ou non sur les index clusterisés dans SQL Server qui pourrait vous intéresser même s'il est lié à un autre produit SQL: x.co/Twpp
Jeff
J'ai remarqué que le document Derby ne répertorie pas l'UUID en tant que type de données. Vous pouvez envisager une alternative telle que H2 Database Engine (une base de données Java pure telle que Derby) qui répertorie un type de données UUID . Bien entendu, Postgres offre un excellent support pour le stockage , l’indexation et la génération efficaces de valeurs UUID.
Basil Bourque

Réponses:

29

Cela dépend de votre fonction de génération et de la taille des tables finales

Les GUID sont conçus pour être des identificateurs globalement uniques . Comme indiqué dans la documentation de Postgres 8.3, il n'y a pas de méthodologies universellement appropriées pour générer ces identifiants, mais postgreSQL est fourni avec quelques candidats plus utiles.

Compte tenu de l’ampleur de votre problème et de la nécessité d’ écrire hors ligne , vous avez parfaitement bien défini l’utilisation de tout, sauf d’un GUID. Par conséquent, il n’ya aucun avantage compensatoire d’autres schémas.

D'un point de vue fonctionnel, la longueur de la clé n'est généralement pas un problème sur les systèmes modernes, en fonction du nombre de lectures et de la taille de la table. En tant que méthodologie alternative, les clients hors connexion pourraient regrouper de nouveaux enregistrements par lot sans clé primaire et les insérer simplement lors de la reconnexion. PostgreSQL offrant le type de données "Série", les clients n’auront jamais besoin de déterminer l’ID s’ils peuvent effectuer une simple écriture dans la base de données.

Brian Ballsun-Stanton
la source
3
Vous dormez, vous êtes parti et laissez Brian répondre à la question. Oui, l'exigence de "mises à jour hors ligne" a complètement changé le concept.
jcolebrand
Muahahahaah! :: virevolt moustache diabolique ::
Brian Ballsun-Stanton le
1
Même avec des écritures hors ligne, il serait possible d'utiliser des INT. Par exemple, en utilisant deux colonnes {Node_ID, Item_ID}où chaque nœud a un Node_IDet un Item_IDauto-incrémenté automatiquement par nœud.
Jonas
@ Jonas ~ Oui, c'est faisable. Cependant, l'une des raisons pour lesquelles la plupart des gens envisagent même des GUID est la réplication du contenu séparée de manière globale vers d'autres bases de données. Je veux dire que le terme lui-même est plutôt QED ici.
jcolebrand
En ce qui concerne les architectures maître / esclave ou les clients à connexion fragmentée + architectures de serveur principal, pourrait-on utiliser un identifiant global_ID (SERIAL) sur le maître et un identifiant global_id (BIGINT) + local_id (SERIAL) sur les esclaves. Les esclaves effectuent leur travail local en utilisant local_id et commettent quand ils le peuvent envers le maître. Le maître reçoit les données et lui attribue un identifiant global qu’il renvoie à l’esclave. Il met à jour le champ global_id (à utiliser comme référence pour parler au serveur ou à d’autres des esclaves).
Mihai Stancu
22

Encore un conseil: n'utilisez jamais de GUID dans le cadre d'un index clusterisé. Les GUID ne sont pas séquentiels. Par conséquent, s’ils font partie d’un index clusterisé, chaque fois que vous insérez un nouvel enregistrement, la base de données doit réorganiser toutes ses pages de mémoire afin de trouver le bon emplacement pour l’insertion. serait juste la dernière page.

Maintenant, regardons quelques réalisations de base de données: 1.) MySQL - les clés primaires sont en cluster, sans possibilité de changer le comportement - la recommandation est de ne pas utiliser de GUID du tout ici 2.) Postgres, MS-SQL - vous pouvez créer un GUID Clé primaire non clusterisée, et utilisez un autre champ comme index clusterisé, par exemple autoincrement int.

Ross Ivantsiv
la source
Ce que vous proposez pour Postgres peut également être effectué dans MySQL, avec une structure légèrement différente - auto_increment PK (clé en cluster), GUID avec index unique (non clusterisé).
Ypercubeᵀᴹ
Ce n'est pas toujours vrai. En fonction du débit du système de disque, la synchronisation de l'accès à cette dernière page peut constituer votre goulot d'étranglement. blog.kejser.org/2011/10/05/…
mwilson
2
"Contrairement à Microsoft SQL Server, la mise en cluster sur un index dans PostgreSQL ne conserve pas cet ordre. Vous devez réappliquer le processus CLUSTER pour conserver cet ordre." Comment CLUSTER ON améliore
-t-il les
Une version plus condensée de l’information @ bartolo-otrit est liée à: stackoverflow.com/a/4796685/1394393 . Cette réponse ne me semble vraiment pas pertinente, car cette question concerne PG et elle semble supposer des similitudes qui n'existent pas avec SQL Server et MySQL.
jpmc26
database would need to rearrange all its memory pages to find the right place for insertion=> Je ne pense pas que ce soit le cas avec Postgres, car la mise en cluster est facultative et les nouvelles lignes sont stockées non ordonnées.
Flavien
3

Ça dépend.

Sérieusement, avec tout ce que vous avez donné jusqu'à présent, c'est à peu près tout ce que vous pouvez aller.

Pourquoi serait-il utile d'utiliser des UUID? Pourquoi n'utilisez-vous pas les INT? Pourquoi ne pouvez-vous pas simplement indexer sur les UUID plus tard? Comprenez-vous ce que signifie avoir une liste triée avec la clé d'un UUID et insérer un UUID aléatoire (non séquentiel) après quelques millions de lignes?

Sur quelle plateforme cela fonctionnera-t-il? Combien de disques? Combien d'utilisateurs? Combien de disques?

jcolebrand
la source
7
Comme je l'ai écrit dans mon commentaire, si j'utilise UUID, les clients peuvent ajouter des lignes à la base de données sans connexion au serveur, puis se synchroniser avec le serveur. Je ne peux pas faire cela si j'utilise des INT pour la clé primaire, car plusieurs clients peuvent alors utiliser la même clé primaire pour différents éléments. Eh bien, il est inutile de trier la liste sur une colonne UUID, il serait plus utile de la trier sur une colonne timestamp. Non, je ne sais pas ce que cela signifie d'insérer un UUID non séquentiel aléatoire après quelques millions de lignes, c'est pourquoi je pose cette question.
Jonas
L'application sera écrite en Java et les clients pourront utiliser Windows, Mac ou Linux. Les clients utiliseront des ordinateurs de bureau courants dotés généralement d’un seul disque. Le nombre d'utilisateurs et d'enregistrements dépend du nombre de clients que je reçois, mais ce sera environ 5000 par client et par client.
Jonas
1
Le commentaire hors ligne a tout changé. Voyez ce que plus de détails fait?
jcolebrand