MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Dois-je implémenter l'auto-incrémentation dans MongoDB ?

Je suis fortement en désaccord avec l'auteur de la réponse sélectionnée selon laquelle Aucun identifiant d'auto-incrémentation dans MongoDB et il y a de bonnes raisons . Nous ne connaissons pas les raisons pour lesquelles 10gen n'a pas encouragé l'utilisation d'ID auto-incrémentés. C'est de la spéculation. Je pense que 10gen a fait ce choix car il est simplement plus facile de garantir l'unicité des ID de 12 octets dans un environnement en cluster. C'est la solution par défaut qui convient à la plupart des nouveaux arrivants, ce qui augmente l'adoption du produit, ce qui est bon pour les affaires de 10gen.

Maintenant, permettez-moi de parler à tout le monde de mon expérience avec ObjectIds dans un environnement commercial.

Je construis un réseau social. Nous avons environ 6 millions d'utilisateurs et chaque utilisateur a environ 20 amis.

Imaginons maintenant que nous ayons une collection qui stocke les relations entre les utilisateurs (qui suit qui). Ça ressemble à ça

_id : ObjectId
user_id : ObjectId
followee_id : ObjectId

sur lequel nous avons un index composite unique {user_id, followee_id} . Nous pouvons estimer la taille de cet index à 12*2*6M*20 =2GB. Voilà un index pour une recherche rapide des personnes que je suis. Pour une recherche rapide des personnes qui me suivent, j'ai besoin d'un index inversé. C'est encore 2 Go.

Et ce n'est que le début. Je dois transporter ces pièces d'identité partout. Nous avons un cluster d'activités où nous stockons votre fil d'actualité. C'est chaque événement que vous ou vos amis faites. Imaginez combien d'espace cela prend.

Et finalement, l'un de nos ingénieurs a pris une décision inconsciente et a décidé de stocker les références sous forme de chaînes représentant ObjectId qui double sa taille.

Que se passe-t-il si un index ne rentre pas dans la RAM ? Rien de bon, dit 10gen :

Lorsqu'un index est trop volumineux pour tenir dans la RAM, MongoDB doit lire l'index à partir du disque, ce qui est une opération beaucoup plus lente que la lecture à partir de la RAM. Gardez à l'esprit qu'un index tient dans la RAM lorsque votre serveur dispose de RAM disponible pour l'index combiné avec le reste de l'ensemble de travail.

Cela signifie que les lectures sont lentes. Le conflit de verrouillage augmente. L'écriture devient également plus lente. Je ne suis plus choqué de voir des conflits de verrouillage dans 80 % de la finition.

Avant de vous en rendre compte, vous vous êtes retrouvé avec un cluster de 460 Go que vous devez diviser en fragments et qui est assez difficile à manipuler.

Facebook utilise 64 bits comme identifiant d'utilisateur :) Il y a une raison à cela. Vous pouvez générer des identifiants séquentiels

  • en utilisant les conseils de 10gen .
  • utiliser mysql comme stockage de compteurs (si vous êtes préoccupé par la vitesse, consultez handlersocket )
  • en utilisant le service de génération d'ID que vous avez créé ou en utilisant quelque chose comme Snowflake par Twitter.

Voici donc mon conseil général à tout le monde. Veuillez rendre vos données aussi petites que possible. Lorsque vous grandirez, cela vous évitera de nombreuses nuits blanches.