J'essaie de déterminer la meilleure façon de traiter une clé primaire composite dans une base de données Mongo. La clé principale pour interagir avec les données de ce système est constituée de 2 uuides. La combinaison d'uuids est garantie d'être unique, mais aucun des uuids individuels ne l'est.
Je vois deux façons de gérer cela:
Utilisez un objet pour la clé primaire qui est composé de 2 valeurs (comme suggéré ici )
Utilisez un identifiant d'objet mongo généré automatiquement comme clé primaire, stockez ma clé dans deux champs distincts, puis créez un index composite sur ces deux champs
Faire de la clé primaire un hachage des 2 uuids
Une autre solution géniale que je ne connais pas actuellement
Quelles sont les implications de performance de ces approches?
Pour l'option 1, je m'inquiète des performances d'insertion en raison de la présence de clés non séquentielles. Je sais que cela peut tuer les systèmes RDBMS traditionnels et j'ai vu des indications que cela pourrait être vrai également dans MongoDB.
Pour l'option 2, il semble un peu étrange d'avoir une clé primaire qui ne serait jamais utilisée par le système. En outre, il semble que les performances des requêtes ne soient pas aussi bonnes que dans l'option 1. Dans un SGBDR traditionnel, un index cluster donne les meilleurs résultats de requête. Quelle est la pertinence de ceci dans MongoDB?
Pour l'option 3, cela créerait un seul champ id, mais encore une fois, il ne serait pas séquentiel lors de l'insertion. Y a-t-il d'autres avantages/inconvénients à cette approche?
Pour l'option 4, eh bien ... qu'est-ce que l'option 4?
En outre, il y a une discussion sur l'utilisation possible de CouchDB au lieu de MongoDB à un moment donné dans le futur. L'utilisation de CouchDB suggérerait-elle une solution différente?
PLUS D'INFO: quelques informations sur le problème peuvent être trouvées ici
Vous devriez choisir l'option 1.
La raison principale est que vous dites que vous êtes préoccupé par les performances - l'utilisation de l'index _id qui est toujours là et déjà unique vous permettra d'économiser d'avoir à maintenir un deuxième index unique.
Pour l'option 1, je m'inquiète des performances de l'insertion pour avoir des clés non séquentielles. Je sais que cela peut tuer les systèmes RDBMS traditionnels et j'ai vu des indications que cela pourrait être vrai également dans MongoDB.
Vos autres options n'évitent pas ce problème, elles le déplacent simplement de l'index _id vers l'index unique secondaire - mais maintenant vous avez deux index, une qui est équilibrée à droite et l'autre qui est à accès aléatoire.
Il n'y a qu'une seule raison de remettre en question l'option 1 et c'est si vous prévoyez d'accéder aux documents par une seule ou simplement l'autre valeur UUID. Tant que vous fournissez toujours les deux valeurs et (cette partie est très importante) que vous les commandez toujours de la même manière dans toutes vos requêtes, alors l'index _id remplira efficacement son rôle.
Pour expliquer pourquoi vous devez vous assurer de toujours commander les deux valeurs UUID de la même manière, lorsque vous comparez des sous-documents { a:1, b:2 }
n'est pas égal à { b:2, a:1 }
- vous pourriez avoir une collection où deux documents avaient ces valeurs pour _id. Donc, si vous stockez _id avec le champ a en premier, vous devez toujours conserver cet ordre dans tous vos documents et requêtes.
L'autre prudence est que l'indice sur _id:1
sera utilisable pour la requête:
db.collection.find({_id:{a:1,b:2}})
mais il sera pas utilisable pour la requête
db.collection.find({"_id.a":1, "_id.b":2})
J'ai une option 4 pour vous:
Utilisez le champ automatique _id
Et ajoutez 2 index de champ unique pour les deux uuid au lieu d'un seul index composite.
_id
Serait séquentiel (bien que ce soit moins important dans MongoDB
), facilement partageable, et vous pouvez laisser MongoDB
le gérer.MongoDB
les entrecroise (nouveau dans la v2.6) comme si vous utilisiez un index composé.J'irais pour l'option 2 et il y a pourquoi
J'aurais choisi l'option 2. Vous pouvez toujours créer un index qui gère les deux champs UUID, et les performances devraient être les mêmes qu'une clé primaire composée, sauf que ce sera beaucoup plus facile à utiliser.
De plus, d'après mon expérience, je n'ai jamais regretté de donner à quelque chose un identifiant unique, même s'il n'était pas strictement requis. C'est peut-être une opinion impopulaire.