04
MARS

NoSQL - MongoDB et PHP: Première approche

Publié le 04/03/10 à 09h49 par DJo

NoSQL et MongoDB ne vous dise probablement pas grand chose, mais cela va changer !

NoSQL - MongoDB

NoSQL

Si le mot NoSQL ne vous dit rien pour le moment, la tendance devrait bientôt changer dans peu de temps. NoSQL ou "Not only SQL" est un mouvement très récent (2009), qui vous l'aurez compris, concerne les bases de données.

L'idée du mouvement est simple: Proposer des alternatives aux bases de données relationnelles pour coller aux nouvelles tendances et architectures du moment, notamment le Cloud Computing.

Les axes principaux du NoSQL: haute disponibilité et partitionnement des données, au détriment de la consistance.

Alors que les bases de données relationnelles actuelles sont basées sur le concept ACID (Atomicité, Consistance, Isolation, Durabilité), le NoSQL prône l'abandon de ces contraintes.

Le NoSQL s'annonce donc comme une réponse aux limites du relationnel et du monde ACID. Et les géants du web l'ont bien compris, tous abandonnent petit à petit leur BDD relationnelle au profit des principes du NoSQL:

  • Google et BigTable
  • Amazon et SimpleDB
  • Facebook et Cassandra
  • LinkedIn et Voldemort
  • Etc.

 

MongoDB

Aujourd'hui, nous allons nous intéresser à une base de données NoSQL qui commence à gagner en maturité: MongoDB.

MongoDB est une base de données "orientée document". Totalement open-source, cette dernière est développée en C++.

Contrairement à MySQL par exemple, MongoDB va stocker des données sous forme de JSON.

Comme toutes bases de données, il sera possible d'effectuer des requêtes dynamiques pour récupérer vos données, définir des index pour améliorer les performances, insérer des données et les mettre à jour etc. La grande différence avec MySQL, c'est sans doute l'absence de tables.

En effet, vous n'aurez pas à créer un schéma de BDD à respecter. Tout est dynamique, vous pourrez à tout moment créer de nouvelles propriétés, sans pour autant perdre en performances ! Pour comprendre, rien de mieux qu'un exemple pratique.

Comparons MongoDB et MySQL sur un exemple simple: Des articles liés à des commentaires. Avec MySQL, nous aurions été obligé dans un premier temps de créer deux tables:

article

  • id
  • titre
  • texte
  • date
  • auteur

commentaire

  • id
  • article_id
  • texte
  • date
  • auteur

Puis nous aurions inséré les données avec une requêtes INSERT INTO. Avec MongoDB, la stracture est créée automatiquement à la première insertion et peut changer à tout moment, exemple:

var article = { titre: 'MongoDB exemple', 
        texte: "Ceci est un test d'article pour tester MongoDB", 
        date: new Date('03-03-2010'), 
        auteur: 'DJo',
        comments : [ { text: 'Super article !!', date: new Date('03-04-2010'), auteur: 'Toto' },
                 { text: 'Je confirme, le NoSQL ça déchire !', date: new Date('03-04-2010'), auteur: 'Novaway' }]
        }
db.articles.insert(article);

Et voilà, nous avons stocké nos données article et commentaire dans MongoDB. Pratique non ?

Vous aurez remarqué qu'on ne spécifie pas d'id aux éléments. Cette tâche est automatiquement effectuée par MongoDB.

Un champ "_id" est présent pour chaque donnée afin de conserver l'identification et l'unicité des données.

MongoDB n'utilise pas des tables, mais des collections. En faisant db.articles.insert, nous avons inséré les données dans la collection "articles".

 

Maintenant, comment récupérer notre article ?

Avec MySQL nous aurions fait un simple SELECT sur la table article, avec MongoDB voilà comment faire:

db.articles.find( { titre: 'MongoDB exemple' }, { comments: 0 } );

Ici, nous allons chercher les articles dont le titre est "MongoDB exemple". Nous voudrons récupérer tous les champs, sauf les commentaires, d'où le comments: 0.

 

Vous pouvez essayer de manipuler les données sur le shell MongoDB de démo.

Pour en savoir plus sur le fonctionnement de la BDD, allez consuter le manuel, il est bien documenté et facile à comprendre.

 

MongoDb et PHP

La question qui doit vous venir à présent est: Mais comment utiliser MongoDB avec mon site PHP ?

La réponse est simple: En utilisant le driver MongoDB de PHP.

En effet, PHP intègre directement une classe Mongo permettant d'intéragir avec la base de données.

 

Se connecter à la base MongoDB en PHP

Première étape, la connexion à votre BDD locale:

$con = new Mongo(); // Connexion sur localhost:27017

 

