Skip to content

Instantly share code, notes, and snippets.

@Arthur
Created December 17, 2009 14:38
Show Gist options
  • Save Arthur/258782 to your computer and use it in GitHub Desktop.
Save Arthur/258782 to your computer and use it in GitHub Desktop.

!SLIDE

Introduction aux bases de données non relationnelles

!SLIDE

Plan

  1. Base de données relationnelles ?
  2. NoSQL : clé-valeur
  3. NoSQL : "clé-valeur + find" ou "bdd orientée document"

!SLIDE

Base de données relationnelles ?

En gros ce qui fait du SQL.

MySQL, SQLite et d'autres.

Caractéristiques :

  • Schéma figé
    • champs des tables,
    • relations entre les tables.
  • permet de faire des find avec des conditions sur les champs, dans le langage SQL.
  • permet de faire des requêtes complexes (JOIN etc..).

!SLIDE @@@ sql

SELECT * FROM account_visits WHERE ( account_visits.item_id = 199 AND account_visits.item_type = 'ForumTopic' AND (account_visits.account_id = 2) ) LIMIT 1

@@@

!SLIDE @@@ sql

SELECT albums.id AS t0_r0, albums.created_at AS t0_r1, albums.kind AS t0_r2, albums.name AS t0_r3, albums.messageid AS t0_r4, albums.account_id AS t0_r5, albums.public AS t0_r6, albums.pictures_count AS t0_r7, albums.pictures_count_valid_date AS t0_r8, albums.pictures_comments_count AS t0_r9, albums.pictures_comments_count_valid_date AS t0_r10, albums.shared_persons_count AS t0_r11, accounts.id AS t1_r0, accounts.email AS t1_r1, accounts.remember_token AS t1_r2, accounts.remember_token_expires_at AS t1_r3, accounts.wifirstsite_id AS t1_r4 FROM albums LEFT OUTER JOIN accounts ON accounts.id = albums.account_id WHERE (public = 1 AND accounts.wifirstsite_id = 208) ORDER BY created_at DESC LIMIT 0, 10 @@@

!SLIDE

Problèmes :

  • requêtes complexes.
  • performances.
  • schéma "figé".
  • scalabilités (migrations de grosses base de données pas simple).

!SLIDE

Une autre approche : le système de clé - valeur.

##Le plus simple : Memcached.

  • Très rapide.
  • Scalable très simplement (côté client).
  • limité set, get.

Mais pas de persistance :

  • pleins de projets pour ajouter de la persistance (MemCacheDB par exemple)

!SLIDE

les clés valeurs, c'est bien, mais un peu limité.

Même memcache va plus loin :

  • incr, decr.

Encore mieux : REDIS

  • STRING
  • LIST
  • SET

Avec toutes les opérations que l'on peut imaginer dessus.

  • SET GET INCR DECR... pour les STRING (comme memcache)
  • R/LPUSH R/LPOP RANGE INDEX ... pour les LIST
  • ADD REM ISMEMBER INTER UNION DIFF pour les SET

Et beaucoup d'autres.

Et en plus c'est vraiment très performant, car tout est en RAM (du coup il en faut beaucoup), et persistance asynchrone.

!SLIDE

les bases de données document-oriented.

des documents schéma-free :

  • un conteneur sans champs prédéfinis,
  • que l'on peut créer => id (rarement un int, mais plutôt un uuid)
  • puis updater via l'id.

find ?

Une manière de chercher dans les documents.

La liste des projets est longue :

  • Utiliser MySQL différemment (dénormalisations, sharding, ...).
  • Tokyo Cabinet/Tyrant
  • Voldemort
  • Cassandra
  • CouchDB
  • MongoDB

!SLIDE

  • Tokyo Cabinet/Tyrant, en C/C++ par un japonais, très très performant.
  • Voldemort (je sais même plus...)
  • Cassandra, fait par Facebook, utilisé par d'autres (Digg), à l'air pas mal.
  • CouchDB
  • MongoDB

!SLIDE

CouchDB

BuzzWord dropping:

  • erlang
  • JSON
  • RESTFull
  • MapReduce
  • JavaScript

Demo

!SLIDE

Avantages de CouchDB :

  • JSON, et REST => très pratique, pas besoin de client spécifique.
  • Sofa => très pratique aussi.
  • MapReduce en JS très puissant.
  • Versionning
  • Replication

Problèmes :

  • pas toujours évident de se plier dans le cadre du MapReduce.
  • pas très rapide (pour l'instant) ?

!SLIDE

MongoDB

  • Un intermédiaire entre le relationnel et le non-relationnel
  • Ou : du non-relationnel sans trop se faire de nœuds au cerveau
  • Et en plus c'est très très performant !!
  • Et déjà utilisé en production sur des gros sites (ex: sourceforge, DisqUs, onzeer.com).

!SLIDE

Exemple, en python !!

driver pymongo

@@@ python import pymongo

connection = pymongo.Connection("localhost", 27017) db = connection.test @@@

On récupére la connection, et on se connecte à la base de donnée "test".

!SLIDE code

Mais c'est de la magie en python ????

@@@ python db = connection.test @@@

Version non magique : @@@ python db = connection["test"] @@@

(2 ways to do it ???)

!SLIDE

insertion

@@@ python posts = db.posts post = {"author": "Arthur", "title": "Mon premier post!", "content": "MongoDB c'est extra.", "tags": ["mongo", "nosql"], "date": datetime.datetime.utcnow()} posts.insert(post) @@@

!SLIDE

find

@@@ python for post in posts.find(): print post["title"]

print posts.find().count() @@@

sorting

@@@ python posts.find().sort('date') @@@

pagination

@@@ python posts.find().skip(12).limit(10) @@@

!SLIDE

find avec des conditions

@@@ python print posts.find_one({"author": "someone"})

print posts.find_one({"date": {"$gt": datetime.datetime(2009,12,15,10)}})

des conditions en Js !!

print posts.find({"$where": "this.title.length > 20"}).count()

print posts.find_one({"tags": "nosql"}) @@@

!SLIDE

MongoDB : encore plein d'autre choses :

  • Création d'index.
  • MapReduce avec du JS.
  • Partial update.
  • Query profiling.

!SLIDE

Utiliser MySQL différement

FriendFeed est allé très loin

@@@ sql CREATE TABLE entities ( added_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, id BINARY(16) NOT NULL, updated TIMESTAMP NOT NULL, body MEDIUMBLOB, UNIQUE KEY (id), KEY (updated) ) ENGINE=InnoDB; @@@

!SLIDE

Conclusion

Pour le relationnel

  • Les transactions.
  • Des bases de données très éprouvées.
  • Une manière d'organiser les données bien connue.

Pour le non-relationnel

  • Souplesse de codage.
  • Souplesse pour scaler.
  • Performance dans beaucoup de cas.

!SLIDE

Des liens

delicious.com/arthur.petry/nosql

Des questions ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment