Tout d'abord, vous devez connaître les compromis que vous allez obtenir avec MongoDB et toute autre base de données NoSQL (mais se rendre compte que je suis un fan de celui-ci). Si vous essayez de normaliser complètement vos données, vous faites une grosse erreur. Même dans les bases de données relationnelles, plus votre application est importante, plus vos données sont dénormalisées (voir this post par Hot Potato). J'ai vu cela encore et encore. Vous ne devriez pas devenir fou et faire un énorme gâchis, mais ne vous inquiétez pas de répéter l'information à deux endroits. L'un des points majeurs (à mon avis) de NoSQL est que votre schéma se déplace dans votre code et pas seulement dans la base de données. Maintenant, pour répondre à votre question, je pense que votre stratégie initiale est ce que je ferais. MongoDB peut placer des index sur des éléments qui sont des tableaux, ce qui rendra les choses beaucoup plus rapides si vous recherchez le nombre d'amitiés d'un utilisateur. Mais en réalité, la seule façon d'être vraiment sûr est d'exécuter un programme de test qui génère une base de données pleine de noms et de relations.
Vous pouvez écrire des scripts en Python ou Perl ou utiliser un fichier de noms pour générer des relations. Découvrez le Census website, qui a une liste de noms de famille. Télécharger le fichier dist.all.last
et écrire certains programmes comme:
#! /usr/bin/env python
import random as rand
f = open('dist.all.last')
names = []
for line in f:
names.append(line.split()[0])
rels = {}
for name in names:
numOfFriends = rand.randint(0, 1000)
rels[name] = []
for i in range(numOfFriends):
newFriend = rand.choice(names)
if newFriend != name: #cannot be friends with yourself
rels[name].append(newFriend)
# take relationships (i.e. rels) and write them to MongoDB
En outre, comme une note générale, vos fieldnames semblent sorte de long. Rappelez-vous que les noms de champs sont répétés avec tous les documents dans cette collection, car vous ne pouvez pas compter sur un champ figurant dans un autre document. Pour économiser de l'espace, une stratégie générale consiste à utiliser des noms de champ plus courts comme "unam" au lieu de "nom d'utilisateur", mais c'est une petite chose. Voir le bon conseil dans thesetwo messages.
EDIT:
En fait, en réfléchissant votre problème un peu plus, je voudrais faire une autre suggestion: briser les types d'abonnement dans différents domaines pour rendre les indices plus efficaces.Par exemple, au lieu de:
{
"username" : "alan",
"photo": "123.jpg",
"subscriptions" : [
{"username" : "john", "status" : "accepted"},
{"username" : "paul", "status" : "pending"}
]
}
Comme vous dit plus haut, je ferais ceci:
{
"username" : "alan",
"photo": "123.jpg",
"acc_subs" : [ "john" ],
"pnd_subs" : [ "paul" ]
}
Alors que vous pourriez avoir un index pour chaque type d'abonnement, rendant ainsi des requêtes telles que « Hoy beaucoup les gens ont Paul en attente? " et "Combien de personnes souscrivent à Paul?" super rapide de toute façon. L'indexation de Mongo sur les valeurs array'd est vraiment une victoire épique.
bon message, +1, mais je ne suis pas d'accord sur les noms courts. Faites-les aussi longtemps que nécessaire pour ne rien expliquer à un autre développeur. Puis profile/optimise au besoin. Si les noms sont un problème de taille important à mesure que vous mettez à l'échelle puis refactoriser. – Lee