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.
Baraguiné par olivierb le 23/09/10 à 18h32
olivierb via Twitter
Moi je travaille depuis quelques temps avec mongoDB et j'adore à tel point cette base noSQL que je ne code plus du tout avec MySQL

Un exemple de ce que j'ai fait avec mongodb : http://solimap.com
Baraguiné par le 29/09/10 à 17h11
C'est vraiment sympa MongoDb, je le test depuis quelque temps et j'ai de bon résultat.

Il existe MongoVUE comme GUI : http://blog.mongovue.com/

Par contre tu ne parles pas du Sharding et Replica qui sont la force de MongoDB.
Baraguiné par le 24/08/11 à 14h21
Vous pouvez testez gratuitement mongoDB sur MongoOd Merci pour vos retours
Baraguiné par le 24/08/11 à 14h23
ah zut le lien est mal passé ! l'url est : http://mongood.com
Baraguiné par pons_thomas le 19/01/13 à 00h32
pons_thomas via Twitter
Un ORM pour MongDB me dérange quelque peu ! L'avantage d'une base NoSQL et de mongoDB en particulier c'est qu'il est schemaless ! Deux document d'une même collection peuvent avoir des propriétés commune ou différente.

Si mon document user posséde un attribut age mais que mon autre document user n'en possède pas, l'orm ajoutera-t-il null ou "" à un nouveau document user ou n'ajoutera pas d'attribut inutilisé !

Si le premier cas s'avére vrai alors l'ORM est à bannir ! On se trompe de philosophie !!!!!!!!
Baraguiné par shadoo le 03/05/13 à 01h12
shadoo sur La Ferme du Web
Le NoSQL effectivement est très porteur et nous en entendons de plus en plus parler. J'apprends petit à petit le NoSql quand j'ai le temps. Mais j'ai lu pas mal de conneries sur les commentaires franchement.

Déjà d'une au diable les "moi j'adore le NoSQL je ne jure que par lui et by by le SQL" C'est bon... Ce genre de commentaire partisan n'aide en rien et si on est professionnel dans le web on n'utilise pas une technologie par effet de Mode ! Comme Github, composer, zend ou symfony quand on entendait parler de plus en plus d'eux (alors que dans ma boite on bossait déjà avec symfony 1 et que peu de personnes connaissaient) on a vue pas mal de boite où développeur utiliser des outils qui ne correspondaient en rien aux besoins qu'ils avaient. Allo quoi ! (;))

Pourquoi utiliser du NoSQL ?
Déjà sans vouloir suivre une mode dites-vous bien que le NoSQL rencontre de bien meilleur performances en terme de monté en charge et convient tout à fait sur la gestion de données à grande échelle. Donc Voilà déjà pourquoi faut s'intéresser à une techno plutôt que de vouloir passer à cette dernière tout simplement car le code nous plait plus.

Pourquoi j'entends parler d'ORM ? Bien sûr il y a pas mal de question que l'on peut se poser lorsque l'on est habitué aux SGBR avec un modèle ACID. Mais oubliez ! Il faut raisonner autrement ! Avant de venir cracher dans la soupe.
En ce qui concerne l'utilisation d'un ORM, je redemande pourquoi ???
1- On manipule déjà des objets et avec les ORM on manipule quoi ?... Des objets aussi

2- Les ORM tout comme les class abstractive SQL ont été créé pour résoudre un problème de compatibilité de CODE SQL ! Donc avoir une interopérabilité entre les différentes SGBD.
Et là on a quoi ???? Du SQL peut être ??! Ouvrez les yeux bon sang.
C'est comme pour le concept ORM, il ne faut plus penser table mais Entité et objets et bien là ça va être pareil, il faudra penser différemment.

Le NoSQL vaut le fait que l'on puisse se pencher dessus sérieusement et on en entends parler car depuis la mode du "Cloud" (en gros tout sur hébergement online décentralisé Qui équivaut en fait au Web 2.0 que l'on annoncait déjà il y a quelques années), il y a eu un besoin d'aller chercher un système de storage économique et plus performant que ce que l'on connaissait jusqu'à présent.

Donc à méditer et attendre un peu plus de maturité, c'est comme pour le HTML5 bien que IE ait fait pas mal d'éffort là dessus on est encore loin de pouvoir utiliser toutes les balises et potentiel du HTML5

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

Connexion avec Facebook

Compte Twitter

Connexion avec votre compte twitter
Rechercher sur la Ferme du web