Choisir la bases de données sur laquelle travailler

Comme pour MySQL, nous devons spécifier quelle base utiliser:

$db = $con->nombasededonnees;

 

Insérer des données dans une collection MongoDB en PHP

Reprenons notre exemple et insérons dans la base notre article et ses commentaires:

$article = array("titre" => 'MongoDB exemple', 
             "texte" => 'Ceci est un test d'article pour tester MongoDB', 
             "date" =>  '2009-03-03', 
             "auteur" => 'DJo',
             "comments" => array(
                  array("texte" => 'Super article !!', 
                    "date" => '2009-03-04',
                    "auteur" => 'Toto'),
                 array("texte" => 'Je confirme, le NoSQL ça déchire !', 
                    "date" => '2009-03-04',
                    "auteur" => 'Novaway')
             )
        );

$db->articles->insert($article);

 

Sélectionner une collection en PHP

Nous souhaitons à présent récupérer la collection de nos articles:

$collectionArticles = $db->articles;

 

Sélectionner une valeur d'une collection MongoDB

Maintenant, nous allons récupérer l'article que l'on souhaite afficher:

$query = array( "titre" => "MongoDB exemple");
$champs = array('comments' => 0);
$article = $collectionArticles->findOne($query, $champs);

En retour, vous obtiendrez un tableau associatif de votre article.

 

Créer un index sur un champ MongoDB

Pour optimiser les performances de sélection de vos données, il faudra ajouter un index sur le titre des articles, voici comment le faire:

$collectionArticles->ensureIndex( array( "titre" => 1 ) ); 

Les index sont indispensables pour les requêtes en lecture, mais peuvent ralentir les insertions. Il faut donc les utiliser à bon escient.

 

Voici quelques exemples d'utilisation, retrouvez toutes les méthodes sur la documentation officielle de PHP.

Alors que pensez-vous de MongoDB ?

Prochainement, nous verrons plus en détail la BDD Cassandra récemment adoptée par Facebook.

 

Gérer votre base de données MongoDB visuellement

Comme MySQL et phpMyAdmin, il existe des plateformes PHP pour gérer votre base de données MongoDB visuellement:

Opricot: Outil permettant de faire les commandes basiques pour gérer votre MongoDB

Opricot - MongoDB

 

PHPMoAdmin: L'alternative à phpMyAdmin pour MongoDB

phpMoAdmin - MongoDB

Baraguiné par dmathieu le 04/03/10 à 10h50
dmathieu via Twitter
Le NoSQL est très récent ... sur le web.
Ce n'est pas un concept récent en dehors du web bien au contraire. C'est un concept qui avait été oublié avec l'avènement des technologies web au "profit" de SQL.
Baraguiné par DJo le 04/03/10 à 10h51
DJo sur La Ferme du Web
T'es sur la Ferme du Web ici :D Effectivement, je ne parle que du Web.
Merci pour tes précisions ;)
Baraguiné par bwhades le 04/03/10 à 10h54
bwhades sur La Ferme du Web
Bonjour et merci pour cette article.
J'apprécie beaucoup les articles habituels qui présentent un service Web ou autre, mais ce type d'articles décrivant un peu plus un sujet (qui se rapproche d'un dossier) est très intéressant aussi.
Surtout que le sujet est très bien trouvé.

Existe-t-il des applications équivalentes à phpMyAdmin pour MongoDB ?
Baraguiné par nazab le 04/03/10 à 11h02
nazab via Twitter
Ça ressemble un peu a un ORM natif dans PHP... Si c'est bien équivalent attention le doctrine et autre propel.
Baraguiné par DJo le 04/03/10 à 11h06
DJo sur La Ferme du Web
@bwhades: Oui je les ai rajouté au billet.
Baraguiné par stailer le 04/03/10 à 11h07
stailer sur La Ferme du Web
Mouais... Mais qu'en est il des requêtes vraiment complexes ? COmment effectuer des jointures ? Ou sont toutes les fonctions internes fournies (gestion des dates, des nombres) ?

Quand tu dis "pas de structure"... Si il en faudra une à travers des classes.
Par exemple pour effectuer un traitement chaque fois que l'on nourrit le champs "date_de_naissance" d'une collection ou qu'on le récupère. Sur le set on pourrait vouloir formatter la date en anglais et sur le get la récupérer dans le format français.

Bref, beaucoup de questions se posent dans le cadre d'une application complexe.
C'est vrai qu'on en parle beaucoup et que le concept est porteur, mais pour le moment, à travers les docs proposées je ne vois rien qui remplace suffisamment un SGBDR.

Pour finir et c'est peut-être uniquement une histoire de gout : je trouve la lisibilité du code infâme par rapport au SQL ou mieux : par rapport à un ORM.
Pour PHP/MySQL, la librairie Doctrine permet de simplifier et automatiser les choses d'une manière phénoménale par exemple.
Baraguiné par DJo le 04/03/10 à 11h12
DJo sur La Ferme du Web
Tu as une structure dans ton code, mais tu ne définis rien réellement sur la BDD.
Les NoSQL ont encore leurs preuves à faire sur le web, il faut voir comment ils évoluent.
Personnellement, j'aime beaucoup la façon de faire. Je préfère largement la syntaxe au SQL. Mais c'est une question de goûts :p
Merci pour tes remarques.
Baraguiné par bwhades le 04/03/10 à 11h22
bwhades sur La Ferme du Web
Merci pour les précisions des "équivalents" à phpMyAdmin. Et merci aux autres commentateurs pour leurs remarques pleines d'expériences..
Baraguiné par TheSorrow le 04/03/10 à 11h38
TheSorrow sur La Ferme du Web
Je préfère quand même CouchDb qui fait maintenant parti de la fondation Apache. J'ai rien contre les mecs de chez 10gen mais bon Apache c'est plus rassurant :)
Et apparement mongoDb ne se positionne pas comme un conteneur d'application comme le propose Couchdb avec CouchApp, ce qui est dommage à l'heure du cloud computing :)
Baraguiné par le 04/03/10 à 12h08
Merci d'avoir aborder ce sujet trés porteur!
C'est intéressant de connaitre une alternative à MySQL, surtout aprés le rachat par Oracle.
Baraguiné par spidergrosben le 04/03/10 à 12h18
spidergrosben via Twitter
A priori, quand on code, il vaut mieux encapsuler les accès base dans un ou 2 objets voir utiliser un ORM. Il ne devrait donc pas être trop difficile de passé à ce genre de base si le besoin s'en fait sentir, ne serait ce que pour la tester.

