SQL VS NOSQL
Tout savoir sur les nouveaux systèmes de gestion de
bases de données
Majd AISSAOUI, Roissy, Octobre 2016
BASES NOSQL
GRAPHS
Bases NoSQL
2 2
QU’EST CE QUE NEO4J
• Développé par Neo Technologies
• Base de données graphique la plus populaire
• Implémentée en Java
• Open source
• Base de données utilisant des structures de graphique avec des nœuds, des
arêtes et des propriétés pour stocker des données
• Fournit une adjacence sans index
► Chaque nœud est un pointeur sur son élément adjacent
• Les « Edges » contiennent la plupart des informations importantes et
connectent
► Les nœuds vers d'autres nœuds
► les noeuds vers les propriétés
3
GRAPH DATABASES - EXEMPLE
(Wikipedia)
4
PHILOSOPHIE NOSQL “GRAPHS”
Relationnelle NoSQL “Graphs”
G
G
Utilisateur Utilisateur Amis
_Amis
- Les tuples (~ objets) sont éclatés
- Les liaisons entre objets (lignes jaunes) peuvent être des
entités et avoir des attributs (ex : “contain”, “is_a”, ...)
5
GRAPH DATABASE
DESCRIPTION
► Basé sur les relations
► Modélisé avec des nœuds et des
relations (edges).
Nœuds :peuvent avoir des attributs,
Edges peuvent avoir des labels
(étiquettes) ou rôles
► Les attributs, labels et rôles utilisent
une notion de clé/valeur
► Les interfaces et les langages de
requêtage variant d’une application à
l’autre
► Les Graph Databases, du fait de son
modèle de données basées sur des
relations entre nœuds, est difficile à
rendre scalable.
► C’est la moins scalable des 4 types de
NoSQL databases
6
GRAPH DATABASE
Une base en Graph peut être extrêmement complexe, et comporter des millions de
nœuds et de relations.
7
GRAPH DATABASE
Le stockage des informations pour les nœuds et les edges se fait dans des tables
séparées, permettant différentes types de recherches.
8
GRAPH DATABASE
Avantages
► Recherches rapides
► Idéal pour les réseaux sociaux, et autres types similaires de besoins
► Représentation de réseaux (Facebook,...)
► Déterminer un chemin ou patron entre des entités (Mappy,...)
Inconvénients
► Pas très scalable
► Difficile d’extraire de l’information, à moins d’utiliser des langages de requêtage
spécialisé dans les graphs.
Solutions commerciales
► Neo4j
► AllegroGraph
9
PRINCIPALES CARACTÉRISTIQUES DE NEO4J
• Neo4j est sans schéma - les données ne doivent adhérer à aucune convention
• ACID - atomique, cohérent, isolé et durable pour les unités de travail logiques
• Facile à démarrer et à utiliser
• Communauté de développeurs importante
• Prise en charge d'une grande variété de langages de programmation
• Java, Python, Perl, Scala, Cypher, etc.
10 (Mistry, Deep, 2013)
REQUÊTAGE POUR NEO4J
Cypher est le langage de requête pour Neo4j
Facile à formuler des requêtes basées sur des relations
De nombreuses fonctionnalités découlent de l'amélioration des points sensibles
avec SQL, telles que les tables de jointure.
(Hunger, Michael 2013)
11
12
THE STRUCTURE OF A CYPHER QUERY
Nodes are surrounded with
parentheses which look like circles, e.g. (a)
A relationship is basically an arrow -->
between two nodes with additional
information placed in square brackets
inside of the arrow
A query is comprised of several distinct clauses, like:
► MATCH: The graph pattern to match. This is the most common way to get data from the
graph.
► WHERE: Not a clause in its own right, but rather part of MATCH, OPTIONAL MATCH and
WITH. Adds constraints to a pattern, or filters the intermediate result passing through WITH.
► RETURN: What to return.
MATCH (john {name: 'John'})-[:friend]->()-[:friend]->(fof) RETURN [Link], [Link]
12
13
WRITING CYPHER QUERIES
Node labels, relationship types and property names are case-sensitive in Cypher
CREATE creates nodes with labels and properties or more complex structures
MERGE matches existing or creates new nodes and patterns. This is especially useful together
with uniqueness constraints.
DELETE deletes nodes, relationships, or paths. Nodes can only be deleted when they have no
other relationships still existing
DETACH DELETE deletes nodes and all their relationships
SET sets values to properties and add labels on nodes
REMOVE removes properties and labels on nodes
ORDER BY is a sub-clause that specifies that the output should be sorted and how
13
CYPHER
14 ([Link]/learn/cypher)
CYPHER
15 ([Link]/learn/cypher)
APPLICATION DOMAINS
([Link])
16
CONCLUSION
Questions clés à se poser
• Mes données vont-elles avoir beaucoup de relations?
• Quel genre de questions voudrais-je poser à ma base de données?
17
HAUTE DISPONIBILITÉ ET
SAUVEGARDE
HAUTE DISPONIBILITÉ POUR NEO4J
Le composant HA prend en
charge la réplication maître-
esclave
• Pour le clustering
• Pour DR sur tous les sites
19
WRITE TO A MASTER
Les écritures au maître sont rapides
• Les esclaves finissent par se rattraper
20
WRITE TO A SLAVE
Une écriture sur un esclave provoque une transaction synchrone avec le maître
les autres esclaves finissent par se rattraper
21
QUID DU PRA ?
Une écriture sur un esclave provoque une transaction synchrone avec le maître
les autres esclaves finissent par se rattraper
DR Site Primary Site
Neo 3 dr Neo 2 p
Neo 1 dr Neo 2 dr Neo 1 p Neo 3 p
(master) (m aster)
Neo
Backup
Agent
22
QUID DE LA SAUVEGARDE ?
DR Site Primary Site
Neo 3 dr Neo 2 p
Neo 1 dr Neo 2 dr Neo 1 p Neo 3 p
(master) (m aster)
Off site Neo Neo Off site
backup Backup Backup backup
channel Agent Agent channel
Optional Optional
23
SCALABILITÉ
Extrêmement difficile !
SERVEUR “TROU NOIR”
les nœuds populaires sont regroupés sur une seule instance
25
NETWORK SURCHARGÉ
Équilibrer la charge peut conduire à de nombreuses relations traversant des instances.
Celles-ci sont très coûteuses à parcourir, les réseaux sont beaucoup plus lents que la mémoire interne des serveurs
26
POINTS DE COUPURE
Il existe des algorithmes qui aident à garder les graphes
équilibrés (le problème du minimum de découpage par
points)
Ils peuvent travailler selon
- temps d'insertion
- périodiquement
Ceci reste un domaine de recherche ouvert. Les graphes
sont hautement modifiables et ces algorithmes sont donc
confrontés à des difficultés croissantes.
Contrairement aux autres bases de données NoSQL, les
graphiques ne sont tout simplement pas prévisibles et
nous ne pouvons donc pas utiliser de techniques telles
que le hachage cohérent pour la scalabilité.
27
EN PRATIQUE
29
NEO4J INSTALLATION
Neo4j runs on Linux, Windows, and OS X
A Java 8 runtime is required
For Community Edition there are desktop installers for OS X and Windows
Several ways to install on Linux, depending on the Linux distro (see the “Neo4j Resources” slide)
Check the /etc/neo4j/[Link] configuration file:
# HTTP Connector
[Link]=HTTP
[Link]=true
# To accept non-local HTTP connections, uncomment this line
[Link]=[Link]:7474
File locations depend on the operating system, as described here:
[Link]
Make sure you start the Neo4j server (e.g., “./bin/neo4j start” or “service neo4j start” on Linux)
29
30
NEO4J BROWSER
Open the URL [Link] (replace “localhost” with your server name, and 7474 with the
port name as set in [Link])
Start working with
Neo4j by entering
Cypher queries
and observing their
results
Save frequently used
Queries to Favorites
30
31
IMPORTING AND EXPORTING DATA
Loading data from CSV is the most straightforward way of importing data into Neo4j
For fast batch import of huge datasets, use the neo4j-import tool
Lots of other tools for different data formats and database sizes
More on importing data at [Link]
Export data using Neo4j browser or neo4j-shell-tools
31
32
LOADING DATA FROM CSV
Understand your graph model
(p1:Person {userId:10,name:"Anne"})-[:KNOWS]->(p2:Person {userId:123,name:"John"})
CSV files
► [Link]
1,"John" 10,"Jane" 234,"Fred" 4893,"Mark" 234943,"Anne"
► [Link]
1,234 10,4893 234,1 4893,234943 234943,234 234943,1
Run the following Cypher queries:
► CREATE CONSTRAINT ON (p:Person) ASSERT [Link] IS UNIQUE;
► LOAD CSV FROM "[Link] AS csvLine
MERGE (p:Person {userId: toInteger(csvLine[0]), name: csvLine[1]});
► USING PERIODIC COMMIT LOAD CSV FROM "[Link] " AS csvLine MATCH (p1:Person {userId:
toInteger(csvLine [0])}), (p2:Person {userId: toInteger(csvLine [1])})
CREATE (p1)-[:KNOWS]->(p2);
► CREATE INDEX ON :Person(name);
Check the results:
MATCH (:Person {name:"Anne"})-[:KNOWS*2..2]-(p2) RETURN [Link], count(*) as freq ORDER BY freq
DESC;
32
33
LOADING DATA FROM A SPREADSHEET
Lay out your data in a spreadsheet
Use formulas to generate the required Cypher statements
Collect Cypher queries and run them
Check the results:
MATCH (p1:Person)-[:ATTENDS]-(e:Event{name:"Meetup Malmö"})-[:ATTENDS]-(p2:Person)
WHERE (p1)-[:FRIENDS_WITH]-(p2) RETURN p1, p2, e;
33
34
LOADING DATA FROM A GRAPHML FILE
Use neo4j-shell-tools from [Link]
Populate the database from a GraphML file
import-graphml -i /usr/share/neo4j/import/[Link] -r HAS_DIRECT_FLIGHTS_TO -
b 20000 -c -t
Check the results:
MATCH (a)--()
WITH [Link] as airport, count(*) as flights
RETURN airport, flights ORDER BY flights DESC LIMIT 10
34
LOADING DATA FROM AN ARBITRARY FORMAT
Write a simple piece of code to convert your file into a from sys import argv
set of two CSV files def read_edge_list(filename):
nodeset= set([])
Load data from the CSV file into a Neo4j database
edgelist = []
with open(filename, 'r') as file_handle:
for line in file_handle:
if line[0] != '#':
► CREATE CONSTRAINT ON (p:Person) ASSERT [Link] data = [Link]()
node_from = data[0]
IS UNIQUE; node_to = data[1]
[Link](node_from)
► LOAD CSV WITH HEADERS FROM "[Link] [Link](node_to)
[Link]([node_from,
[Link]" AS csvLine MERGE (p:Person {userId: node_to])
return nodeset, edgelist
toInt([Link])});
► USING PERIODIC COMMIT LOAD CSV WITH HEADERS FROM def write_csv_nodes(nodes, file_nodes):
with open(file_nodes, 'w') as
"[Link] AS csvLine MATCH file_handle:
file_handle.write("NodeID\n")
(p1:Person {userId: toInt([Link])}), for node in nodes:
(p2:Person {userId: toInt([Link])}) file_handle.write('{0}\n'.format(node))
CREATE (p1)-[:VOTED_ON]->(p2);
► CREATE INDEX ON :Person(name); def write_csv_edges(edges, file_nodes):
with open(file_nodes, 'w') as
file_handle:
Check the results: file_handle.write("EdgeFrom,EdgeTo\n")
for edge in edges:
MATCH (p:Person)-[r]-() file_handle.write('{0},{1}\n'.format(edge[0],
WITH p as persons, count(distinct r) as degree edge[1]))
RETURN degree, count(persons) ORDER BY degree script, input_file, output_file_nodes,
ASC output_file_edges = argv
nodes, edges = read_edge_list(input_file)
write_csv_nodes(nodes, output_file_nodes)
write_csv_edges(edges, output_file_edges)
35
EXPORTING DATA FROM NEO4J
Click the download icon on the table view of
the Cypher query results
Use neo4j-shell-tools to export results of a
Cypher query to a CSV or GraphML file
Access the graph data with Neo4j API and save it in the desired format
36
ACCESSING NEO4J DATA USING REST API
Service root is the starting point to
discover the REST API
► GET [Link]
► Accept: application/json; charset=UTF-8
Create node with properties
► POST [Link]
► Accept: application/json; charset=UTF-8
► Content-Type: application/json
► { "foo" : "bar" }
Create relationship
► POST [Link]
► Accept: application/json; charset=UTF-8
► Content-Type: application/json
► { "to" : "[Link] "type" : "FRIENDS_WITH" }
37
38
USING DRIVERS TO ACCESS NEO4J
Binary Bolt protocol (starting with Neo4j 3.0)
Binary protocol is enabled in Neo4j by default and can be used in any
language driver that supports it
Native Java driver officially supported by Neo4j
Drivers implement all low level connection and communication tasks
import [Link].v1.*;
public class Neo4j
{
public static void javaDriverDemo() {
Driver driver = [Link]("bolt://[Link]", "neo4j", "neo4j"));
Session session = [Link]();
StatementResult result = [Link]("MATCH (a)-[]-(b)-[]-(c)-[]-(a) WHERE [Link] < [Link] AND [Link] < [Link] RETURN DISTINCT a,b,c");
int counter = 0;
while ([Link]())
{
counter++;
Record record = [Link]();
[Link]([Link]("a").get("id") + " \t" + [Link]("b").get("id") + " \t" + [Link]("c").get("id"));
}
[Link]("Count: " + counter);
[Link]();
[Link]();
}
public static void main(String [] args)
{
javaDriverDemo();
}
}
38
39
USING CORE JAVA API
Native Java API performs database operations directly with Neo4j core
import [Link].*;
import [Link].*;
import [Link].*
public class Neo4j
{
public enum NodeLabels implements Label { NODE; }
public enum EdgeLabels implements RelationshipType{ CONNECTED; }
public static void javaNativeDemo(int nodes, double p) {
Node node1, node2; Random randomgen = new Random();
GraphDatabaseFactory dbFactory = new GraphDatabaseFactory();
GraphDatabaseService db = [Link](new File("TestNeo4jDB"));
try (Transaction tx = [Link]()) {
for (int i = 1; i <= nodes; i++) {
Node node = [Link]([Link]);
[Link]("id", i);
}
for (int i = 1; i <= nodes; i++)
for (int j = i + 1; j <= nodes; j++) {
if ([Link]() < p) {
node1 = [Link]([Link], "id", i);
node2 = [Link]([Link], "id", j);
Relationship relationship = [Link](node2,[Link]);
relationship = [Link](node1,[Link]);
}
}
[Link]();
}
[Link]();
}
public static void main(String [] args) {
javaNativeDemo(100, 0.2); }
39 }
REFERENCES
Neo4j Web site: [Link]
Neo4j installation manual: [Link]
manual/current/deployment/single-instance/
Cypher Refcard [Link]
40