14 choses que j'aurais aimé savoir avant de commencer à travailler avec MongoDB

La traduction de l'article a été préparée en prévision du lancement du cours Bases de données non relationnelles.

14 choses que j'aurais aimé savoir avant de commencer à travailler avec MongoDB

Principaux points :

  • Il est essentiel de concevoir un schéma, même s'il n'est pas obligatoire dans MongoDB.
  • De même, les index doivent correspondre à votre schéma et à vos modèles d'accès.
  • Évitez d'utiliser de grands objets et de grands tableaux.
  • Soyez prudent avec les paramètres de MongoDB, notamment en ce qui concerne la sécurité et la fiabilité.
  • MongoDB n'a pas d'optimiseur de requêtes, il faut donc être prudent lors de l'exécution des opérations de requête.

Je travaille avec des bases de données depuis longtemps, mais je n'ai découvert MongoDB que récemment. Il y a plusieurs choses que j'aimerais savoir avant de commencer à l'utiliser. Lorsqu'une personne a déjà de l'expérience dans un domaine, elle a des préjugés sur ce que sont les bases de données et ce qu'elles font. Dans l'espoir de faciliter la compréhension pour d'autres, je présente une liste des erreurs courantes.

Créer un serveur MongoDB sans authentification

En effet, MongoDB est installé par défaut sans authentification. Pour une station de travail accessible localement, cette pratique est normale. Mais étant donné que MongoDB est un système multi-utilisateur qui utilise de grandes quantités de mémoire, il est préférable de l'installer sur un serveur avec la quantité maximale de RAM possible dans vos conditions, même si vous prévoyez de l'utiliser uniquement pour le développement. L'installation sur un serveur via le port par défaut peut poser problème, surtout si une requête peut exécuter du code JavaScript (par exemple, $where comme idée pour injection).

Il existe plusieurs méthodes d'authentification, mais le plus simple est de définir un ID/ mot de passe pour l'utilisateur. Utilisez cette idée, en attendant de réfléchir à une authentification plus fantaisiste basée sur LDAP. En ce qui concerne la sécurité, MongoDB doit être mis à jour en permanence et les journaux doivent toujours être vérifiés pour détecter un accès non autorisé. Personnellement, j'aime choisir un autre port comme port par défaut.

N'oubliez pas de lier la surface d'attaque à MongoDB

Liste de contrôle pour la sécurité de MongoDB contient de bons conseils pour réduire le risque d'intrusion dans le réseau et de fuite de données. Il est facile de balayer cette préoccupation et de dire qu'un serveur de développement n'a pas besoin d'un niveau élevé de sécurité. Cependant, la situation est plus complexe et concerne tous les serveurs MongoDB. En particulier, s'il n'y a pas de raison valable d'utiliser mapReduce, groupe ou $where, il faut désactiver l'utilisation de code arbitraire en JavaScript en modifiant le fichier de configuration javascriptActivé:false. Étant donné que dans MongoDB standard, les fichiers de données ne sont pas chiffrés, il est sage de lancer MongoDB avec Utilisateur dédié, qui a un accès complet aux fichiers, avec un accès restreint uniquement pour lui et la possibilité d'utiliser ses propres outils de contrôle d'accès aux fichiers du système d'exploitation.

Erreur lors de la conception du schéma

MongoDB n'utilise pas de schéma. Mais cela ne signifie pas qu'un schéma n'est pas nécessaire. Si vous souhaitez simplement stocker des documents sans aucun schéma cohérent, les sauvegarder peut être rapide et simple, mais les extraire par la suite peut être extrêmement difficile.

L'article classique «6 règles empiriques pour la conception de schémas MongoDB » vaut la peine d'être lu, et des fonctions telles que Schema Explorer dans l'outil tiers Studio 3T, devraient être utilisées pour des contrôles réguliers des schémas.

N'oubliez pas l'ordre de tri

Oublier l'ordre de tri peut provoquer la plus grande déception et prendre plus de temps que n'importe quelle autre configuration incorrecte. Par défaut, MongoDB utilise le tri binaire. Mais il est peu probable qu'il soit utile à quiconque. Les tris sensibles à la casse, à l'accent, et binaires étaient considérés comme des curiosités anachroniques aux côtés des perles, des caftans et des moustaches bouclées dans les années 80. Aujourd'hui, leur utilisation est inacceptable. Dans la vie réelle, «moto» est la même chose que «Moto». Et «Britannique» et «britannique» désignent le même lieu. Une lettre minuscule est simplement l'équivalent minuscule d'une lettre majuscule. Et ne me faites pas parler du tri des diacritiques. Lors de la création d'une base de données dans MongoDB, utilisez des paramètres de tri insensibles à l'accent et à la casse, qui correspondent à la langue et à la culture des utilisateurs du système. Cela simplifiera considérablement la recherche dans les données textuelles.

