NoSQL
Not only SQL
Un peu d'historique
Carlo Strozzi, 1998 → une BDD "lightweight" open source
"No SQL" ? → Pas de SQL.
"NoRel" ? → devrait être le vrai nom du mouvement NoSQL.
What else ?• BDD orientée documents• BDD orientée objets• BDD orientée colonnes• ...
La vraie différence: A.C.I.D.
Atomicité → Transactions (un groupe d'opérations, une échoue, tout doit pouvoir être annulé).
Cohérence → Pas d'état incohérent à la fin d'une transaction (contraintes).
Isolation → Pas de dialogue entre les transactions. Gestion des conflits ? Lock :(
Durabilité → À la fin d'une opération, les données sont persistées (coupure de courant = pas de perte de données).
http://en.wikipedia.org/wiki/ACID
Et alors ?
A.C.I.D. c'est cool, mais...
→ L'atomicité et surtout l'isolation sont des freins à la distribution des données.
→ Performances ?
http://dbmsmusings.blogspot.com/2010/08/problems-with-acid-and-how-to-fix-them.html
http://highscalability.com/drop-acid-and-think-about-data
google "pupples nosql". What ?
Théorie de la distribution des donnéesNoSQL s'affranchit de la contrainte "A.C.I.D."
Le théorème "C.A.P." d'Eric Brewerhttp://www.julianbrowne.com/article/viewer/brewers-cap-theorem
http://fr.wikipedia.org/wiki/Th%C3%A9or%C3%A8me_CAP
On ne peut pas tout avoir :)
→ Consistency→ Availability→ Parition ToleranceSeulement 2 à la fois peuvent être garantis au même instant.
Le deuil de la cohérence à tous prix
Accepter que le système sera "probablement cohérent".
→ Mais on n'est pas obligé de distribuer les données !
http://davidmasclet.gisgraphy.com/post/2010/06/09/10-minutes-pour-comprendre...NoSQL
Performances: le nerf de la guerre ?→ On peut toujours optimiser une solution SQL.→ MySQL & PostgreSQL & cie offrent de très bonnes solutions de réplication.
Alors pourquoi NoSQL ?
→ Meilleures performances "out of the box" ? À voir...
→ MAIS ÇA NE DOIT PAS ÊTRE LE SEUL CRITÈRE
→ NoSQL = Un autre mode de pensée
Les différentes familles
• Colonnes: Google's BigTable, HBase, Cassandra...Voir ça comme un gros fichier CSV.
• Graphes (Euler): Neo4JIdéal pour représenter un réseau.
• Clé-Valeur: Riak, Voldemort, Redis...Voir ça comme un gros tableau associatif. Basique, efficace.
• Documents: CouchDB, MongoDB...Un entrepôt de "documents" (objets anonymes).
Toutes sont schemaless
Et la vraie vie ?
Twitter→ MySQL pour le stockage des tweets→ Pour tout le reste (logs, géolocalisation, tous les nouveaux services) c'est Cassandra
FacebookCréateur de Cassandra (open-sourcé en 2008)http://cassandra.apache.org/
Diigo & AmazonCassandra aussi
Google App EngineBigTable
MongoDB
Orienté documents. Un bon exemple : une boutique hétéroclite.Le panier :
• 2 livres• 1 t-shirt rouge XL• 2 pneus en 255 55 R16 91V
Super chiant à modéliser. Pas de schéma ? Cool !
MongoDB : JSON powa
> user = { name: "johndoe", panier: null }{ "name" : "johndoe", "panier" : null }> user.panier = [];[ ]> user.panier.push({ type: "livre", titre: "Élever des poneys avec amour" })1> user.panier.push({ type: "livre", titre: "L'art tu tartare de cheval" })2> user.panier.push({ type: "t-shirt", taille: "XL", couleur: "rouge" })3> user.panier.push({ type: "pneu", dimension: { largeur: 255, diameter: 55, ratio: 16, charge: 91, vitesse: "V" } })4> user.panier[3].count = 2;
MongoDB : JSON powa > user{
"name" : "johndoe",
"panier" : [
{
"type" : "livre",
"titre" : "Élever des poneys avec amour"
},
{
"type" : "livre",
"titre" : "L'art tu tartare de cheval",
"count" : 2
},
{
"type" : "t-shirt",
"taille" : "XL",
"couleur" : "rouge"
},
{
"type" : "pneu",
"dimension" : {
"largeur" : 255,
"diameter" : 55,
"ratio" : 16,
"charge" : 91,
"vitesse" : "V"
}
]}
MongoDB : requêtage
> db.users.save(user)
> db.users.findOne()
> db.users.find({"name": "johndoe"}).limit(1)
http://www.mongodb.org/display/DOCS/Querying
MongoDB : edit-in-place
> db.counters.save({ name: "X", n: 0 }) > c = db.counters.findOne({ name: "X" }){ "_id" : ObjectId("4d6eb03f089b38a5a40e543d"), "name" : "X", "n" : 0 }> value = c.n++ // ancienne valeur + incrément0 > db.counters.save(c) // nouvelle valeur: 1 > value = db.counters.findAndModify({ query: { name: "X" }, update: { $inc: { n: 1 } } }).n // nouvelle valeur: 21 // ancienne valeur http://www.mongodb.org/display/DOCS/findAndModify+Command
Redis
INCR compteur
Du relationnel avec un système clé-valeur ? Why not ?
SET post:33:title "Coucou gamin"
SET author:1:name "Toto Laptop"SET author:1:nickname "toto42"RPUSH author:1:posts "post:33"
http://redis.io/
Très simpl(ist)e, mais très puissant
Benchmark
→ Insérer plein d'articles, avec des commentaires.→ Récupérer tous les articles d'un auteur donné, avec le nb de commentaires.
Pour changer → Python :)
time mongo mongodb_insert_noindex.js> 1.419stime python mongodb_insert_noindex.py> 0.580s
OK, ne nous fions pas au client par défaut pour les tests :)
Benchmark (à prendre avec des grosses pincettes)
MySQL
InnoDB indexé
MySQL
MyIsam sans index
MongoDB
indexé
MongoDB
non indexé
Redis
Insertion
10'000 articles30'000 commentaires
6200 ms 5200 ms 570 ms 590 ms 10500 ms
Lecture
Les 100 premiers posts d'un auteur avec le nombre de commentaires par post.
100 ms(puis ~45 ms avec cache de requête)
110 ms(puis ~45 ms avec cache de requête)
290 ms 380 ms 40 ms
WTF ??? C'est pas magique alors ?
Mais alors, si ça booste pas, ça pux ?Le clé-valeur reste IMBATTABLE en lecture. → I18N ? Préférences utilisateur ? Listes, scores...
La comparaison doit se faire sur le fonctionnelhttp://www.mongodb.org/display/DOCS/MongoDB,+CouchDB,+MySQL+Compare+Grid
Procédures stockées ? Map/Reduce est plus simple, plus souple, probablement plus puissant...
SQL reste à mon avis le meilleur langage de requêtage.
Open your mind, mec !
Oubliez un peu le relationnel !Ou alors... Oubliez NoSQL :)
Mais on a toujours de relations !
Ah bon ? Réfléchis encore...
Ouais mais tous ces trucs de données distribuées...
YAGNI ? Oui, mais ça marche dans les deux sens...
NO QUESTION !