!SLIDE
!SLIDE
- Base de données relationnelles ?
- NoSQL : clé-valeur
- NoSQL : "clé-valeur + find" ou "bdd orientée document"
!SLIDE
MySQL, SQLite et d'autres.
- 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
- requêtes complexes.
- performances.
- schéma "figé".
- scalabilités (migrations de grosses base de données pas simple).
!SLIDE
##Le plus simple : Memcached
.
- Très rapide.
- Scalable très simplement (côté client).
- limité
set
,get
.
- pleins de projets pour ajouter de la persistance (MemCacheDB par exemple)
!SLIDE
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 lesSTRING
(comme memcache)R/LPUSH R/LPOP RANGE INDEX ...
pour lesLIST
ADD REM ISMEMBER INTER UNION DIFF
pour lesSET
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
- 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.
Une manière de chercher dans les documents.
- 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
- erlang
- JSON
- RESTFull
- MapReduce
- JavaScript
!SLIDE
- 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
- pas toujours évident de se plier dans le cadre du MapReduce.
- pas très rapide (pour l'instant) ?
!SLIDE
- 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
@@@ 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
@@@ python db = connection.test @@@
Version non magique : @@@ python db = connection["test"] @@@
(2 ways to do it ???)
!SLIDE
@@@ 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
@@@ python for post in posts.find(): print post["title"]
print posts.find().count() @@@
@@@ python posts.find().sort('date') @@@
@@@ python posts.find().skip(12).limit(10) @@@
!SLIDE
@@@ python print posts.find_one({"author": "someone"})
print posts.find_one({"date": {"$gt": datetime.datetime(2009,12,15,10)}})
print posts.find({"$where": "this.title.length > 20"}).count()
print posts.find_one({"tags": "nosql"}) @@@
!SLIDE
- Création d'index.
- MapReduce avec du JS.
- Partial update.
- Query profiling.
!SLIDE
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
- Les transactions.
- Des bases de données très éprouvées.
- Une manière d'organiser les données bien connue.
- Souplesse de codage.
- Souplesse pour scaler.
- Performance dans beaucoup de cas.
!SLIDE