J'ai besoin d'un conseil sur NoSQL / MongoDb et la structure de données / modèles
Question
Récemment, j'explore les bases de données NoSQL. J'ai besoin d'un conseil sur la manière de stocker les données de la manière la plus optimale et la plus efficace possible pour un problème donné. Je cible MongoDB, maintenant. Cependant, cela devrait être la même chose avec CouchDB.
Disons que nous avons ces 3 modèles:
Story:
id
title
User:
id
name
Vote:
id
story_id
user_id
Je veux pouvoir poser à la base de données ces questions:
- Qui a voté pour cette histoire?
- Pourquoi cet utilisateur a voté?
Je fais des jointures simples lorsque je travaille avec une base de données relationnelle. La question est de savoir comment dois-je stocker les données de ces objets pour être plus efficace.
Par exemple, si je stocke les objets de vote en tant que sous-collection de récits, il ne sera pas facile d'obtenir les informations - "Qu'est-ce qu'un utilisateur a voté pour",
?.La solution
Je suggérerais de stocker les votes sous forme de liste des articles _id
de chaque utilisateur. De cette façon, vous pourrez découvrir les histoires pour lesquelles un utilisateur a voté simplement en consultant la liste. Pour obtenir les utilisateurs qui ont voté pour une histoire, vous pouvez faire quelque chose comme:
db.users.find ({stories: story_id})
où story_id
est le _id
de l'article en question. Si vous créez un index sur le champ stories
, ces deux requêtes seront rapides.
Autres conseils
- ne vous inquiétez pas si vos requêtes sont efficaces jusqu'à ce qu'elles commencent à compter
- selon la citation ci-dessous, vous le faites mal
La façon dont je vais sur le changement d'esprit est d'oublier la base de données tous ensemble. dans le monde relationnel db vous devez toujours s'inquiéter de la normalisation des données et votre structure de table. Fossé tout. Juste mettre en page votre page Web. Lay les tous dehors. Maintenant regarde-les. Votre déjà 2/3 là-bas. Si vous oubliez le notion que la taille de la base de données est importante et les données ne doivent pas être dupliquées que votre 3/4 là et vous n'avez même pas à écrivez n'importe quel code! Laissez votre avis dicter vos modèles. Tu n'as pas à prendre vos objets et les faire 2 plus dimensionnelle comme dans le monde relationnel. Vous pouvez stocker objets avec forme maintenant.
comment penser en magasin de données au lieu de bases de données
Ok, vous avez donné un modèle de données normalisé comme vous le feriez dans une configuration SQL.
À ma connaissance, vous ne le faites pas dans MongoDB. Vous pouvez stocker des références, mais pas pour des raisons de performances dans le cas général.
Je ne suis pas un expert du domaine NoSQL, mais pourquoi ne pas simplement suivre vos besoins et stocker les utilisateurs (identifiants) qui ont voté pour une histoire dans la collection d'histoires et l'histoire (identifiants) un utilisateur a voté pour dans la collection d'utilisateurs?
Dans CouchDB, cela est très simple. Une vue émet:
function(doc) {
if(doc.type == "vote") {
emit(doc.story_id, doc.user_id);
}
}
Une autre vue émet:
function(doc) {
if(doc.type == "vote") {
emit(doc.user_id, doc.story_id);
}
}
Les deux requêtes sont extrêmement rapides car il n’ya pas de jointure. Si vous avez besoin de données utilisateur ou de données de récit, CouchDB prend en charge la récupération de plusieurs documents. C'est également assez rapide et constitue un moyen de créer une "jointure".
Je me suis beaucoup intéressé à MongoDB et à CouchDB ces derniers temps, mais ma compréhension est limitée. Néanmoins, lorsque vous songez à stocker les votes dans le récit, vous pourriez avoir à vous soucier de ne pas dépasser la limite de taille de document de 4 Mo. Même si vous ne le faites pas, vous augmenterez peut-être la taille du document de manière suffisante pour le déplacer et ainsi ralentir vos écritures (voir comment les documents sont dimensionnés dans MongoDB).
Comme pour CouchDB, ce genre de choses est assez simple, élégant et rapide une fois les indices de vue calculés. Personnellement, cependant, j’ai hésité à faire un projet similaire dans CouchDB en raison des repères indiquant qu’il ralentissait progressivement à mesure que la base de données grandissait (et que les index de vues grandissaient). J'aimerais voir des points de repère plus récents montrant les performances de CouchDB à mesure que la taille de la base de données augmente. Je veux essayer MongoDB ou CouchDB, mais le langage SQL semble toujours aussi efficace et logique, je vais donc en rester là jusqu'à ce que le projet corresponde à la tentation.