Ajout documents pour cours NoSQL

This commit is contained in:
Sylvain 2019-09-22 22:14:24 +02:00
parent 0091d980b3
commit ad6aced650
16 changed files with 905 additions and 0 deletions

2
cesi/nosql/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.pdf
Slides/*.html

View File

@ -0,0 +1,233 @@
# Initiation à NoSQL
## Sylvain Eliade, Cadoles
------
## C'est quoi NoSQL ?
* Désigne toutes les bases de données non-relationnelles
* Base relationnelle (RDBMS) = généralement SQL
* Mais on peut faire du SQL non-relationnel !
* Donc maintenant, NoSQL = "Not Only SQL"
* Au final, un mot un peu trop vague, comme "Web 2.0"
---
## Rappel : RDBM
<figure>
<img src="Images/rdbm.svg" alt="" />
</figure>
---
## Rappel : ACID
* Atomique = tout changement (transaction) à la BDD doit fonctionner ou échouer en entier (mais pas être exécuté à moitié et échouer à moitié !)
* Consistant = toutes les règles imposées doivent être valides (clés, triggers, contraintes, etc.) pour empêcher la corruption de la BDD
* Isolation = les transactions pouvant être exécutées en même temps, une requête concurrente ne doit pas avoir accès à un état transitoire de la BDD
* Durabilité = une transaction écrite dans la BDD doit le rester en cas de crash logiciel ou coupure du serveur
---
## Différences entre RDBMS et NoSQL
* Généralement pas ACID (Atomicity, Consistency, Isolation, Durability)
* Mais parfois oui (CouchDB), parfois partiellement
* Théoriquement plus facile à dimensionner horizontalement
* En pratique les RDBMS se dimensionnent très bien aussi
* La plus grosse différence et intérêt : non relationnel ! :)
---
## Les familles de bases NoSQL
* Clé-valeur (Berkeley DB, memcached, Redis, Apache Ignite, etc.)
* Document (MongoDB, Apache CouchDB, etc.)
* Colonnes ou "wide column" (Cassandra, HBase, etc.)
* Graph (Neo4j, Apache Giraph…)
---
### Quand utiliser une BDD noSQL ?
* Besoin de très grosses performances
* … ou stockage de très grosses données
* Données non adaptées à un RDBM
* Et surtout : pas de besoins relationnels !
---
### Quand utiliser une BDD noSQL ?
* … mais même dans ces cas, un RDBM est souvent plus simple et rapide à mettre en œuvre
* Et un RDBM supporte aussi de très grandes quantités de données et de bonnes performances… si vous savez bien l'utiliser :)
* Vous n'êtes pas Google, Amazon ou Alibaba !
* Une solution SQL (Postgre, MySQL, SQL Server, Oracle…) sera adaptée à 95% des besoins
---
## Bases de données clé-valeur
* Aussi vieilles que l'informatique !
* On référence une valeur à l'aide d'une clé pour aider à retrouver la valeur
* La valeur ne fait pas de différence pour le moteur de BDD (opaque)
* On ne peut donc pas trouver une entrée juste avec une partie de la valeur
* Du plus simple (memcached, Berkeley DB) au plus évolué (Redis)
* Rapide, simple, efficace
---
## Bases de données clé-valeur
<figure>
<img src="Images/kv.png" alt="" />
</figure>
---
### Quand utiliser une BDD clé-valeur ?
* Données simples et à une seule dimension
* Données qui peuvent expirer
* Pas forcément besoin de persistance
* Exemples : cache, queue, statistiques…
---
### Quand ne pas utiliser une BDD clé-valeur ?
* Données structurées sur plusieurs niveaux (2D+)
* Besoins de jointures entre les données
* Besoin d'index sur le contenu des valeurs
* Besoin de chercher dans les valeurs
* Besoin de lister toutes les clés (lent)
* Données très grandes (selon le moteur de BDD, par exemple si les données sont stockées en RAM)
---
## Bases de données document
* Évolution du modèle clé-valeur (document = valeur)
* Sauf que le contenu de la valeur peut être indexé / référencé
* Plutôt adapté à un modèle où les documents sont indépendants et n'ont pas de relation entre eux
* Exemples : MongoDB, CouchDB, etc.
---
## Bases de données document
<figure>
<img src="Images/document.png" alt="" />
</figure>
---
### Quand utiliser une BDD document ?
* Données structurées ou complexes
* Structure des données très variable
* Données non relationnelles
* Pas de schéma
* Exemple : fiches produit d'un site ecommerce
---
## Base de données orientée colonnes
* Comme une BDD clé-valeur, mais en 2D !
* On retrouve une donnée à l'aide d'une clé (ligne) et d'un nom de colonne
* Toutes les lignes n'ont pas forcément les même colonnes (contrairement à une table dans un RDBM)
* Les colonnes sont donc indépendantes d'une ligne à l'autre
* Exemples : Cassandra, HBase (historiquement : Google BigTable)
---
### Quand utiliser une BDD orientée colonnes ?
* Beaucoup d'écritures (ajouts)
* Grand volume de données
* Besoins de réplication
* Données peu structurées
* Données en 2D uniquement (clé d'accès + colonnes)
* Exemple idéal : statistiques, messageries temps réel
---
### Quand ne pas utiliser une BDD orientée colonnes ?
* Beaucoup de mises à jour / suppression de lignes
* Besoin de transactions, de rollbacks, de triggers, joins, etc.
* Besoin ACID : ce n'est pas du tout fait pour
* Besoin de parcourir toutes les données stockées : lent !
---
## Base de données graph
* Documents (= nœuds) liés ensemble par des relations (= arcs ou graphs)
* Les relations peuvent disposer de propriétés selon le contexte
* On peut accéder aux nœuds via leurs relations
---
## Base de données graph
<figure>
<img src="Images/graph.png" alt="" />
</figure>
---
### Quand utiliser une BDD graph ?
* Données non structurées (pas de schéma)
* Liées ensemble de manière non ordonnée
* Exemples : graph d'amis (réseau social), recommandations de produits, détection de fraude…
---
### Quand ne pas utiliser une BDD graph ?
* Données non liées
* Données séquentielles
* Pas de besoin de lire les données
* Données dans un schéma fixe
* Besoin de stocker beaucoup de données dans les propriétés
---
## NoSQL : une solution parmi d'autres
* Les bases NoSQL ont été créées pour répondre à des besoins de très gros acteurs
* Besoins qui sont rarement atteints ailleurs
* NoSQL est une solution, pas LA solution
* Bien évaluer le problème avant de choisir la ou les solutions :)
* Le bon côté : NoSQL a initié une modernisation des RDBMs
---
## Google abandonne NoSQL
* Google, à l'origine de BigTable et MapReduce, premières solutions NoSQL
* … sont repassés à SQL avec [Spanner et le "Standard SQL"](https://blog.timescale.com/blog/why-sql-beating-nosql-what-this-means-for-future-of-data-time-series-database-348b777b847a/) commun à plusieurs outils internes.
* Car SQL facilite l'arrivée de nouveaux développeurs et la possibilité de communiquer avec des outils différents mais avec le même langage.
---
## NoSQL dans SQL
* Stockage JSON dans PostgreSQL (depuis la version 9.2), MySQL (5.7.8), SQLite (3.9.0), SQL Server
* Recherche plein texte, index sur les données JSON, jointures !
* Implémentation légèrement différente dans SQLite
* Performance : pas forcément lent
* PostgreSQL est plus rapide avec JSONB que MongoDB par exemple, mais nécessite plus d'optimisation de la configuration
---
## Dans quel cas utiliser une BDD NoSQL ?
* Gros volume de données
* Données très spécifiques et non-relationnelles
* Petit projet, "pour tester", qui ne sera pas amené à évoluer, car changer de BDD est lourd !

46
cesi/nosql/02-Redis.md Normal file
View File

@ -0,0 +1,46 @@
# Introduction à Redis
## Sylvain Eliade, Cadoles
---
## Redis
* Stockage en mémoire
* Mais pas que… Stockage persistant optionnel
* Base de données, cache, pub-sub
* Réplication, transactions, partitionnement…
* Nombreux types de structures de données, majoritairement clé-valeur
* Très très rapide
* Un seul thread, mais c'est pas grave, c'est pas le CPU qui limite
* Scriptable avec Lua
---
## Types de structures de données
* Chaînes de caractère
* Listes simples
* Jeux de données uniques non-ordonnées (sets)
* Dictionnaires (hashes)
* Liste triée (sorted set)
---
## Le protocole de Redis
* Protocole texte simple (utilisable par telnet !)
* Commandes texte suivies d'arguments : `SET clé valeur`
* Réponse texte : `OK`, chaînes, etc.
---
## Commandes de base
* [Commandes Redis](https://redis.io/commands)
* [Types Redis](https://redis.io/topics/data-types)
* Redis-cli !
* `SET test coucou``OK`
* `GET test``"coucou"`
* `DEL test``(integer) 1` = une clé supprimée, c'est bon !
* `KEYS *` = lister toutes les clés

View File

@ -0,0 +1,85 @@
# Exercices Redis
Utiliser redis-cli et copier/coller le résultat de chaque exercice (commandes et retours de Redis) dans un fichier texte.
---
## Exercice 1
* créer une clé "normale" avec sa valeur
* récupérer le résultat
* supprimer la clé
---
## Exercice 2 : expiration
* créer une clé
* lui donner une expiration courte (quelques secondes)
* vérifier que la clé "disparaît" toute seule
---
## Exercice 3 : compteurs
* Créer une clé contenant un numéro
* L'incrémenter et le décrementer avec les commandes Redis adaptées
---
## Exercice 4 : liste unique non ordonnée
* Créer une liste unique non ordonnée (set, `SADD`)
* Y insérer plusieurs entrées
* Insérer des entrées en double
* Vérifier que la liste ne contient pas de doublons
* Supprimer des entrées
---
## Exercice 5 : liste ordonnée par ordre d'insertion
* Créer une liste ordonnée (`LPUSH`)
* Ajouter des entrées par la gauche et la droite (`LPUSH` et `RPUSH`)
* Récupérer une partie de la liste
* Supprimer des éléments par la gauche, la droite (pop) et arbitrairement (rem)
---
## Exercice 6 : hashes
* Créer un hash avec plusieurs sous-clés et sous-valeurs (`HSET` et `HMSET`)
* Récupérer toutes les sous-valeurs du hash
* Modifier une seule sous-valeur
* Récupérer une seule sous-valeur
---
## Exercice 7 : liste ordonnée par score
* Enregistrer les scores de 10 joueurs de Tetris dans une liste ordonnée (`ZADD`), avec leurs noms et leurs scores
* Récupérer la liste des 5 meilleurs joueurs (`ZRANGE`)
* Récupérer le score du joueur Bob
---
## Mini-projet : newsfeed de réseau social
Note : tout le monde doit utiliser le même serveur Redis au final !
Travail en équipe (groupes et classe).
Prérequis avant de coder : se mettre d'accord avec le reste de la classe de la structure des données à stocker dans Redis (types, noms des clés, etc.) !
Pour rendre les choses plus faciles : la base Redis contiendra une liste unique non ordonnée "utilisateurs" contenant la liste des noms/pseudo des utilisateurs du réseau social.
* L'application doit permettre d'ajouter des posts à sa propre timeline
* Les posts doivent contenir : date, nom de l'utilisateur, contenu du post
* Chaque utilisateur a une timeline différente selon qui il veut suivre
* Mais le contenu des posts ne doit être stocké qu'une seule fois !
* L'application doit propager ces posts aux utilisateurs inscrits à sa propre timeline
* L'application doit permettre de lire les derniers posts des utilisateurs auxquels on s'est inscrit
Note : l'implémentation de la gestion des utilisateurs et de l'inscription aux timelines des autres utilisateurs est facultative (création d'utilisateur et inscription aux timelines sont possibles à la main avec redis-cli).
Note 2 : certaines données associatives peuvent être doublonnées (présence dans plusieurs clés) si besoin.

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
cesi/nosql/Images/graph.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
cesi/nosql/Images/kv.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="195.79131" height="40.452461" id="svg3780" version="1.1" inkscape:version="0.48.3.1 r9886" sodipodi:docname="logo.svg">
<defs id="defs3782"/>
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="4.2416268" inkscape:cx="45.753768" inkscape:cy="19.200676" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" inkscape:window-width="1366" inkscape:window-height="744" inkscape:window-x="0" inkscape:window-y="24" inkscape:window-maximized="1">
<inkscape:grid type="xygrid" id="grid3015" empspacing="5" visible="true" enabled="true" snapvisiblegridlinesonly="true" originx="-8.39956px" originy="-37.93714px"/>
</sodipodi:namedview>
<metadata id="metadata3785">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g inkscape:label="Calque 1" inkscape:groupmode="layer" id="layer1" transform="translate(-335.39956,-499.83558)">
<path style="fill:#078eb5;fill-opacity:1;stroke:none;display:inline;enable-background:new" d="m 356.56825,499.83558 c -13.23043,0 -21.16869,13.23042 -21.16869,23.81477 l 2.64609,0 0,10.58433 c 5.29217,7.93824 32.07212,8.20297 37.04519,0 l 0,-10.58433 2.64607,0 c 0,-4.29058 -1.30219,-9.01755 -3.73483,-13.12018 l -2.99063,3.03198 0,7.12513 1.61247,2.21885 -2.39802,2.31533 -2.43937,-2.31533 1.72272,-2.14993 -0.0688,-7.71776 3.87264,-3.6108 c -0.97461,-1.47147 -2.10693,-2.84403 -3.37655,-4.0656 l -4.87871,5.18192 0,7.13891 1.61245,2.21886 -2.41179,2.31532 -2.43936,-2.31532 1.73648,-2.16374 -0.0826,-7.71774 5.37486,-5.63672 c -1.29755,-1.09094 -2.7222,-2.03518 -4.27232,-2.77012 l -5.59538,5.93992 0,7.12513 1.62625,2.23264 -2.4118,2.31532 -2.43936,-2.31532 1.73649,-2.16373 -0.0826,-7.71774 5.88478,-5.95371 c -2.05509,-0.79293 -4.29761,-1.24034 -6.72546,-1.24034 z m 6.72545,1.24034 1.2817,0.53749 z m 5.55403,3.30761 1.08875,0.97851 z m 4.46526,5.04411 0.68909,1.10253 z M 352,526.57486 l 8.85806,-0.11137 0.0557,10.43027 -8.91375,0.1018 z" id="path3773" inkscape:connector-curvature="0" sodipodi:nodetypes="scccccccccccccccccccccccccccccccccscccccccccccccc"/>
<g style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;line-height:0%;letter-spacing:0px;word-spacing:0px;fill:#777777;fill-opacity:1;stroke:none;font-family:Liberation Sans Narrow;-inkscape-font-specification:Liberation Sans Narrow Bold Condensed" id="text2983" transform="translate(42.28018,-8.4690297)">
<path d="m 374.16131,539.65491 1.40625,0.95703 c -1.35419,1.86198 -3.07294,3.33333 -5.15625,4.41406 -2.08335,1.06771 -4.32945,1.60156 -6.73828,1.60156 -2.00522,0 -3.91928,-0.39062 -5.74219,-1.17187 -1.82292,-0.78125 -3.39193,-1.83594 -4.70703,-3.16406 -1.31511,-1.32812 -2.36328,-2.91015 -3.14453,-4.7461 -0.78125,-1.83592 -1.17188,-3.76301 -1.17188,-5.78125 0,-2.01821 0.39063,-3.94529 1.17188,-5.78125 0.78125,-1.83591 1.82942,-3.41794 3.14453,-4.74609 1.3151,-1.3281 2.88411,-2.38279 4.70703,-3.16406 1.82291,-0.78122 3.73697,-1.17185 5.74219,-1.17188 2.39581,3e-5 4.63539,0.5469 6.71875,1.64063 2.08331,1.08075 3.80857,2.55862 5.17578,4.43359 l -1.40625,1.03516 c -1.21096,-1.62758 -2.7344,-2.91013 -4.57031,-3.84766 -1.82294,-0.95049 -3.79559,-1.42575 -5.91797,-1.42578 -2.36981,3e-5 -4.5573,0.58596 -6.5625,1.75781 -1.9922,1.1719 -3.56772,2.76695 -4.72656,4.78516 -1.15886,2.00522 -1.73829,4.19923 -1.73828,6.58203 -10e-6,1.77084 0.33853,3.46355 1.01562,5.07812 0.6901,1.61459 1.61458,3.00782 2.77344,4.17969 1.15884,1.17188 2.54556,2.10938 4.16015,2.8125 1.61457,0.69011 3.30728,1.03516 5.07813,1.03516 2.12238,0 4.09503,-0.47526 5.91797,-1.42578 1.83591,-0.95052 3.35935,-2.24609 4.57031,-3.88672" style="font-weight:normal;font-stretch:normal;fill:#777777;fill-opacity:1;font-family:Sawasdee;-inkscape-font-specification:Sawasdee" id="path2997" inkscape:connector-curvature="0"/>
<path d="m 435.4735,526.29553 c 1.36717,2e-5 2.67576,0.26695 3.92578,0.80078 1.24998,0.53388 2.33071,1.25653 3.24218,2.16797 0.91144,0.91148 1.6341,1.99872 2.16797,3.26172 0.53383,1.26303 0.80076,2.58465 0.80078,3.96484 -2e-5,1.39324 -0.26695,2.72137 -0.80078,3.98438 -0.53387,1.26303 -1.25653,2.35026 -2.16797,3.26172 -0.91147,0.89844 -1.9922,1.62109 -3.24218,2.16797 -1.25002,0.53385 -2.55861,0.80078 -3.92578,0.80078 -2.79949,0 -5.18881,-0.99609 -7.16797,-2.98828 -1.97917,-1.99219 -2.96876,-4.40104 -2.96875,-7.22657 -10e-6,-1.84894 0.44921,-3.55467 1.34765,-5.11718 0.91146,-1.57551 2.14192,-2.81248 3.69141,-3.71094 1.56249,-0.91144 3.26171,-1.36717 5.09766,-1.36719 m -8.39844,10.19531 c -1e-5,2.33074 0.82031,4.32944 2.46094,5.9961 1.65363,1.65365 3.64582,2.48047 5.97656,2.48047 2.33071,0 4.31639,-0.82682 5.95703,-2.48047 1.65362,-1.66666 2.48045,-3.66536 2.48047,-5.9961 -2e-5,-2.31769 -0.82685,-4.30337 -2.48047,-5.95703 -1.64064,-1.65362 -3.62632,-2.48045 -5.95703,-2.48047 -2.33074,2e-5 -4.32293,0.82685 -5.97656,2.48047 -1.64063,1.65366 -2.46095,3.63934 -2.46094,5.95703" style="font-weight:normal;font-stretch:normal;fill:#777777;fill-opacity:1;font-family:Sawasdee;-inkscape-font-specification:Sawasdee" id="path3003" inkscape:connector-curvature="0"/>
<path d="m 451.22209,546.41272 -1.75781,0 0,-29.18754 1.75781,0 0,29.18754" style="font-weight:normal;font-stretch:normal;fill:#777777;fill-opacity:1;font-family:Sawasdee;-inkscape-font-specification:Sawasdee" id="path3005" inkscape:connector-curvature="0"/>
<path d="m 456.99022,534.83069 14.39453,0 c -0.3646,-1.96613 -1.22398,-3.58723 -2.57812,-4.86328 -1.35419,-1.27603 -2.90366,-1.91405 -4.64844,-1.91407 -1.73178,2e-5 -3.27475,0.63804 -4.62891,1.91407 -1.34115,1.27605 -2.1875,2.89715 -2.53906,4.86328 m 16.30859,1.66015 -16.58203,0 c 0,2.33074 0.72916,4.30991 2.1875,5.9375 1.45833,1.62761 3.18359,2.44141 5.17578,2.44141 1.31509,0 2.60416,-0.35156 3.86719,-1.05469 1.263,-0.70312 2.22655,-1.64713 2.89063,-2.83203 l 1.54296,0.87891 c -0.79429,1.41927 -1.96616,2.58464 -3.51562,3.49609 -1.54949,0.89844 -3.14455,1.34766 -4.78516,1.34766 -1.65365,0 -3.17709,-0.46224 -4.57031,-1.38672 -1.38021,-0.92448 -2.46745,-2.16797 -3.26172,-3.73047 -0.78125,-1.57551 -1.17188,-3.27473 -1.17187,-5.09766 -1e-5,-1.80988 0.39713,-3.49608 1.1914,-5.05859 0.80729,-1.56248 1.90755,-2.80597 3.30078,-3.73047 1.40625,-0.93748 2.93619,-1.40623 4.58985,-1.40625 1.56248,2e-5 3.01431,0.4232 4.35547,1.26953 1.35415,0.83335 2.44789,1.95966 3.28125,3.37891 0.83331,1.41928 1.32159,2.97527 1.46484,4.66797 l 0.0391,0.8789" style="font-weight:normal;font-stretch:normal;fill:#777777;fill-opacity:1;font-family:Sawasdee;-inkscape-font-specification:Sawasdee" id="path3007" inkscape:connector-curvature="0"/>
<path d="m 487.66068,530.10413 -1.62109,0.5664 c -0.27345,-0.87238 -0.73569,-1.53644 -1.38672,-1.99219 -0.65105,-0.46873 -1.34767,-0.7031 -2.08984,-0.70312 -0.85939,2e-5 -1.59506,0.27346 -2.20703,0.82031 -0.59897,0.54689 -0.89845,1.28908 -0.89844,2.22656 -10e-6,0.49481 0.13671,0.94403 0.41015,1.34766 0.27344,0.40366 0.63151,0.73569 1.07422,0.99609 0.4427,0.26043 0.94401,0.52736 1.50391,0.80079 0.57291,0.27345 1.15233,0.52735 1.73828,0.76171 0.58593,0.23439 1.15884,0.52736 1.71875,0.87891 0.5729,0.35157 1.08072,0.72918 1.52344,1.13281 0.44269,0.40366 0.80076,0.92449 1.07422,1.5625 0.27342,0.63803 0.41014,1.35418 0.41015,2.14844 -1e-5,1.8099 -0.64454,3.28125 -1.93359,4.41406 -1.28908,1.1198 -2.78647,1.67969 -4.49219,1.67969 -0.74219,0 -1.45183,-0.11719 -2.1289,-0.35156 -0.67709,-0.2474 -1.30209,-0.60547 -1.875,-1.07422 -0.57293,-0.46875 -1.06121,-1.09375 -1.46485,-1.875 -0.40365,-0.78125 -0.66406,-1.67317 -0.78125,-2.67578 l 1.73828,-0.25391 c 0.18229,1.48438 0.69661,2.60417 1.54297,3.35938 0.85937,0.75521 1.86197,1.13281 3.00781,1.13281 1.21093,0 2.28515,-0.40364 3.22266,-1.21094 0.93749,-0.82031 1.40624,-1.86848 1.40625,-3.14453 -1e-5,-0.70312 -0.17579,-1.32161 -0.52734,-1.85547 -0.35158,-0.54686 -0.80731,-0.98957 -1.36719,-1.32812 -0.54689,-0.33854 -1.15887,-0.65755 -1.83594,-0.95703 -0.67709,-0.29947 -1.35417,-0.60546 -2.03125,-0.91797 -0.67709,-0.31249 -1.29558,-0.65103 -1.85547,-1.01563 -0.54688,-0.37759 -0.9961,-0.86587 -1.34765,-1.46484 -0.35157,-0.61197 -0.52735,-1.30858 -0.52735,-2.08985 0,-1.45831 0.48177,-2.61716 1.44532,-3.47656 0.97655,-0.85935 2.12889,-1.28904 3.45703,-1.28906 1.09374,2e-5 2.11587,0.33205 3.0664,0.99609 0.95051,0.65106 1.62759,1.60158 2.03125,2.85157" style="font-weight:normal;font-stretch:normal;fill:#777777;fill-opacity:1;font-family:Sawasdee;-inkscape-font-specification:Sawasdee" id="path3009" inkscape:connector-curvature="0"/>
<g style="font-weight:normal;fill:#777777;fill-opacity:1;font-family:Sans" id="text3011">
<path d="m 377.53329,536.50769 c 0,-2.8203 0.99577,-5.22622 2.98731,-7.21777 1.99153,-1.99152 4.39127,-2.98729 7.19922,-2.98731 2.8203,2e-5 5.22622,0.99579 7.21777,2.98731 0.38344,0.39585 0.73598,0.81023 1.05762,1.24316 l 0,-2.5791 1.66992,0 0,18.2207 -1.66992,0 0,-3.71093 c -0.32164,0.43294 -0.67418,0.84733 -1.05762,1.24316 -1.99155,1.99154 -4.39747,2.9873 -7.21777,2.9873 -2.80795,0 -5.20769,-0.99576 -7.19922,-2.9873 -1.99154,-1.99153 -2.98731,-4.39127 -2.98731,-7.19922 m 1.7627,0 c 0,2.32553 0.82259,4.31088 2.46777,5.95606 1.64518,1.63281 3.63053,2.44922 5.95606,2.44921 2.3255,10e-6 4.31085,-0.82259 5.95605,-2.46777 1.23696,-1.23697 2.01007,-2.66568 2.31934,-4.28613 l 0,-3.30274 c -0.30927,-1.6328 -1.08238,-3.06769 -2.31934,-4.30468 -1.6452,-1.64517 -3.63055,-2.46776 -5.95605,-2.46778 -2.32553,2e-5 -4.31088,0.82261 -5.95606,2.46778 -1.64518,1.64519 -2.46777,3.63054 -2.46777,5.95605" style="font-size:38px;font-variant:normal;font-stretch:normal;letter-spacing:-1.11000001000000004px;fill:#777777;fill-opacity:1;font-family:Caviar Dreams;-inkscape-font-specification:Caviar Dreams" id="path3018" inkscape:connector-curvature="0"/>
<path d="m 401.65767,536.50769 c 0,-2.8203 0.99576,-5.22622 2.9873,-7.21777 1.99153,-1.99152 4.39127,-2.98729 7.19922,-2.98731 2.8203,2e-5 5.22622,0.99579 7.21778,2.98731 0.38344,0.39585 0.73598,0.81023 1.05761,1.24316 l 0,-14.0459 1.66993,0 0,29.6875 -1.66993,0 0,-3.71093 c -0.32163,0.43294 -0.67417,0.84733 -1.05761,1.24316 -1.99156,1.99154 -4.39748,2.9873 -7.21778,2.9873 -2.80795,0 -5.20769,-0.99576 -7.19922,-2.9873 -1.99154,-1.99153 -2.9873,-4.39127 -2.9873,-7.19922 m 1.76269,0 c 0,2.32553 0.82259,4.31088 2.46778,5.95606 1.64517,1.63281 3.63052,2.44922 5.95605,2.44921 2.32551,10e-6 4.31086,-0.82259 5.95606,-2.46777 1.23696,-1.23697 2.01007,-2.66568 2.31933,-4.28613 l 0,-3.30274 c -0.30926,-1.6328 -1.08237,-3.06769 -2.31933,-4.30468 -1.6452,-1.64517 -3.63055,-2.46776 -5.95606,-2.46778 -2.32553,2e-5 -4.31088,0.82261 -5.95605,2.46778 -1.64519,1.64519 -2.46778,3.63054 -2.46778,5.95605" style="font-size:38px;font-variant:normal;font-stretch:normal;letter-spacing:-1.11000001000000004px;fill:#777777;fill-opacity:1;font-family:Caviar Dreams;-inkscape-font-specification:Caviar Dreams" id="path3020" inkscape:connector-curvature="0"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg viewBox="135 125 577 535" width="442px" height="410px" xmlns="http://www.w3.org/2000/svg" version="1.1">
<line x1="288" y1="170" x2="298" y2="170" style="stroke:#333;stroke-width:1;"/>
<line x1="420" y1="170" x2="430" y2="170" style="stroke:#333;stroke-width:1;"/>
<line x1="298" y1="170" x2="420" y2="170" style="stroke:#333;stroke-width:1;"/>
<line x1="295.5" y1="170" x2="291.96446609407" y2="173.53553390593" style="stroke:#333;stroke-width:2;"/>
<line x1="295.5" y1="170" x2="291.96446609407" y2="166.46446609407" style="stroke:#333;stroke-width:2;"/>
<line x1="425" y1="170" x2="421.46446609407" y2="173.53553390593" style="stroke:#333;stroke-width:2;"/>
<line x1="425" y1="170" x2="421.46446609407" y2="166.46446609407" style="stroke:#333;stroke-width:2;"/>
<line x1="328" y1="290" x2="338" y2="290" style="stroke:#333;stroke-width:1;"/>
<line x1="420" y1="170" x2="430" y2="170" style="stroke:#333;stroke-width:1;"/>
<line x1="338" y1="290" x2="420" y2="170" style="stroke:#333;stroke-width:1;"/>
<line x1="335.5" y1="290" x2="331.96446609407" y2="293.53553390593" style="stroke:#333;stroke-width:2;"/>
<line x1="335.5" y1="290" x2="331.96446609407" y2="286.46446609407" style="stroke:#333;stroke-width:2;"/>
<line x1="425" y1="170" x2="421.46446609407" y2="173.53553390593" style="stroke:#333;stroke-width:2;"/>
<line x1="425" y1="170" x2="421.46446609407" y2="166.46446609407" style="stroke:#333;stroke-width:2;"/>
<rect width="138" height="20" x="430" y="140" style="fill:#007;stroke:black;"/>
<text width="138" height="20" x="435" y="154" style="fill:#fff;" font-family="Arial" font-size="16px"> product</text>
<rect width="138" height="20" x="430" y="160" style="fill:#aea;stroke:black;"/>
<text width="138" height="20" x="435" y="174" style="fill:black;" font-family="Arial" font-size="16px">id</text>
<rect width="138" height="20" x="430" y="180" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="194" style="fill:black;" font-family="Arial" font-size="16px">name</text>
<rect width="138" height="20" x="430" y="200" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="214" style="fill:black;" font-family="Arial" font-size="16px">seo_name</text>
<rect width="138" height="20" x="430" y="220" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="234" style="fill:black;" font-family="Arial" font-size="16px">slug</text>
<rect width="138" height="20" x="430" y="240" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="254" style="fill:black;" font-family="Arial" font-size="16px">reference</text>
<rect width="138" height="20" x="430" y="260" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="274" style="fill:black;" font-family="Arial" font-size="16px">short_description</text>
<rect width="138" height="20" x="430" y="280" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="294" style="fill:black;" font-family="Arial" font-size="16px">seo_description</text>
<rect width="138" height="20" x="430" y="300" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="314" style="fill:black;" font-family="Arial" font-size="16px">position</text>
<rect width="138" height="20" x="430" y="320" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="334" style="fill:black;" font-family="Arial" font-size="16px">weight</text>
<rect width="138" height="20" x="430" y="340" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="354" style="fill:black;" font-family="Arial" font-size="16px">created</text>
<rect width="138" height="20" x="430" y="360" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="374" style="fill:black;" font-family="Arial" font-size="16px">updated</text>
<rect width="138" height="20" x="430" y="380" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="394" style="fill:black;" font-family="Arial" font-size="16px">long_description</text>
<rect width="138" height="20" x="430" y="400" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="414" style="fill:black;" font-family="Arial" font-size="16px">details</text>
<rect width="138" height="20" x="430" y="420" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="434" style="fill:black;" font-family="Arial" font-size="16px">ingredients</text>
<rect width="138" height="20" x="430" y="440" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="454" style="fill:black;" font-family="Arial" font-size="16px">status</text>
<rect width="138" height="20" x="430" y="460" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="474" style="fill:black;" font-family="Arial" font-size="16px">tva</text>
<rect width="138" height="20" x="430" y="480" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="494" style="fill:black;" font-family="Arial" font-size="16px">label</text>
<rect width="138" height="20" x="430" y="500" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="435" y="514" style="fill:black;" font-family="Arial" font-size="16px">description_comp</text>
<rect width="138" height="20" x="150" y="140" style="fill:#007;stroke:black;"/>
<text width="138" height="20" x="155" y="154" style="fill:#fff;" font-family="Arial" font-size="16px"> product_categories</text>
<rect width="138" height="20" x="150" y="160" style="fill:#aea;stroke:black;"/>
<text width="138" height="20" x="155" y="174" style="fill:black;" font-family="Arial" font-size="16px">product_id</text>
<rect width="138" height="20" x="150" y="180" style="fill:#aea;stroke:black;"/>
<text width="138" height="20" x="155" y="194" style="fill:black;" font-family="Arial" font-size="16px">category_id</text>
<rect width="138" height="20" x="190" y="240" style="fill:#007;stroke:black;"/>
<text width="138" height="20" x="195" y="254" style="fill:#fff;" font-family="Arial" font-size="16px"> product_price</text>
<rect width="138" height="20" x="190" y="260" style="fill:#aea;stroke:black;"/>
<text width="138" height="20" x="195" y="274" style="fill:black;" font-family="Arial" font-size="16px">id</text>
<rect width="138" height="20" x="190" y="280" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="195" y="294" style="fill:black;" font-family="Arial" font-size="16px">product_id</text>
<rect width="138" height="20" x="190" y="300" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="195" y="314" style="fill:black;" font-family="Arial" font-size="16px">price</text>
<rect width="138" height="20" x="190" y="320" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="195" y="334" style="fill:black;" font-family="Arial" font-size="16px">context_id</text>
<rect width="138" height="20" x="190" y="340" style="fill:none;stroke:black;"/>
<text width="138" height="20" x="195" y="354" style="fill:black;" font-family="Arial" font-size="16px">price_ttc</text>
</svg>

After

Width:  |  Height:  |  Size: 7.2 KiB

14
cesi/nosql/Makefile Normal file
View File

@ -0,0 +1,14 @@
.PHONY: all slides
.ONESHELL:
all: pdf
slides:
for i in *.md; do php Slides/make.php "$$i" > "Slides/$${i##.md}.html"; done;
pdf: slides
cd Slides; for i in *.html; do prince -o "../$${i##.html}.pdf" "$$i"; done;
clean:
rm -f Slides/*.html
rm -f *.pdf

1
cesi/nosql/Slides/Images Symbolic link
View File

@ -0,0 +1 @@
../Images

View File

@ -0,0 +1,99 @@
<?php
if (empty($argv[1])) {
die("Usage: make.php SOURCE_MARKDOWN > DESTINATION_HTML\n");
}
$lines = file($argv[1]);
$out = '';
$in_list = $in_section = false;
$section_class = null;
function escape($str) {
$str = htmlspecialchars($str);
$str = str_replace('&lt;!--', '<sup>', $str);
$str = str_replace('--&gt;', '</sup>', $str);
$str = preg_replace_callback('/`(.*?)`/', function ($match) {
return '<code>' . $match[1] . '</code>';
}, $str);
$str = preg_replace_callback('/\[(.*?)\]\((.*?)\)/', function ($match) {
return sprintf('<a href="%s">%s</a>', $match[2], $match[1]);
}, $str);
return $str;
}
foreach ($lines as $line)
{
if (preg_match('/^---+(?:\s*=(\w+))?$/', $line, $match)) {
if ($in_section) {
if ($in_list) {
$out .= ' </ul>' . PHP_EOL;
$in_list = false;
}
$out .= '</section>' . PHP_EOL . PHP_EOL;
$in_section = false;
}
$section_class = !empty($match[1]) ? $match[1] : null;
continue;
}
if ('' === trim($line)) {
continue;
}
if (!$in_section) {
$out .= sprintf('<section class="%s">', $section_class) . PHP_EOL;
$in_section = true;
}
if (preg_match('/^(#+)\s+/', $line, $match)) {
$size = strlen($match[1]);
$title = trim(substr($line, strlen($match[0])));
$out .= sprintf(' <h%d>%s</h%d>', $size, escape($title), $size) . PHP_EOL;
}
elseif (preg_match('/^\*\s+/', $line)) {
if (!$in_list) {
$out .= ' <ul>' . PHP_EOL;
$in_list = true;
}
$out .= sprintf(' <li>%s</li>', escape(trim(substr($line, 2)))) . PHP_EOL;
}
else {
$out .= ' ' . trim($line) . PHP_EOL;
}
}
if ($in_section) {
if ($in_list) {
$out .= ' </ul>' . PHP_EOL;
$in_list = false;
}
$out .= '</section>' . PHP_EOL . PHP_EOL;
$in_section = false;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Slides</title>
<link rel="stylesheet" type="text/css" href="style.css" media="screen,presentation" />
<link rel="stylesheet" type="text/css" href="print.css" media="print" />
<script type="text/javascript" src="slides.js"></script>
</head>
<body>
<?=$out?>
</body>
</html>

View File

@ -0,0 +1,12 @@
body {
color: #666;
font-size: .8em;
}
sup {
vertical-align: baseline;
font-size: 1.2em;
display: block;
font-style: italic;
color: #000;
}

148
cesi/nosql/Slides/slides.js Normal file
View File

@ -0,0 +1,148 @@
var slides;
var current_slide = 0;
var current_slide_items;
var current_item = 0;
var slide_window;
var clock;
var timer;
var timer_interval;
var slideCounter;
var planned_duration = 30;
function changeSlide(i, hide_items) {
if (current_slide + i < 0 || current_slide + i >= slides.length)
{
return true;
}
if (slide_window)
{
slide_window.window.changeSlide(i, hide_items);
}
slides[current_slide].classList.remove('current');
current_slide += i;
// Change URL
window.location.hash = "#" + current_slide;
// Get all items in a list
current_slide_items = slides[current_slide].getElementsByTagName('li');
current_item = 0;
for (var i = 0; i < current_slide_items.length; i++)
{
if (hide_items)
{
current_slide_items[i].classList.remove('shown');
}
else
{
current_slide_items[i].classList.add('shown');
}
}
slides[current_slide].classList.add('current');
slideCounter.innerHTML = current_slide + 1;
return true;
}
function progressSlide() {
if (current_item + 1 > current_slide_items.length || current_slide_items[current_item].classList.contains('shown'))
{
return changeSlide(1, true);
}
current_slide_items[current_item++].classList.add('shown');
if (slide_window)
{
slide_window.window.progressSlide();
}
return true;
}
function addTime() {
if (!clock)
{
clock = document.createElement('div');
clock.className = 'clock';
document.body.appendChild(clock);
}
function zerofill(v) {
return ("0" + v).slice(-2);
}
timer = 0;
window.clearInterval(timer_interval);
timer_interval = window.setInterval(function () {
timer += 1;
clock.style.width = Math.round(timer / (planned_duration * 60) * 100) + '%';
}, 1000);
}
function initSlides () {
slides = document.getElementsByTagName('section');
var current = window.location.hash.substr(1);
if (current > 0)
{
current_slide = parseInt(current, 10);
}
slides[current_slide].classList.add('current');
current_slide_items = slides[current_slide].getElementsByTagName('li');
slideCounter = document.createElement('div');
slideCounter.className = 'counter';
document.body.appendChild(slideCounter);
document.onkeydown = function (e) {
var prevent = false;
if (e.key == " ")
{
prevent = progressSlide();
}
else if (e.key == "ArrowRight" || e.key == "ArrowDown" || e.key == "PageDown")
{
prevent = changeSlide(1, false);
}
else if (e.key == "ArrowLeft" || e.key == "ArrowUp" || e.key == "PageUp")
{
prevent = changeSlide(-1, false);
}
else if (e.key == "Home")
{
prevent = changeSlide(-(current_slide), false);
}
else if (e.key == "End")
{
prevent = changeSlide(slides.length - 1, false);
}
else if (e.key == "o")
{
slide_window = window.open(document.location.href);
document.body.className = "notes";
prevent = true;
}
else if (e.key == "s")
{
addTime();
}
if (prevent)
{
e.preventDefault();
return false;
}
return true;
};
}
window.onload = initSlides;

158
cesi/nosql/Slides/style.css Normal file
View File

@ -0,0 +1,158 @@
html, body {
height: 100%;
}
body, section, h1, h2, h3, h4, h5, h6, p, ol, ul, li {
margin: 0;
padding: 0;
}
h1 {
font-size: 400%;
}
h2 {
font-size: 250%;
font-weight: normal;
}
h3 {
font-size: 200%;
font-weight: normal;
}
h1, h2, h3 {
margin-bottom: 1rem;
}
ul, ol {
margin-left: 2em;
font-size: 200%;
}
li {
margin: 1rem 0;
}
ul ul, ul ol, ol ul, ol ol {
font-size: 100%;
}
body {
background: #000;
font-family: "Eras Medium ITC", sans-serif;
overflow: hidden;
color: #fff;
font-size: 16pt;
}
section {
width: 90%;
opacity: 0;
transition: all .7s ease-in-out;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
padding: 5%;
background: #000;
display: flex;
flex-direction: column;
justify-content: space-around;
text-shadow: 0px 0px 10px #000;
visibility: hidden;
}
section.current {
transform: translate(0);
opacity: 1;
visibility: visible;
}
a {
color: inherit;
cursor: pointer;
text-decoration: none;
border-bottom: 2px dashed darkblue;
line-height: .8em;
display: inline-block;
transition: all .5s;
border-radius: .2em;
padding: 0 .1em;
}
a:hover {
border-color: #fff;
background: darkblue;
}
.companyLogo {
margin-top: 3rem;
}
section {
background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,rgba(0,0,0,0.7) 70%), url("Images/logo.svg") no-repeat center bottom;
background-size: contain;
}
li {
transform: translateX(-500px);
opacity: 0;
transition: all .5s;
}
li.shown {
transform: translate(0);
opacity: 1;
}
sup {
display: none;
}
.notes sup {
display: block;
background: #fff;
padding: .2em;
color: #000;
}
.notes {
font-size: 12pt;
}
.clock {
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
font-size: 2em;
background: #333;
height: 5px;
width: 0px;
transition: width 1s linear;
}
.counter {
position: absolute;
right: 5px;
bottom: 5px;
font-size: 1.5em;
}
figure {
margin: 0;
border-radius: .5em;
padding: 1em;
background: rgba(255, 255, 255, 0.3);
text-align: center;
height: 70%;
}
figure img {
height: 95%;
background: #fff;
padding: .5em;
border-radius: .5em;
}