Le seul hic doit être les migrations de base complexes (Nombreuses tables
Baraguiné par spidergrosben le 04/03/10 à 12h21
spidergrosben via Twitter
Je reprends ...

Le seul hic doit être les migrations de base complexes (Nombreuses tables et nombreux enregistrements) qui doit être une vraie galère.

Une chose que je ne saisie pas. On a bien vu comment gérer les relations 1-N, mais comment gère-t-on les relations N-N ? Et de même, si l'on souhaite récupérer un enregistrement précis a-t-on accès au champs _id ?
Baraguiné par posykrat le 04/03/10 à 13h15
posykrat via Twitter
Très intéressant mais je reste un peu sur ma faim pour savoir comment s'est gérable sur un site complexe.
Baraguiné par DJo le 04/03/10 à 13h17
DJo sur La Ferme du Web
Je ferais peut être un tuto plus avancé avec un cas concret. Là c'était plus une introduction :) Mais je vois que ça à l'air de vous intéresser.
Baraguiné par zetoun17 le 04/03/10 à 15h10
zetoun17 sur La Ferme du Web
au premier coup d'oeil ce systeme me parait quand meme beaucoup plus gourmand en ressources cpu et place disque. un petit comparatif avec mysql serait le bienvenu :)
Baraguiné par gLUK le 04/03/10 à 16h32
gLUK sur La Ferme du Web
Intéressent...
Effectivement cette facon de faire doit encore murire.
on doit prendre en compte les contraintes liées au schéma de données, pour ne pas se retouver avec des champs à tir la rigot !
il faudra peut être s'appuyer sur des "bean" à la mode JAVA pour ne pas tomber dans le panneau et garantir une cohérence sur le nom des champs.
Pour ma part, j'utilise un petit ORM pour php qui s'appel PHPSIMPLEDB, il ne défraye la chronique en terme de performance, mais si le site est bien fait on a généralement pas besoin de remonter des milliers d'enregistrements. C'est un choix personnel à faire entre performance et maintenabilité !

Article intéressant :)
Baraguiné par PastisD le 04/03/10 à 18h48
PastisD sur La Ferme du Web
un p'ti pdf qui montre une requête SQL transformé en MongoDB :)
http://rickosborne.org/download/SQL-to-MongoDB.pdf
Baraguiné par le 06/03/10 à 10h52
Un des avantages de CouchDB face à MongoDB c'est qu'il respecte les transactions et les propriétés ACID.

Ajouter un Commentaire

Pour poster un commentaire, vous devez être identifié. Vous pouvez choisir parmi ces trois méthodes d'identification:

Compte la Ferme du Web

Identifiez-vous
Inscrivez-vous

Compte Facebook

Compte Twitter

Connexion avec votre compte twitter
Rechercher sur la Ferme du web