Création de collections avec de grands documents

MongoDB est capable de stocker de gros documents allant jusqu'à 16 Mo dans des collections, mais GridFS est conçue pour les documents de taille supérieure à 16 Mo. Cependant, même si de grands documents peuvent y être stockés, ce n'est pas la meilleure pratique. MongoDB fonctionne mieux lorsque vous enregistrez des documents individuels qui ne pèsent que quelques kilo-octets, les considérant plutôt comme des lignes dans un tableau SQL étendu. Les gros documents peuvent causer des problèmes avec la performance.

La création de documents contenant de grands tableaux

Les documents peuvent contenir des tableaux. Il est préférable que le nombre d'éléments dans le tableau soit bien en dessous d'un nombre à quatre chiffres. Si des éléments sont fréquemment ajoutés au tableau, il dépassera le document qui le contient, et il faudra le déplacer, ce qui signifie qu'il faudra mettre à jour les index. Lors de la réindexation d'un document avec un grand tableau, les index seront souvent réécrits, car il existe une entrée, qui conserve son index. Cette réindexation a également lieu lorsque le document est inséré ou supprimé.

MongoDB dispose d'un appelé « taux d'occupation », qui fournit de l'espace pour la croissance des documents afin de minimiser ce problème.
Vous pourriez penser qu'il est possible de se passer d'indexation des tableaux. Malheureusement, en l'absence d'index, vous pourriez rencontrer d'autres problèmes. Étant donné que les documents sont parcourus de début en fin, la recherche d'éléments à la fin du tableau prendra plus de temps, et la plupart des opérations liées à ce document seront lentes.

N'oubliez pas que l'ordre des phases dans l'agrégation compte

Dans un système de base de données avec un optimiseurs de requêtes, les requêtes que vous écrivez sont des explications de ce que vous voulez obtenir, et non de la façon de l'obtenir. Cela fonctionne de manière analogue à une commande au restaurant : généralement, vous commandez juste un plat sans donner d'instructions détaillées au chef.

Dans MongoDB, vous instruisez le chef. Par exemple, assurez-vous que les données passent par reduce le plus tôt possible dans le pipeline avec $match et $project, tandis que le tri n'intervient qu'après. reduce, et que la recherche se déroule exactement dans l'ordre dont vous avez besoin. La présence d'un optimiseurs de requêtes, qui élimine le travail superflu, ordonne de manière optimale les étapes et sélectionne le type de connexion, peut vous gâter. Avec MongoDB, vous avez plus de contrôle sur le prix du confort.

Des outils comme Studio 3T faciliteront la construction des requêtes d'agrégation dans MongoDB. La fonction Aggregation Editor vous permettra d'appliquer des opérateurs de pipeline étape par étape, et également de vérifier les données d'entrée et de sortie à chaque étape pour simplifier le débogage.

Utilisation d'une écriture rapide

Ne jamais configurer dans MongoDB des paramètres d'écriture à haute vitesse mais de faible fiabilité. Ce mode «file-and-forget» semble rapide, car la commande retourne avant que l'écriture ne soit effectuée. Si le système échoue avant que les données soient écrites sur le disque, elles seront perdues et se retrouveront dans un état incohérent. Heureusement, le MongoDB 64 bits inclut un journal.

Les moteurs de stockage MMAPv1 et WiredTiger utilisent le journal pour éviter cela, bien que WiredTiger puisse se rétablir jusqu'au dernier point de contrôle, si le journal est désactivé.

Le journal garantit que la base de données est dans un état cohérent après la récupération et conserve toutes les données jusqu'au moment de l'écriture dans le journal. La fréquence des écritures est configurée à l'aide du paramètre intervalDeValidationMs.

Pour vous assurer des écritures, assurez-vous que le journaling est activé dans le fichier de configuration (storage.journal.enabled), et que la fréquence des écritures correspond à la quantité d'informations que vous pouvez vous permettre de perdre.

Tri sans index

Lors de la recherche et de l'agrégation, il est souvent nécessaire de trier les données. Espérons que cela se fait à l'une des étapes finales, après le filtrage des résultats afin de réduire le volume des données à trier. Et même dans ce cas, vous aurez besoin d'un index. Vous pouvez utiliser un index simple ou composé.

