C'est une bonne question qui illustre les problèmes de sur-couche et comment y faire face.
Exemple :Postez des mentions J'aime
Restons sur l'exemple des utilisateurs qui aiment les publications, qui est un exemple simple. Les autres relations devraient être traitées en conséquence.
Vous avez tout à fait raison de dire que le fait de stocker les likes dans le message conduirait tôt ou tard au problème que les messages très populaires atteindraient la limite de taille.
Vous avez donc correctement recouru pour créer un post_likes
le recueil. Pourquoi est-ce que j'appelle cela correct? Puisqu'il s'adapte à vos cas d'utilisation et à vos exigences fonctionnelles et non fonctionnelles !
- Cela évolue indéfiniment (enfin, il y a une limite théorique, mais c'est énorme)
- Il est facile à entretenir (créez un index unique sur
post_id
etliked_user_id
) et l'utilisation (l'utilisateur et la publication sont connus, donc l'ajout d'un like est un simple insert ou plus probablement un upsert) - Vous pouvez facilement savoir quels utilisateurs aiment quelle publication et quelle publication est aimée par quels utilisateurs
Cependant, j'élargirais un peu la collection pour éviter les requêtes inutiles pour certains cas d'utilisation fréquents.
Supposons pour l'instant que les titres de publication et les noms d'utilisateur ne peuvent pas être modifiés. Dans ce cas, le modèle de données suivant pourrait avoir plus de sens
{
_id: new ObjectId(),
"post_id": someValue,
"post_title": "Cool thing",
"liked_user_id": someUserId,
"user_name": "JoeCool"
}
Supposons maintenant que vous souhaitiez afficher le nom d'utilisateur de tous les utilisateurs qui ont aimé une publication. Avec le modèle ci-dessus, il s'agirait d'une seule requête plutôt rapide :
db.post_likes.find(
{"postId":someValue},
{_id:0,user_name:1}
)
Avec seulement les identifiants stockés, cette tâche plutôt habituelle nécessiterait au moins deux requêtes et - étant donné la contrainte qu'il peut y avoir un nombre infini de likers pour un message - potentiellement énorme consommation de mémoire (vous auriez besoin de stocker les ID utilisateur dans la RAM).
Certes, cela entraîne une certaine redondance, mais même lorsque des millions de personnes aiment un message, nous ne parlons que de quelques mégaoctets d'espace disque relativement bon marché (et facile à mettre à l'échelle) tout en gagnant beaucoup de performances en termes d'expérience utilisateur.
Maintenant, voici le problème :même si les noms d'utilisateur et les titres des publications sont susceptibles de changer, vous n'avez qu'à effectuer une mise à jour multiple :
db.post_likes.update(
{"post_id":someId},
{ $set:{ "post_title":newTitle} },
{ multi: true}
)
Vous négociez qu'il faut un certain temps pour faire des choses plutôt rares comme changer un nom d'utilisateur ou un message pour une vitesse extrême pour des cas d'utilisation qui se produisent extrêmement souvent.
Conclusion
Gardez à l'esprit que MongoDB est une base de données orientée document. Documentez donc les événements qui vous intéressent avec les valeurs dont vous avez besoin pour les requêtes futures et modélisez vos données en conséquence.