Accueil > Informatique > mongoDB

mongoDB

30/03/2010

Allez, un sujet à la mode : mongoDB, et plus largement le NoSQL.

Pourquoi ? Les RDBMS remplissent souvent bien leurs rôles, mais la manière d’aborder le problème est toujours la même. L’approche d’une base de données orientée document comme mongoDB est différente, tester en prenant du recul c’est s’intéresser à une autre manière de faire, de voir les choses sous un autre angle.

Développer avec un ORM (comme  avec ActiveRecord) c’est déjà avoir “le cul entre deux chaises”, poussons les choses encore un peu plus loin…

=== Différents besoins, différents outils ===

Avant d’aller plus loin, je tiens à mettre en avant un point important : il n’est pas question ici de remplacer aveuglément une base de données relationnelle. Cela pourra se faire dans certains cas, dans d’autre un outil comme mongoDB sera un complément, et bien souvent une bonne vieille base de données traditionnelle sera la seule réponse. A chaque problème sa solution, chaque outil ayant ses avantages et ses inconvénients.

Côté avantages, mongoDB est simple à utiliser, pas de migration, pas de schéma à définir, mais surtout c’est très rapide et prévu dès l’origine pour une forte croissance du volume et de la charge.

Le principal inconvénient de mongoDB est l’absence de gestion de transaction, pas tant pour des problématiques d’atomicité, d’isolation ou de cohérence dont on peut se passer dans certains cas, mais plus pour l’absence de durabilité. Pour plus de détails voir Les propriétés ACID d’une base de données et  Durability and Repairs.

En d’autres termes, pour …

  • stocker un volume important de données non critiques et structurées par une approche “document” plutôt que “relationnelle”, …
  • ET pouvoir manipuler les données rapidement malgré une charge et un volume important, …
  • ET manipuler les données sans avoir besoin des apports d’une gestion de transaction, …

… alors mongoDB peut présenter un intérêt.

En suivant le reste de ce sujet, vous réaliserez quelques commandes simples dans un “shell” mongoDB. Mais l’outil cohabite très bien avec bon nombre de langages : C, C++, Java, Ruby, PHP, … Pour avoir une liste complète : http://www.mongodb.org/display/DOCS/Drivers

=== Installation (de test) et démarrage de mongoDB ===

Il est possible de faire fonctionner mongDB sous Windows, mais pour ma part, ce sera un exemple utilisé sous Linux (ce qui ne changera pas grand chose) :

  • Identifier la version de mongoDB correspondant à votre environnement, ça se passe ici : http://www.mongodb.org/display/DOCS/Downloads .
  • Télécharger, exemple : wget http://downloads.mongodb.org/linux/mongodb-linux-i686-1.4.0.tgz
  • Décompresser : tar xzf  mongodb-linux-i686-1.4.0.tgz
  • Créer un répertoire pour les données, pour un simple de test j’ai fait le sauvage en la plaçant dans mon répertoire de test de mongoDB. C’est pas bien je sais…. mais c’est une simple prise de contact : cd mongodb-linux-i686-1.4.0 puis mkdir -p data/db
  • Démarrer le serveur de mongoDB : bin/mongod –dbpath data/db

Et c’est tout.

=== Premières commandes ===

Le serveur ayant rendu la console indisponible (c’est du test, ne râlez pas :D ), en ouvrir une autre, et se placer dans le même répertoire qu’au démarrage du serveur.

Démarrer un “shell” client de mongoDB : bin/mongo

A noter que mongo et mongod peuvent avoir divers arguments et qu’il suffit d’y ajouter -h pour en avoir un résumé.

Quelques commandes a essayer juste pour tâter le terrain  :

  • use meuh
  • db.vache.save({nom:”La Noiraude”})
  • db.vache.save({nom:”Azalee”})
  • db.vache.find()
  • n=db.vache.findOne({nom:”Azalee”})
  • n.amis=["Zebulon","Margotte","Pollux"]
  • db.vache.save(n)
  • db.vache.find({amis:”Zebulon”})

Nous n’avons pas créé de bases, ni de tables (appelées ici “collections”), ni aucun champ. Les enregistrements ne se ressemblent pas tous, et ne sont pas “à plat” mais peuvent avoir une structure plus complexe, beaucoup plus que dans cet exemple.

La syntaxe utilisée est à base de Javascript, nous sommes loin du SQL. La manière de travailler est très différente. Dans certain cas on sera agréablement surpris, dans d’autres on regrettera son “bon vieux SQL”. Tout dépend de la manière dont seront structurées les données, ainsi que des opérations à réaliser. Ce n’est pas mieux ou moins bien c’est différent.

=== Scripts et requêtes ===

Il est possible d’écrire des scripts :

  • use test (puisque ça n’a aucun rapport avec les vaches…)
  • for(i=0;i<1000;i++) db.carres.save({x:i,y:i*i});

Et nous voilà avec un millier de documents. Si vous voulez tester avec 100000 itérations, pas de soucis, ça répondra dans un délai raisonnable.