S'il n'existe pas d'index approprié, MongoDB s'en passera. Il existe une limite de mémoire de 32 Mo sur la taille totale de tous les documents dans l'opération de tri, et si MongoDB atteint cette limite, elle renverra soit une erreur, soit un ensemble de résultats vide.

Recherche sans prise en charge des index

Les requêtes de recherche remplissent une fonction similaire à celle de l'opération JOIN dans SQL. Pour un meilleur fonctionnement, elles nécessitent un index de valeur de clé utilisé en tant que clé étrangère. Cela n'est pas évident car l'utilisation n'est pas reflétée dans explain(). Ces index sont un complément à l'index enregistré dans explain(), qui est utilisé par les opérateurs de pipeline $match et $sort, lorsqu'ils apparaissent au début du pipeline. Les index peuvent désormais couvrir n'importe quelle étape du pipeline d'agrégation.

L'abandon de l'utilisation des mises à jour multiples

Méthode db.collection.update() est utilisé pour modifier une partie d'un document existant ou l'ensemble du document, jusqu'à le remplacer complètement en fonction du paramètre que vous avez défini update. Il n'est pas aussi évident qu'il ne traitera pas tous les documents de la collection, à moins que vous ne définissiez le paramètre multi pour mettre à jour tous les documents répondant aux critères de la requête.

N'oubliez pas l'importance de l'ordre des clés dans une table de hachage

Dans JSON, un objet est composé d'une collection non ordonnée de zéro ou plusieurs paires nom/valeur, où le nom est une chaîne et la valeur est une chaîne, un nombre, un booléen, zéro, un objet ou un tableau.

Malheureusement, BSON attache une grande importance à l'ordre lors de la recherche. Dans MongoDB, l'ordre des clés à l'intérieur des objets intégrés a de l'importance, c'est-à-dire { firstname: "Phil", surname: "factor" } n'est pas la même chose que { { surname: "factor", firstname: "Phil" }. Cela signifie que vous devez conserver l'ordre des paires nom/valeur dans les documents si vous voulez être assuré de les retrouver.

Ne confondez pas "null" et "undefined"

Valeur "undefined" qui n'a jamais été valide dans JSON, selon la norme officielle JSON (ECMA-404, Section 5), même s'il est utilisé en JavaScript. De plus, pour BSON, il est obsolète et se transforme en $null, ce qui n'est pas toujours une bonne solution. Évitez d'utiliser "undefined" dans MongoDB.

Utilisation $limit() sans $sort()

Très souvent, lorsque vous développez dans MongoDB, il est utile de simplement voir un échantillon de résultat qui sera renvoyé par la requête ou l'agrégation. Pour cette tâche, vous aurez besoin de $limit(), mais cela ne devrait jamais être dans la version finale du code, à moins que vous ne l'utilisiez avec $sort. Cette mécanique est nécessaire, car sinon vous ne pouvez pas garantir l'ordre des résultats et vous ne pourrez pas consulter les données de manière fiable. En haut du résultat, vous recevrez des enregistrements différents en fonction du tri. Pour un fonctionnement fiable, les requêtes et les agrégations doivent être déterministes, c'est-à-dire produire les mêmes résultats à chaque exécution. Le code dans lequel il y a $limit(), mais pas $sort, ne sera pas déterministe et pourra par la suite générer des erreurs difficilement traçables.

Conclusion

La seule façon de se désillusionner avec MongoDB est de la comparer directement avec un autre type de base de données, comme un SGBD, ou d'aborder son utilisation avec des attentes spécifiques. C'est comme comparer une orange avec une fourchette. Les systèmes de bases de données poursuivent des objectifs précis. Il est préférable de comprendre et d'évaluer ces différences pour soi-même. Il serait dommage de pousser les développeurs de MongoDB à suivre le chemin qu'ils ont dû emprunter à cause des SGBD. J'aimerais voir de nouvelles et intéressantes façons de résoudre des problèmes anciens, comme assurer l'intégrité des données et créer des systèmes de données résilients aux pannes et aux attaques malveillantes.

L'introduction de la transactionnalité ACID dans MongoDB avec la version 4.0 est un bon exemple d'implémentation d'améliorations importantes de manière innovante. Les transactions multidocument et multiopérateurs sont désormais atomiques. Il est également possible de régler le temps nécessaire pour obtenir des verrous et de terminer les transactions bloquées, ainsi que de modifier le niveau d'isolation.

14 choses que j'aurais aimé savoir avant de commencer à travailler avec MongoDB

Lire aussi :

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster