Skip to content

Instantly share code, notes, and snippets.

@kipavy
Created February 17, 2026 09:32
Show Gist options
  • Select an option

  • Save kipavy/1a87d401cb846bfb05ca782aaa628241 to your computer and use it in GitHub Desktop.

Select an option

Save kipavy/1a87d401cb846bfb05ca782aaa628241 to your computer and use it in GitHub Desktop.

Recap NoSQL + Neo4j - Fiche de revision


Table des matieres

  1. Introduction au NoSQL
  2. Theoreme de CAP
  3. Fondements techniques
  4. Les 4 types de BD NoSQL
  5. Neo4j et Cypher

1. Introduction au NoSQL

Pourquoi le NoSQL ?

Les SGBD relationnels (SQL) atteignent leurs limites face aux besoins modernes :

Probleme Explication
Volume massif Google, Facebook, Amazon gerent des petaoctets de donnees
Distribution Donnees reparties sur des milliers de serveurs (data centers)
Objets complexes Donnees heterogenes, imbriquees, pas toujours tabulaires
Scalabilite Les jointures et ACID coutent cher en environnement distribue

NoSQL = "Not Only SQL" (propose par Carl Strozzi). Ce n'est pas un remplacement du SQL, mais un complement pour les cas ou le relationnel est inadapte.

Modele relationnel vs Agregat

graph LR
    subgraph Relationnel
        A[CUSTOMER] -->|FK| B[ADDRESS]
        A -->|FK| C[ORDER]
        C -->|FK| D[ORDER_ITEM]
        D -->|FK| E[PRODUCT]
    end
    subgraph Agregat NoSQL
        F["{ id:1, name:'Guido',
        billingAddress:{...},
        orders:[{items:[...]}] }"]
    end
Loading
Relationnel Agregat (NoSQL)
Structure Tables, lignes, colonnes predefinies Objets imbriques, schema libre
Liens Jointures entre tables Donnees regroupees dans un document
Distribution Difficile (donnees liees = meme noeud) Facile (agregat = unite de distribution)

ACID vs NoSQL

Les SGBD relationnels respectent ACID :

  • Atomicity : transaction tout-ou-rien
  • Consistency : coherence et integrite maintenues
  • Isolation : transactions independantes
  • Durability : ecriture definitive et fiable

En distribue, maintenir ACID a un cout enorme en performance. Les BD NoSQL relachent ACID pour gagner en scalabilite.


2. Theoreme de CAP

Les 3 proprietes (Brewer, 2000)

graph TD
    C["C - Consistance<br/>Tous les noeuds voient<br/>les memes donnees"]
    A["A - Disponibilite<br/>(Availability)<br/>Le systeme repond<br/>meme si des noeuds tombent"]
    P["P - Tolerance au<br/>partitionnement<br/>Fonctionne malgre<br/>des coupures reseau"]

    C --- CA["CA : SGBDR classiques<br/>(MySQL, PostgreSQL, Oracle)"]
    C --- CP["CP : MongoDB, HBase,<br/>Redis"]
    A --- CA
    A --- AP["AP : Cassandra,<br/>CouchDB, DynamoDB"]
    P --- CP
    P --- AP
Loading

Regle fondamentale

On ne peut garantir que 2 des 3 proprietes simultanement.

Combinaison Sacrifice Exemples
CA Pas de tolerance partition SGBDR classiques
CP Pas toujours disponible MongoDB, HBase, Redis
AP Pas toujours consistant Cassandra, CouchDB, DynamoDB

Illustration concrete (banque)

  • 2 data centers, 2 repliques de la BD
  • Coupure reseau entre les deux
  • Choix CP : on gele les ecritures (perte de disponibilite) pour garder la coherence
  • Choix AP : on continue a lire/ecrire (risque d'incoherence entre les 2 sites)

3. Fondements techniques

3.1 Sharding

Partitionnement horizontal des donnees sur plusieurs serveurs.

partition = hash(objet) mod n    (n = nb de serveurs)
  • Les objets accedes ensemble resident sur le meme noeud
  • La charge est repartie uniformement
  • Les objets peuvent etre repliques

3.2 Consistent Hashing

Sharding dynamique avec un anneau logique :

graph TD
    subgraph "Anneau de hachage"
        direction LR
        A["Noeud A"]
        B["Noeud B"]
        C["Noeud C"]
    end

    O1["Objet 1"] -->|"hash -> sens horaire"| A
    O2["Objet 2"] -->|"hash -> sens horaire"| B
    O3["Objet 3"] -->|"hash -> sens horaire"| C
    O4["Objet 4"] -->|"hash -> sens horaire"| A
Loading

Regles :

  • Noeuds et objets sont haches avec la meme fonction
  • Un objet est affecte au premier noeud dans le sens horaire
  • Noeud quitte l'anneau : ses objets vont au noeud suivant
  • Noeud rejoint l'anneau : il recupere les objets selon sa position

Utilise par Cassandra notamment.

3.3 MapReduce

Framework de calcul distribue parallele (cree par Google).

flowchart LR
    Input["Donnees<br/>d'entree"] --> Split["Splitting<br/>(decoupage)"]
    Split --> M1["Map 1"]
    Split --> M2["Map 2"]
    Split --> M3["Map 3"]
    M1 --> Shuffle["Shuffle<br/>(regroupement<br/>+ tri)"]
    M2 --> Shuffle
    M3 --> Shuffle
    Shuffle --> R1["Reduce 1"]
    Shuffle --> R2["Reduce 2"]
    R1 --> Result["Resultat<br/>final"]
    R2 --> Result
Loading

Les 2 fonctions a implementer :

Map(key, value)              -> list(key1, value1)
Reduce(key1, list(value1))   -> value2

Exemple : compter les mots

Fichier : "A A C | C B D | A C D"

Map:    "A A C" -> [(A,1),(A,1),(C,1)]
        "C B D" -> [(C,1),(B,1),(D,1)]
        "A C D" -> [(A,1),(C,1),(D,1)]

Shuffle: A -> [1,1,1]  B -> [1]  C -> [1,1,1]  D -> [1,1]

Reduce:  A -> 3, B -> 1, C -> 3, D -> 2

Architecture Master/Worker :

  • Le Master distribue les taches Map et Reduce aux Workers
  • Worker : 3 etats = idle, in-progress, completed
  • On pousse le programme vers les donnees (pas l'inverse)

3.4 MVCC (Controle de Concurrence Multi-Version)

  • Les mises a jour ne suppriment pas l'ancien enregistrement
  • Elles marquent l'ancienne version comme obsolete et ajoutent une nouvelle version
  • Plusieurs versions coexistent, une seule est la plus recente
  • Necessite un nettoyage periodique des versions obsoletes

3.5 Vector Clocks (Horloges vectorielles)

  • Chaque noeud maintient un vecteur d'horloge : V[0], V[1], ..., V[n]
  • Chaque entree = horloge d'un noeud du systeme
  • Permet de detecter les conflits lors de mises a jour concurrentes
  • Valeurs d'horloge = timestamps, numeros de version, etc.

3.6 Hadoop

High Availability Distributed Object Oriented Platform

Module Role
HDFS Systeme de fichiers distribue
Hadoop Common Bibliotheques et utilitaires
YARN Gestion des ressources du cluster
MapReduce Implementation du modele MapReduce

4. Les 4 types de BD NoSQL

Vue d'ensemble

graph TD
    NoSQL["BD NoSQL"]
    KV["Cle-Valeur<br/>Redis, Riak, Voldemort"]
    COL["Colonne<br/>Cassandra, HBase"]
    DOC["Document<br/>MongoDB, CouchDB"]
    GRA["Graphe<br/>Neo4j, OrientDB"]

    NoSQL --> KV
    NoSQL --> COL
    NoSQL --> DOC
    NoSQL --> GRA
Loading

Comparatif

Cle-Valeur Colonne Document Graphe
Modele Paires cle/valeur Familles de colonnes Documents JSON/XML Noeuds + Relations
Scalabilite +++ +++ ++ ++
Complexite + ++ ++ +++
Oriente agregat Oui Oui Oui Non
Exemples Redis, Riak Cassandra, HBase MongoDB, CouchDB Neo4j, OrientDB

4.1 Cle-Valeur (Key-Value)

Principe : hashmap distribuee geante. La valeur est opaque (la BD ne connait pas sa structure).

cle1 -> valeur (string, JSON, blob...)
cle2 -> valeur
cle3 -> valeur

Operations CRUD :

  • create(key, value) / read(key) / update(key, value) / delete(key)

Interface : HTTP REST

Forces Faiblesses
Simple, performant Trop simple pour donnees complexes
Excellente scalabilite horizontale Interrogation uniquement par cle
Haute disponibilite Complexite reportee sur l'applicatif

Cas d'usage : cache, sessions, preferences utilisateur, paniers d'achat, logs, capteurs.


4.2 Colonne (Column-Family)

Principe : stockage par colonnes (pas par lignes). Nombre de colonnes dynamique et variable par ligne.

Concepts cles :

  • Colonne : couple cle/valeur
  • Super-colonne : colonne contenant d'autres colonnes
  • Famille de colonnes : regroupement de colonnes (~ table)
Forces Faiblesses
Donnees semi-structurees Mauvais pour donnees interconnectees
Naturellement indexe Requetes doivent etre pre-ecrites
Bonne scalabilite + MapReduce Maintenance a l'ajout/suppression de colonnes
Temps reel Pas de requetes ad-hoc

Cas d'usage : logging (Netflix), optimisation de recherche (eBay), BI (Adobe), analyse temps reel, compteurs.


4.3 Document

Principe : extension du cle-valeur ou la valeur est un document semi-structure (JSON, XML).

{
  "id": 1,
  "nom": "Dupond",
  "adresses": [
    {"ville": "Paris", "cp": "75001"}
  ],
  "commandes": [...]
}
  • Schemaless : pas de schema prealable
  • Documents heterogenes dans la meme collection
  • Requetes possibles sur le contenu des documents
Forces Faiblesses
Simple mais puissant (structures imbriquees) Inadapte aux donnees interconnectees
Pas de maintenance schema Requetes limitees aux cles/index
Bonne expressivite de requetage Lent sur grandes requetes (-> MapReduce)

Cas d'usage : CMS, evenements/capteurs, analytics temps reel, catalogues produits, messagerie.


4.4 Graphe

Principe : base sur la theorie des graphes. Noeuds + Relations + Proprietes.

graph LR
    A["Personne<br/>nom: Alice"] -->|AMIE_DE| B["Personne<br/>nom: Bob"]
    A -->|TRAVAILLE_A| C["Entreprise<br/>nom: ACME"]
    B -->|TRAVAILLE_A| C
    A -->|ACHETE| D["Produit<br/>nom: TV"]
Loading
  • Relations orientees et avec proprietes
  • Beaucoup plus rapide que les SGBDR pour les traversees de graphe
Forces Faiblesses
Puissant pour donnees liees Sharding plus difficile
Tres rapide pour les parcours
Langages etablis (Cypher, SPARQL)

Cas d'usage : reseaux sociaux, recommandations, BI, geospatial, genealogie, detection de fraude, routage.

Triple Store RDF : structure sujet-predicat-objet, requete via SPARQL, fondation du Web Semantique.


5. Neo4j et Cypher

5.1 Presentation de Neo4j

  • BD orientee graphe, ecrite en Java (GPLv3)
  • Transactionnelle (respecte ACID - exception parmi les NoSQL !)
  • Schemaless : pas de schema preetabli
  • Supporte des milliards de noeuds et relations
  • Langage de requete : Cypher
  • Acces web : http://localhost:7474

5.2 Concepts fondamentaux

graph LR
    subgraph "Noeud (Node)"
        N1["Labels: Personne, Salarie<br/>Proprietes:<br/>  nom: 'Dupond'<br/>  prenom: 'Marcel'"]
    end
    subgraph "Noeud"
        N2["Label: Produit<br/>Proprietes:<br/>  nom: 'TV'<br/>  taille: 50"]
    end
    N1 -->|"ACHAT<br/>date: 09/12/2018"| N2
Loading
Element Description
Propriete Attribut cle/valeur sur un noeud ou une relation (types Java)
Noeud Entite avec 0..n labels et 0..n proprietes
Relation Lien oriente entre 2 noeuds, avec 1 type (obligatoire) et 0..n proprietes

5.3 Cypher - Syntaxe des motifs (ASCII art)

Noeuds :

()                          -- noeud anonyme
(n)                         -- noeud stocke dans variable n
(:Personne)                 -- noeud avec label Personne
(n:Personne)                -- noeud Personne dans variable n
(n:Personne:Salarie)        -- noeud avec 2 labels

Relations :

(a)--(b)                    -- relation non orientee
(a)-->(b)                   -- relation orientee a -> b
(a)-[:AMIE]->(b)            -- relation de type AMIE
(a)-[r:AMIE|COLLEGUE]->(b)  -- type AMIE ou COLLEGUE, stockee dans r

5.4 Cypher - CRUD

CREATE (creation)

-- Noeud simple
CREATE (n:Personne {nom: 'Dupond', prenom: 'Marcel'})

-- Noeud + relation + noeud en une fois
CREATE (a:Personne {nom:'Alice'})-[:AMIE]->(b:Personne {nom:'Bob'})

-- Relation entre noeuds existants (dans le meme bloc)
CREATE (n1)-[:CONNAIT {depuis: 2020}]->(n2)

-- Relations chainees
CREATE (a)-[:AMIE]->(b)<-[:COLLEGUE]-(c)

MATCH + RETURN (recherche)

-- Tous les noeuds
MATCH (n) RETURN n

-- Par label
MATCH (n:Personne) RETURN n

-- Par propriete
MATCH (n:Personne {nom: 'Dupond'}) RETURN n

-- Par relation
MATCH (a {nom:'Alice'})-->(b) RETURN b

-- Par type de relation
MATCH (a)-[:AMIE]->(b) RETURN a, b

-- Relation a profondeur variable (2 a 5 sauts)
MATCH (a)-[*2..5]-(b) RETURN a, b

-- Plus court chemin
MATCH p = SHORTESTPATH((a)-[*1..10]-(b)) RETURN p

WHERE (filtrage avance)

MATCH (n:Personne)
WHERE n.age > 25 AND n.ville IN ['Paris', 'Nice']
RETURN n

-- Operateurs sur chaines
WHERE n.nom STARTS WITH 'Du'
WHERE n.nom ENDS WITH 'nd'
WHERE n.nom CONTAINS 'po'
WHERE n.nom =~ 'Mar.*'        -- regex

-- Existence / Null
WHERE EXISTS(n.email)
WHERE n.email IS NULL

SET (mise a jour)

-- Ajouter/modifier une propriete
MATCH (n {nom: 'Dupond'})
SET n.age = 42, n.ville = 'Paris'

-- Ajouter un label
MATCH (n {nom: 'Dupond'})
SET n:VIP

-- Remplacer TOUTES les proprietes (= ecrase)
MATCH (n {nom: 'Dupond'})
SET n = {nom: 'Dupond', age: 43}

-- Fusionner les proprietes (+= conserve les existantes)
MATCH (n {nom: 'Dupond'})
SET n += {age: 43, email: 'dupond@mail.com'}

REMOVE (suppression propriete/label)

MATCH (n {nom: 'Dupond'})
REMOVE n.age              -- supprime la propriete age

MATCH (n {nom: 'Dupond'})
REMOVE n:VIP               -- supprime le label VIP

DELETE / DETACH DELETE (suppression)

-- Supprimer un noeud (SANS relations, sinon erreur)
MATCH (n {nom: 'Dupond'}) DELETE n

-- Supprimer les relations d'un noeud
MATCH (n {nom: 'Dupond'})-[r]->() DELETE r

-- Supprimer un noeud ET toutes ses relations
MATCH (n {nom: 'Dupond'}) DETACH DELETE n

5.5 Cypher - Clauses complementaires

Clause Usage Exemple
RETURN Afficher les resultats RETURN n.nom, n.age
LIMIT Limiter le nb de resultats RETURN n LIMIT 10
DISTINCT Eliminer les doublons RETURN DISTINCT b
ORDER BY Trier ORDER BY n.nom DESC
COUNT(*) Compter RETURN COUNT(*)
AVG / SUM / MIN / MAX Agregats RETURN AVG(n.age)
WITH Chainage de requetes voir ci-dessous
FOREACH Boucle de traitement voir ci-dessous
LABELS(n) Labels d'un noeud RETURN LABELS(n)
TYPE(r) Type d'une relation RETURN TYPE(r)
ID(n) Identifiant interne RETURN ID(n)

WITH (chainage)

-- Departements avec plus d'1 noeud lie
MATCH (n {nom:'Val'})--(b)
WITH b.dept AS dept, COUNT(*) AS nb
WHERE nb > 1
RETURN dept, nb

FOREACH (boucle)

-- Creer des amis depuis une liste
MATCH (n {nom: 'Alice'})
FOREACH (name IN ['Bob', 'Charlie'] |
    CREATE (n)-[:AMIE]->(:Personne {nom: name}))

5.6 Index et contraintes

-- Creer un index
CREATE INDEX ON :Personne(nom)

-- Supprimer un index
DROP INDEX ON :Personne(nom)

-- Contrainte d'unicite
CREATE CONSTRAINT ON (p:Personne) ASSERT p.email IS UNIQUE

-- Supprimer une contrainte
DROP CONSTRAINT ON (p:Personne) ASSERT p.email IS UNIQUE

Cheat Sheet - Resume ultra-compact

NoSQL = Not Only SQL (complement du SQL, pas remplacement)

CAP : on choisit 2 parmi {Consistance, Availabilite, Partition-tolerance}
  - SGBDR = CA
  - NoSQL = CP ou AP

4 modeles NoSQL :
  Cle-Valeur  -> Redis, Riak         (cache, sessions)
  Colonne     -> Cassandra, HBase    (analytics, logs)
  Document    -> MongoDB, CouchDB   (CMS, catalogues)
  Graphe      -> Neo4j, OrientDB    (reseaux sociaux, recommandation)

Fondements :
  Sharding         = repartition horizontale des donnees
  Consistent Hash  = anneau avec hash(noeud) et hash(objet)
  MapReduce        = Map(k,v)->[(k1,v1)] puis Reduce(k1,[v1])->v2
  MVCC             = multi-versioning au lieu de remplacement
  Vector Clocks    = vecteurs d'horloge pour gerer la concurrence

Cypher (Neo4j) :
  CREATE   (n:Label {prop: val})              -- creer
  MATCH    (n:Label) WHERE ... RETURN n       -- chercher
  SET      n.prop = val                       -- modifier
  REMOVE   n.prop / n:Label                   -- supprimer prop/label
  DELETE   n / DETACH DELETE n                -- supprimer noeud
  Motifs : (a)-[:TYPE]->(b)  /  (a)-[*2..5]-(b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment