JustMarried : conception de la base de données (SQL -> NoSQL)

View Comments

Avant de débuter le développement des pages du site, je souhaiterais un peu m’attarder sur la base de données. J’ai lu des dizaines d’articles sur les bases de données NoSQL, mais je n’en ai encore réellement utiliser aucune (juste quelques requêtes de test en PHP il y a quelques mois). Je vais dans un premier temps concevoir la base de données comme si j’allais l’implémenter avec une base de données relationnelle, puis la modifier pour son implémentation avec MongoDB.

Rien qu’en regardant la page d’accueil du site VieDeMerde.fr, on peut rapidement en extraire les entités que nous aurons besoin de stocker et leurs relations entre elles pour en concevoir un schéma relationnel simple.

  • Les Catégories (categories) : sert à organiser nos histoires.
  • Les Histoires (posts): appartiennent à une et une seule catégorie, et peut ne pas voir d’utilisateur lié (on peut poster une histoire sans créer de compte).
  • Les Utilisateurs (users) : il faut s’inscrire au site pour commenter les histoires.
  • Les Commentaires (comments).
  • Les Votes (votes) : un vote peut être négatif ou positif et avoir un poids différent suivant l’action (ou autres paramètres). Un internaute ne pourra voter qu’une seule fois, nous utiliserons les cookies pour gérer cette restriction.


Schéma relationnel


Du SQL au NoSQL

MongoDB est une base de données dite « schema-less » ou « document-oriented », c’est à dire que la structure d’une table (on appelle plutôt cela des collections dans MongoDB) n’est pas fixe. On dit que l’on stocke des documents dans ces collections. Chaque document d’une même collection peut avoir un format différent. Ça, c’est pour la théorie ! Dans notre pratique, on va définir (à notre niveau, pas au niveau de la base de données) un schéma/format pour nos documents.

MongoDB ne gère pas les relations entre les collections, et ne permet pas de faire de jointure comme cela est possible en SQL. Il faut donc limiter les entités différentes (collections), et embarquer (embed in english) des entités dans une autre entité. Cela n’est pas très clair, alors je vais essayer de donner un exemple.

Dans notre version SQL, nous avons une table des Histoires et une table des Commentaires avec une relation entre les 2 tables.

Dans notre version NoSQL/MongoDB, nous allons embarquer les Commentaires dans nos Histoires, comme suit (les documents dans MongoDB sont stockés au format Binary JSON) :

post = {
  '_id': ObjectID('XXXXX'),
  'content': 'Lorem ipsum post 1',
  'comments': [
    { 'comment': 'Lorem ipsum comment 1' },
    { 'comment': 'Lorem ipsum comment 2' }
  ]
}

En effet, on souhaite rarement récupérer les Commentaires en dehors du contexte de leurs Histoires associées.

Nous allons donc embarquer dans nos Histoires les Commentaires et les Votes associés.  Dans certains articles que j’ai lu, les auteurs embarquaient aussi les catégories, mais je ne souhaite pas le faire pour le moment.  Nous aurons donc une représentation BSON équivalente à ce qui suit pour les documents que nous stockerons dans la collection des Histoires.

post = {
  '_id': ObjectID('XXXXX'),
  'content': 'Lorem ipsum post 1',
  'created_at': '2010-07-22 12:00:00',
  'category_id': ObjectID('XXXXX'),
  'user_id': ObjectID('XXXXX'),
  'comments': [
    {
      'comment': 'Lorem ipsum comment 1',
      'user_id': ObjectID('XXXXX'),
      'created_at': '2010-07-22 12:00:00'
    },
    {
      'comment': 'Lorem ipsum comment 2',
      'user_id': ObjectID('XXXXX'),
      'created_at': '2010-07-22 12:00:00'
    }
  ]
}

Et pour finir les représentation BSON des documents pour les collections des Utilisateurs et des Catégories.

category = {
  '_id': ObjectID('XXXXX'),
  'name': 'Category name'
}
user = {
  '_id': ObjectID('XXXXX'),
  'login': 'myPseudo',
  'password': 'XXXXX',
  'email': 'user@domain.tld',
  'cookie_unique_id': 'XXXX',
  'created_at': '2010-07-22 12:00:00'
}

Dans un prochain article, je parlerais de la partie ‘requêtage’ de MongoDB.  A partir de la console de MongoDB, j’insèrerai un jeu de données de test dans ma base de données, et je listerai les différentes requêtes qui seront utilisées par l’application Symfony2.


Ressources
Je me suis servi des articles/documents suivants pour modéliser la base de données dans sa version NoSQL.

Partager:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • email
  • MySpace
  • Netvibes
  • Ping.fm
  • Technorati
  • Tumblr
  • Wikio FR
  • Yahoo! Buzz

Articles similaires:

  1. JustMarried : projet Symfony2 + MongoDB (via Doctrine)
  2. DailyQuote : Changement de techno !
  3. Nouveau projet : nom de code « DailyQuote »
  4. Quoi de neuf développeur ?
  5. DailyQuote : Environnement et outils de développement

View Comments (+add yours?)

  1. vince
    juil 21, 2010 @ 13:29:00

    yeahhhhhhh, bon article, mais question !!!!!!!!!! Il te sert à quoi le champ cookie unique id ???

  2. popofr13
    juil 22, 2010 @ 07:56:04

    C'est pour empêcher qu'un internaute/utilisateur ne vote plusieurs fois pour une même histoire. Quand un internaute arrive sur le site, si le cookie n'existe pas tu le crée.

  3. Adrien
    juil 22, 2010 @ 11:50:00

    Bonne continuation avec MongoDB :-)
    C'est un superbe outil que j'ai exploité de fond en comble, je vais faire quelques articles dessus tiens :)

    VIvement la 1.6 !

  4. popofr13
    juil 22, 2010 @ 12:02:09

    Merci.

    Faites moi signe lorsque les articles seront publiés : je suis intéressé !

    Que'est ce qui est prévu dans la 1.6 ?

  5. Adrien
    juil 22, 2010 @ 12:07:51

    Des Replicas Pairs remplacés par les Replicas Sets, un auto-sharding utilisable en production, des capped collections basées sur un TTL…

    On verra déjà pas mal de tout ça avec la 1.5.3, mais pas vraiment production ready…

Leave a Reply

You must be logged in to post a comment.

blog comments powered by Disqus