Quelques requêtes sur ces enregistrements :

  • Le nombre de documents avec x>500 : db.carres.find({x:{$gt:500}}).count()
  • Uniquement des valeurs de y pour x<10 : db.carres.find({x:{$lt:10}},{y:true})
  • Les documents ayant des valeurs paires de x : db.carres.find({$where:”(this.x%2)==0″})

La dernière requête est intéressant car elle montre comment effectuer des requêtes contenant du code Javascript ce qui permet de réaliser  des filtres complexes. Par ailleurs elle est loin d’afficher l’ensemble des résultats et termine l’affichage par “has more”, mongoDB ne renvoyant pas des valeurs mais un curseur pour itérer sur le  résultat. Pour voir la suite il suffit d’utiliser la commande :

  • it

Pour plus d’information sur les requêtes : http://www.mongodb.org/display/DOCS/Querying

=== Les indexes n’ont pas été oublies ===

Optimisons un peu tout ça avec un index croissant et unique  sur x :

  • db.carres.ensureIndex({x:1},{unique:true})

Les indexes peuvent être composés, mais il peuvent aussi utiliser les valeurs d’un tableau (souvenez vous des amis d’Azalée) :

  • use meuh
  • db.vache.find({amis:”Pollux”})
  • db.vache.find({amis:”Pollux”}).explain()
  • db.vache.ensureIndex({amis:1})
  • db.vache.find({amis:”Pollux”}).explain()

Le résultat de la fonction explain n’est pas évident à lire à première vue, mais en y regardant de plus près :

  • sans index on constate que dans la première requête (sans index) il y a eu un parcours séquentiel de la collection et deux documents ont été lu.
  • avec index un Btree a été utilisé pour trouver le résultat, et un seul document a été lu.

Pour plus d’information sur les indexes : http://www.mongodb.org/display/DOCS/Indexes

=== Le mot de la fin ===

Le but de ce sujet n’est pas de vous “convertir” à mongoDB, pas plus qu’il ne s’agit d’un cours. Je serais d’ailleurs bien mal placé pour cela, étant également en pleine découverte de cet outil. J’ai simplement voulu donner un aperçu de son utilisation, et montrer à quel point il est facile de procéder à quelques tests.

Comme indiqué au début du sujet, ce qui compte, c’est d’élargir son horizon. Il y a un peu de gymnastique cérébrale en vue pour celui qui compte approfondir le sujet, mais depuis le “professeur kawachéplukoi” et son jeu sur une console de jeu très connue c’est à la mode ;)

Sam. Informatique ,

  1. 02/04/2010 à 17:51 | #1

    Ce qui me manque, c’est l’intérêt du NoSQL dans le cadre d’applis “normales”, là où les volumes délirants à la Google ne sont pas impliqués. Jeter une partie des intérêts et de la maturité du SQL par la fenêtre, soit, mais pour gagner quoi ?

  2. 03/04/2010 à 10:08 | #2

    Je ne vais pas répondre sur le “NoSQL”, parce-que c’est un sac dans lequel on trouve pas mal de choses.

    Par contre concernant une base données orientée document comme mongoDB, l’intérêt est que la modélisation des données dans la base est à peu près le reflet de ce que l’on a dans son code en utilisant un ORM. Cela peut d’ailleurs apporter des gains importants de performances en lecture lorsqu’il n’y a pas de jointures à faire.

    Ma principale motivation est la curiosité intellectuelle. Je trouve cela très intéressant et vais continuer à garder un oeil dessus, mais je ne prône pas le remplacement à outrance des bases de données “traditionnelles”.

    Maintenant pour de petits volumes, pour lequel aucune réplication n’est prévue, l’intérêt est très limité, et la sécurité douteuse.

  3. 05/04/2010 à 22:25 | #3

    (2è essai, j’ai dû oublier de cliquer la première fois).

    Les bases “orientées document”, ça me laisse assez rêveur. En caricaturant, ça donne ça :
    http://www.courtois.cc/blogeclectique/index.php?post/2008/10/22/518-comment-ne-pas-utiliser-une-base-de-donnees Il y avait une discussion sur Slashdot cet été à ce propos, et j’avais tendance à approuver ceux qui considéraient que la structuration directe en relationnel (en SQL donc, par abus de langage) étaient quand même le plus intelligent et même le plus facile au final.

    Même sans ça, tout en étant d’accord que ça mérite un coup d’œil par curiosité intellectuelle, et que cela peut se justifier pour certaines applications aux données massives et jetables (Twitter, Google), j’ai quand même du mal à justifier de fiche en l’air toute la compatibilité avec les outils existants basés sur le SQL.

  4. 07/04/2010 à 10:55 | #4

    La caricature va un cran trop loin car dans ce cas les données sont dans un container opaque, il est impossible de faire des requêtes les exploitant comme critère.

    Concernant le “fiche en l’air toute la compatibilité…” c’est du cas par cas. De toute manière je ne prône pas l’abandon du SQL, des SGBDR, pas plus que je n’incite à se jeter sur mongoDB et autres outils similaires. Juste la curiosité ;)

Les commentaires sont fermés.