29 1 5MB
Bases de données NOSQL LP SIBD Pr. Youssef LEFDAOUI Année Universitaire 2020 -2021
Pr Y.Lefdaoui
NOSQL
Slide 1
Module NoSQL : Les objectifs Partie I u u u
u u u u u
Contexte d'utilisation de bases de données NOSQL. Les modèles de bases de données NoSQL Les systèmes de gestion de bases de données NoSQL orientées documents Les caractéristiques du système MongoDB. Installer et configurer le SGBD MongoDB Manipuler les objets et les données dans MongoDB Implémenter une application sous MongoDB Améliorer les performances
Pr Y.Lefdaoui
NOSQL
Slide 2
Nouveaux besoins en gestion de données
Pr Y.Lefdaoui
NOSQL
Slide 3
Nouveaux besoins en gestion de données Pr Y.Lefdaoui NOSQL Slide 4
Le V de la Valeur
Pr Y.Lefdaoui
NOSQL
Slide 5
Les évolutions... ●
Nouvelles Données : • • •
●
Nouveaux Traitements : • • •
●
Web 2.0 : Facebook, Twitter, news, blogs, ... LOD : graphes, ontologies, ... Flux : capteurs, GPS, … Moteurs de recherche Extraction, analyse, ... Recommandation, filtrage collaboratif, …
Nouvelles Infrastructures : •
Cluster, réseaux mobiles, microprocesseurs multi-coeurs, …
Pr Y.Lefdaoui
NOSQL
➔ très gros volumes, données pas ou faiblement structurées
➔ transformation, agrégation, indexation
➔ distribution, parallélisation, redondance
Slide 6
Quelle technologie choisir pour ses données ? ●
Il existe un très grand nombres de solutions techniques différentes !
Pr Y.Lefdaoui
NOSQL
Slide 7
Differents usages des donnees
Pr Y.Lefdaoui
NOSQL
Slide 8
Limites de bases de données relationnelles
Pr Y.Lefdaoui
NOSQL
Slide 9
Limites des systèmes SGBD classiques
Pr Y.Lefdaoui
NOSQL
Slide 10
Limites des systèmes SGBD classiques
Pr Y.Lefdaoui
NOSQL
Slide 11
Caractéristiques générales de BD. NOSQL
Pr Y.Lefdaoui
NOSQL
Slide 12
Taxonomie des bases NoSQL
Pr Y.Lefdaoui
NOSQL
Slide 13
Key/Value Store
Pr Y.Lefdaoui
NOSQL
Slide 14
Classement des moteurs NoSQL Par schémas de données Les moteurs orientés colonnes •
Chaque colonne est définie par un couple clé-valeur
•
Une super-colonne est un couple clévaleur dont la valeur est une colonne
•
Une famille de colonnes permet de regrouper plusieurs colonnes ou supercolonnes. Implémentations existantes
• » » »
HBase(Open Source de BigTablede Google) Cassandra (fondation Apache) SimpleDB(Amazon)
Pr Y.Lefdaoui
NOSQL
Slide 15
Les moteurs orientés colonnes •
Chaque colonne est définie par un couple clé-valeur
•
Une super-colonne est un couple clévaleur dont la valeur est une colonne
•
Une famille de colonnes permet de regrouper plusieurs colonnes ou supercolonnes. Implémentations existantes
• » » »
HBase(Open Source de BigTablede Google) Cassandra (fondation Apache) SimpleDB(Amazon)
Pr Y.Lefdaoui
NOSQL
Slide 16
BD orientée document
Pr Y.Lefdaoui
NOSQL
Slide 17
BD NoSQL orientée document
Pr Y.Lefdaoui
NOSQL
Slide 18
BD NoSQL orientée document
Pr Y.Lefdaoui
NOSQL
Slide 19
BD NoSQL orientée document
Pr Y.Lefdaoui
NOSQL
Slide 20
MongoDB Document ●
Le champ _id •
●
Seul champ obligatoire, utilisé comme clef primaire dans une collection
Les noms des champs ne peuvent pas commencer par un $ ou contenir le caractère « . »
Pr Y.Lefdaoui
NOSQL
Slide 21
MongoDB Structures de Documents ● ●
Deux manières des relations entre les données: Références et Données Imbriquées Références • Inclusion de liens ou références d’un document à un autre • C’est à l’application de résoudre ces références pour accéder aux données associées • On dit qu’on utilise des Modèles de Données Normalisés
Pr Y.Lefdaoui
NOSQL
Slide 22
MongoDB Structures de Documents ●
Données Imbriquées (Embedded Data) • • • •
Sauvegarde des données associées dans la même structure de documents Il est possible d’inclure des documents dans un champ ou un tableau Permet aux applications d’extraire et manipuler plusieurs niveaux de hiérarchie en une seule instruction Ce sont les Modèles de Données Dénormalisés
Pr Y.Lefdaoui
NOSQL
Slide 23
MongoDB Lecture ●
●
MongoDB fournit une méthode db.collection.find() pour l’extraction de données • § Accepte les critères de la requête, ainsi que les projections • § Retourne un curseur vers les documents correspondants Fournit également une méthode db.collection.findOne() retournant un seul document
Pr Y.Lefdaoui
NOSQL
Slide 24
MongoDB Terminologie
Pr Y.Lefdaoui
NOSQL
Slide 25
BD NoSQL orientées graphes
Pr Y.Lefdaoui
NOSQL
Slide 26
BD NoSQL orientées graphes
Pr Y.Lefdaoui
NOSQL
Slide 27
MongoDB : les fondements
Pr Y.Lefdaoui
NOSQL
Slide 28
Structure de données
Pr Y.Lefdaoui
NOSQL
Slide 29
Les documents
Pr Y.Lefdaoui
NOSQL
Slide 30
Instance mongodb
Pr Y.Lefdaoui
NOSQL
Slide 31
Bases de données (1)
Pr Y.Lefdaoui
NOSQL
Slide 32
Bases de données (2) Effacement d’une base > show dbs admin 0.000GB db‐films 0.000GB local 0.000GB > db db‐films > db.dropDatabase() { "dropped" : "db‐films", "ok" : 1 } > show dbs admin 0.000GB local 0.000GB > db db‐films Pr Y.Lefdaoui
NOSQL
Slide 33
Bases de données (3) Le client MongoDB permet de définir et d’exécuter du code Java Script > function fact(n) { ... if (n == 1) return 1 ... else return (n* fact(n‐1)) ... } > fact (2) 2
Le client MongoDB contient un interpréteur de Java Script permettant de définir des fonctions et des variables
La définition de fonctions de calcul en Java Script sera très utile/nécessaire pour l’écriture des fonctions map() et reduce() des Map‐Reduce (voir plus loin)
Pr Y.Lefdaoui
NOSQL
Slide 34
Définition d'un schéma de données avec MongoDB Les collections
Pr Y.Lefdaoui
NOSQL
Slide 35
Définition d'un schéma de données avec MongoDB Les collections
Pr Y.Lefdaoui
NOSQL
Slide 36
Insertion de documents
Pr Y.Lefdaoui
NOSQL
Slide 37
[ { "_id": "movie:1", "title": "Vertigo", "year": "1958", "director": { "_id": "artist:3", "last_name": "Hitchcock", "first_name": "Alfred", "birth_date": "1899" }, "actors": [ { "_id": "artist:15", "first_name": "James", "last_name": "Stewart", }, { "_id": "artist:16", "first_name": "Kim", "last_name": "Novak", } ] }, { "_id": "movie:2", "title": "Alien", ... } ] Pr Y.Lefdaoui
NOSQL
Slide 38
Importation de données • Le démon mongod doit être lancé, et mongoimport s’y connectera • L’option ‐‐mode permet de préciser si on ajoute/mélange/remplace les données déjà présente dans la collection • L’option ‐‐jsonArray permet d’importer des tableaux de documents JSON • La commande mongoimport est riche en options de fonctionnement (voir la doc technique de MongoDB) Gestion de l’ajout des nouvelles données : • Si la donnée lue ne possède pas de ‘’_id’’ : alors un ‘’_id’’ sera créé et lui sera affecté. • Si la donnée lue possède un ‘’_id’’ déjà utilisé dans une donnée de la base : • ‐‐mode insert : indique une erreur • ‐‐mode upsert : remplace l’ancienne donnée par la donnée lue • ‐‐mode merge : ajoute les nouveaux champs présents dans le fichier JSON, remplace ceux déjà existants et redéfinis dans la donnée lue.
En supposant que ce tableau est sauvegardé dans movies.json, on peut l’importer dans la collection movies de la base nfe204 avec la commande suivante: mongoimport -d nfe204 -c movies --file movies.json --jsonArray
mongoimport -d nfe204 -c movies --file movies.json --jsonArray Pr Y.Lefdaoui
NOSQL
Slide 39
Recherche
Pr Y.Lefdaoui
NOSQL
Slide 40
Recherche fonction find() (1)
Pr Y.Lefdaoui
NOSQL
Slide 41
Recherche fonction find() (1)
Pr Y.Lefdaoui
NOSQL
Slide 42
Recherche fonction find() (2)
Pr Y.Lefdaoui
NOSQL
Slide 43
Recherche fonction find() (3)
Pr Y.Lefdaoui
NOSQL
Slide 44
Recherche fonction findOne()
Pr Y.Lefdaoui
NOSQL
Slide 45
Insertion des données dans MongoDB
Pr Y.Lefdaoui
NOSQL
Slide 46
Insertion des données dans MongoDB
Pr Y.Lefdaoui
NOSQL
Slide 47
Consultation des données Mongodb
Pr Y.Lefdaoui
NOSQL
Slide 48
db.collection.find(query, projection) § Sélectionne des documents dans une collection ou une vue et renvoie un curseur sur les documents sélectionnés. Projection : détermine quels champs sont retournés dans les documents correspondants. { field1: true | false , field2: : true | false ... } { "_id": "apples", "qty": 5 } { "_id": "bananas", "qty": 7 } { "_id": "oranges", "qty": { "in stock": 8, "ordered": 12 } } { "_id": "avocados", "qty": "fourteen" }
db.collection.find( { qty: { $gt: 4 } } ) { "_id": "apples", "qty": 5 } { "_id": "bananas", "qty": 7 } Pr Y.Lefdaoui
NOSQL
Slide 49
Requêtes utilisant les opérateurs db.bios.find({ _id: { $in: [ 5, ObjectId("507c35dd8fada716c89d0013") ] } })
db.bios.find( { birth: { $gt: new Date('1950-01-01') } } ) db.bios.find( { birth: { $gt: new Date('1940-01-01'), $lt: new Date('1960-01-01') } } ) db.bios.find( { birth: { $gt: new Date('1920-01-01') }, death: { $exists: false } }) db.bios.find( { name: { first: "Yukihiro", last: "Matsumoto" } } ) db.bios.find( {"name.first": "Yukihiro", "name.last": "Matsumoto" }) Pr Y.Lefdaoui
NOSQL
Slide 50
Requête sur des éléments d'un tableau db.bios.find( { contribs: "UNIX" } )
db.bios.find( { contribs: { $in: [ "ALGOL", "Lisp" ]} } ) db.bios.find( { contribs: { $all: [ "ALGOL", "Lisp" ] } } ) db.bios.find( { contribs: { $size: 4 } } ) db.bios.find( { "awards.award": "Turing Award" } ) db.bios.find( { awards: { $elemMatch: { award: "Turing Award", year: { $gt: 1980 } } } } )
Pr Y.Lefdaoui
NOSQL
Slide 51
Interroger un tableau db.inventory.insertMany([ { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] }, { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] }, { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] }, { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] }, { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] } ]); // un tableau avec exactement deux éléments, "red" et "blank", db.inventory.find( { tags: ["red", "blank"] } ) // contient à la fois les éléments "red" et "blank", sans tenir compte de l'ordre ou des // autres éléments du tableau. db.inventory.find( { tags: { $all: ["red", "blank"] } } ) // contient au moins un élément dont la valeur est supérieure à 25. db.inventory.find( { dim_cm: { $gt: 25 } } ) Pr Y.Lefdaoui
NOSQL
Slide 52
Interroger un tableau db.inventory.insertMany([ { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] }, { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] }, { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] }, { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] }, { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] } ]); // un élément peut satisfaire la condition supérieure à 15 et un autre élément peut // satisfaire la condition inférieure à 20, ou un seul élément peut satisfaire les deux: db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } ) // contient au moins un élément qui est supérieur à ($ gt) 22 et inférieur à ($ lt) 30: db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } ) // le deuxième élément du tableau dim_cm est supérieur à 25: db.inventory.find( { "dim_cm.1": { $gt: 25 } } ) Pr Y.Lefdaoui
NOSQL
Slide 53
Interroger un tableau db.inventory.insertMany([ { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] }, { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] }, { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] }, { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] }, { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] } ]); // un élément peut satisfaire la condition supérieure à 15 et un autre élément peut // satisfaire la condition inférieure à 20, ou un seul élément peut satisfaire les deux: db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } ) // contient au moins un élément qui est supérieur à ($ gt) 22 et inférieur à ($ lt) 30: db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } ) // sélectionne les documents où les balises de tableau ont 3 éléments. db.inventory.find( { "tags": { $size: 3 } } ) Pr Y.Lefdaoui
NOSQL
Slide 54
Interroger un tableau de documents incorporés db.inventory.insertMany( [ { item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] }, { item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] }, { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] }, { item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] }, { item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] } ]); // Le tableau correspond au document spécifié: db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } ) db.inventory.find( { "instock": { qty: 5, warehouse: "A" } } ) // vide // tableau a au moins un document incorporé contenant le champ qty dont la / /valeur est inférieure ou égale à 20: db.inventory.find( { 'instock.qty': { $lte: 20 } } ) // Le tableau a pour premier élément un document contenant le champ qty dont la // valeur est inférieure ou égale à 20. db.inventory.find( { 'instock.0.qty': { $lte: 20 } } ) Pr Y.Lefdaoui
NOSQL
Slide 55
Interroger un tableau de documents incorporés db.inventory.insertMany( [ { item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] }, { item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] }, { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] }, { item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] }, { item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] } ]); // Ltableau a au moins un document incorporé qui contient à la fois le champsqty //égale à 5 et le champs warehouse égale à A: db.inventory.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } ) db.inventory.find( { "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } } )
Pr Y.Lefdaoui
NOSQL
Slide 56
db.collection.aggregate() { _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 } { _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 } { _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 } { _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 } { _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 }
// les documents dont l'état est égal à "A", regroupe les documents correspondants dans // le champ cust_id, calcule le total de chaque champ cust_id à partir de la somme du //champ du montant et trie les résultats en fonction du champ total par ordre //décroissant: db.orders.aggregate([ { $match: { status: "A" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } } ])
Pr Y.Lefdaoui
NOSQL
Slide 57
db.collection.aggregate() { _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 } { _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 } { _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 } { _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 } { _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 }
// les documents dont l'état est égal à "A", regroupe les documents correspondants dans // le champ cust_id, calcule le total de chaque champ cust_id à partir de la somme du //champ du montant et trie les résultats en fonction du champ total par ordre //décroissant: db.orders.aggregate([ { $match: { status: "A" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } } ])
Pr Y.Lefdaoui
NOSQL
Slide 58