Session 02 : Différence entre versions
(→À voir, à lire) |
(→Les projets) |
||
(61 révisions intermédiaires par 18 utilisateurs non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
+ | [[Fichier:Formulaire-1.jpg|vignette]] | ||
=Session #02: bases de données= | =Session #02: bases de données= | ||
[[Fichier:20141104-bastashevski-nothing personal.jpg]] | [[Fichier:20141104-bastashevski-nothing personal.jpg]] | ||
− | ==Les | + | ==Introduction== |
+ | Cette session porte sur la récupération, l'archivage, l'analyse de données numériques. Il s'agira pour chacun.e de développer une ou plusieurs méthodologie(s) permettant de mener un travail d'enquête et de mise(s) en forme(s) à partir d'un corpus choisi. Durant cette session, nous nous intéresserons à ce qui délimite un corpus, ce qui définit un spécimen, ce qui le transforme en document. Nous aborderons ensuite différents paradigmes de bases de données et les types de d'opérations (et les requêtes) possibles pour chacun d'eux. Enfin, il sera question d'accessibilité à la fois des documents et du processus de travail (quoi partager et comment?). | ||
+ | |||
+ | ==Structures de données: intro== | ||
+ | |||
+ | Exemple de source: https://www.thispersondoesnotexist.com | ||
+ | Un script bash qui permet de télécharger les images de cette source: | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | i=0; while true; do file=$(printf "%04d" $i); wget -O Documents/WORK/images/deepf$file.jpeg https://www.thispersondoesnotexist.com; i=$((i+1)); sleep 1; done; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Pour définir une structure de données: | ||
+ | * Quelles entités? | ||
+ | * Quels champs? | ||
+ | * Pour chaque champ, quels types de valeurs? | ||
+ | * Quelles relations entre les entités? | ||
+ | ** Types de relations possibles: 1:1, 1:n, n:n | ||
+ | * Dessiner la structure (par exemple avec https://textik.com/) | ||
+ | |||
+ | <pre style="white-space: pre;overflow:auto;"> | ||
+ | +--------------------------------------------+ | ||
+ | | | | ||
+ | | image | | ||
+ | |--------------------------------------------| | ||
+ | | --ID | | ||
+ | +------------------------------------+ | - fichier -> text | | ||
+ | | | | - date_capture -> date | | ||
+ | | image_visage | ---| | | ||
+ | |------------------------------------- -----/ | | | ||
+ | | -- ID |--/ | | | ||
+ | | -- ID_image | | | | ||
+ | | -- ID_visage | | | | ||
+ | | | | | | ||
+ | | | | | | ||
+ | +------------------------------------+ +--------------------------------------------+ | ||
+ | \ | ||
+ | | | ||
+ | \ | ||
+ | | | ||
+ | +-------------------------------------------------------+ +------------------------------------------------------+ | ||
+ | | | | | | ||
+ | | visage | | emotion | | ||
+ | | | | | | ||
+ | --------------------------------------------------------| ------------------------------------------------------ | | ||
+ | | - - ID -> integer -------------| - - ID -> integer | | ||
+ | | - presence -> boolean -----------------------/ | | - nom -> texte | | ||
+ | | - emotion -> ------------/ | | | | ||
+ | | | | - indice -> integer (1 à 10) | | ||
+ | | - description -> text | | | | ||
+ | | | | | | ||
+ | | | | | | ||
+ | | | +------------------------------------------------------+ | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | | ||
+ | | | +----------------------------------------------------------+ | ||
+ | | | +-----------------------------------------------------------+ | | | ||
+ | | | | cheveux | | couleur | | ||
+ | | | | | | ---------------------------------------------------------| | ||
+ | | | |-----------------------------------------------------------| | | | ||
+ | | | | | /| -- ID | | ||
+ | | | | -- ID |\ / | - nom -> texte | | ||
+ | | | | - souplesse -> integer (1 à 10) | \ / | | | ||
+ | | | | | \ / | | | ||
+ | | | | | \ / | | | ||
+ | | | | | \ / | | | ||
+ | | | | | | / | | | ||
+ | | | | | \ / | | | ||
+ | | | | | \ / | | | ||
+ | | | +-----------------------------------------------------------+ \ / +----------------------------------------------------------+ | ||
+ | | | ---/ \ / | ||
+ | +-------------------------------------------------------+ ---/ \ / | ||
+ | -----\ ---/ \ / | ||
+ | ---------\ --/ +------|----------------+ | ||
+ | +-----------------------+ | | | ||
+ | | | | cheveux_couleur | | ||
+ | | visage_cheveux | | | | ||
+ | | --------------------- | |-----------------------| | ||
+ | | -- ID | | -- ID_cheveux | | ||
+ | | -- ID_visage | | -- ID_couleurs | | ||
+ | | -- ID_cheveux | | -- ID | | ||
+ | | | | | | ||
+ | | | | | | ||
+ | | | +-----------------------+ | ||
+ | | | | ||
+ | | | | ||
+ | +-----------------------+ </pre> | ||
+ | |||
+ | ===Stocker des données sans base de données=== | ||
+ | * Utiliser les noms de fichiers | ||
+ | * Utiliser des formats de données type json ou xml | ||
+ | |||
+ | ===Les bases de données relationnelles=== | ||
+ | * Langage de requête: Pouvoir écrire le ''quoi'' sans spécifier le ''comment'' | ||
+ | * SQL avec mySQL, MariaDB, PostgreSQL | ||
+ | * Des tables qui contiennent des enregistrements | ||
+ | |||
+ | ===Les bases de données noSQL (orientées documents)=== | ||
+ | * Une structure (champs) qui n'est pas prédéfinie, une base de données qui peut être distribuée | ||
+ | * javascript avec MongoDB | ||
+ | * Des collections qui contiennent des documents | ||
+ | |||
+ | ===Mise en place et utilisation d'une base de données mySQL=== | ||
+ | * Pour pouvoir utiliser une base de données mySQL (ou mariaDB), il faut installer un serveur mySQL soit sur une machine fournie par un hébergeur sur Internet (l'hébergeur le fait la plupart du temps pour vous), soit sur votre ordinateur (on parle alors d'une installation locale). | ||
+ | * La plupart du temps, on installe aussi ce que l'on appelle un serveur web (par exemple apache ou nginx), pour pouvoir interroger le serveur mySQL à partir d'une page web | ||
+ | * Et pour pouvoir précisément faire le lien entre une page web et la base de données il nous faudra un interpréteur de langage orienté serveur (par exemple php). | ||
+ | * La combinaison d'apache, mysql et php peut être installée d'un seul coup sur mac os ou windows avec le programme mamp (pour mac apache mysql php) ou wamp (pour windows apache mysql php). Sous linux, l'installation des 3 serveurs se fait séparément. | ||
+ | * Pour utiliser la base de données autrement que via le terminal ou un script, on peut utiliser un utilitaire de gestion de base de données tel que phpmyadmin (qui est aussi installé automatiquement avec mamp et wamp). | ||
+ | |||
+ | ===Un exemple de formulaire d'encodage=== | ||
+ | Pour un formulaire qui permet d'aider à l'encodage des images provenant du site thispersonisnotreal.com | ||
+ | |||
+ | formulaire.php | ||
+ | <syntaxhighlight lang="php"> | ||
+ | <?php | ||
+ | $conn = new PDO('mysql:host=localhost;dbname=tpdne', 'dede', '56FaSaoDZpILKlSz'); | ||
+ | //SELECT UPDATE INSERT DELETE | ||
+ | $statement = $conn->query('SELECT * FROM emotion'); | ||
+ | $emotions = $statement->fetchAll(PDO::FETCH_ASSOC); | ||
+ | |||
+ | $statement = $conn->query('SELECT * FROM couleur'); | ||
+ | $couleurs = $statement->fetchAll(PDO::FETCH_ASSOC); | ||
+ | |||
+ | |||
+ | ?> | ||
+ | |||
+ | <!doctype html> | ||
+ | <html> | ||
+ | <head> | ||
+ | <link rel="stylesheet" href="styles.css" type="text/css"> | ||
+ | <meta charset="utf-8"> | ||
+ | <title>Formulaire</title> | ||
+ | </head> | ||
+ | <body> | ||
+ | <form action="envoi.php" method="post" enctype="multipart/form-data"> | ||
+ | <section class="form-part" id="infos-generales"> | ||
+ | |||
+ | <label for="filename">Nom du fichier</label> | ||
+ | <input name="filename" type="text" value="test"> | ||
+ | |||
+ | <label for="date">Date et heure de récupération de l'image</label> | ||
+ | <input type="datetime" name="date"> | ||
+ | </section> | ||
+ | |||
+ | <section class="form-part" id="infos-visage"> | ||
+ | |||
+ | <label for="description">Description du visage</label> | ||
+ | <textarea name="description"> | ||
+ | </textarea> | ||
+ | |||
+ | <label for="emotion">Emotion</label> | ||
+ | <select name="emotion"> | ||
+ | <?php | ||
+ | foreach($emotions as $emotion){ | ||
+ | |||
+ | echo '<option value="'.$emotion['id'].'">'.$emotion['nom'].'</option>'; | ||
+ | } | ||
+ | |||
+ | ?> | ||
+ | |||
+ | </select> | ||
+ | |||
+ | <label for="new_emotion">Emotion (si pas listée)</label> | ||
+ | <input type="text" name="new_emotion"> | ||
+ | <label for="emotion_indice">Indice de l'émotion (entre 1 et 10)</label> | ||
+ | <input type="number" name="emotion_indice" min="1" max="10"> | ||
+ | |||
+ | <label for="cheveux_souplesse">Souplesse des cheveux</label> | ||
+ | <input type="number" name="cheveux_souplesse" min="1" max="10"> | ||
+ | |||
+ | <label for="couleurs">Couleurs des cheveux</label> | ||
+ | <select name="couleurs[]" multiple> | ||
+ | <?php | ||
+ | foreach($couleurs as $couleur){ | ||
+ | echo '<option value="'.$couleur['id'].'">'.$couleur['nom'].'</option>'; | ||
+ | |||
+ | } | ||
+ | ?> | ||
+ | </select> | ||
+ | |||
+ | <label for="new_couleur">Couleur (si pas listée)</label> | ||
+ | <input type="text" name="new_couleur"> | ||
+ | </section> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | <!--input type="checkbox"> | ||
+ | <input type="color"> | ||
+ | <input type="radio" name="emotion" value="heureux"> | ||
+ | <input type="radio" name="emotion" value="malheureux"> | ||
+ | <input type="file"--> | ||
+ | |||
+ | <input type="submit" value="envoyer"> | ||
+ | </form> | ||
+ | |||
+ | |||
+ | </body> | ||
+ | </html> | ||
+ | </syntaxhighlight> | ||
+ | envoi.php | ||
+ | <syntaxhighlight lang="php"> | ||
+ | <?php | ||
+ | ini_set('display_errors', 1); | ||
+ | ini_set('display_startup_errors', 1); | ||
+ | error_reporting(E_ALL); | ||
+ | |||
+ | |||
+ | /* insertion avec un champ checkbox | ||
+ | |||
+ | $testbox = 0; | ||
+ | if(isset($_POST['testbox'])){ | ||
+ | $testbox = 1; | ||
+ | } | ||
+ | $conn->exec("INSERT INTO image (box) VALUES ('".$testbox."')"); | ||
+ | */ | ||
+ | |||
+ | |||
+ | |||
+ | $conn = new PDO('mysql:host=localhost;dbname=tpdne', 'dede', '56FaSaoDZpILKlSz'); | ||
+ | //echo $_POST['filename']; | ||
+ | //echo $_POST['date']; | ||
+ | |||
+ | |||
+ | $conn->exec("INSERT INTO image (fichier, date_capture) VALUES ('".$_POST['filename']."', '".$_POST['date']."')"); | ||
+ | print_r($conn->errorInfo()); | ||
+ | |||
+ | $imageId = $conn->lastInsertId(); | ||
+ | |||
+ | |||
+ | if($_POST['new_emotion'] != '' && $_POST['emotion_indice'] != ''){ | ||
+ | $conn->exec("INSERT INTO emotion (nom, indice) VALUES ('".$_POST['new_emotion']."', '".$_POST['emotion_indice']."')"); | ||
+ | |||
+ | $emotionId = $conn->lastInsertId(); | ||
+ | |||
+ | }else{ | ||
+ | |||
+ | $emotionId = $_POST['emotion']; | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | $conn->exec("INSERT INTO visage (emotion, description) VALUES ('".$emotionId."', '".$_POST['description']."')"); | ||
+ | |||
+ | $visageId = $conn->lastInsertId(); | ||
+ | |||
+ | $conn->exec("INSERT INTO image_visage (id_image, id_visage) VALUES ('".$imageId."', '".$visageId."')"); | ||
+ | |||
+ | |||
+ | |||
+ | $couleursId = array(); | ||
+ | |||
+ | if($_POST['new_couleur'] != ''){ | ||
+ | $conn->exec("INSERT INTO couleur (nom) VALUES ('".$_POST['new_couleur']."')"); | ||
+ | |||
+ | $couleursId[] = $conn->lastInsertId(); | ||
+ | |||
+ | } | ||
+ | foreach($_POST['couleurs'] as $couleurId){ | ||
+ | $couleursId[] = $couleurId; | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | //$conn->lastInsertId(); | ||
+ | //print_r($_POST); | ||
+ | |||
+ | ?> | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | ===Un exemple de script de requêtes=== | ||
+ | requete.php | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | <?php | ||
+ | |||
+ | //$connexion = new PDO('mysql:host=localhost;dbname=objet', 'quentin', 'bsZ7ut2ctNk6EgBm'); | ||
+ | |||
+ | |||
+ | $connexion = new PDO('mysql:host=localhost;dbname=gracely', 'quentin', 'bsZ7ut2ctNk6EgBm'); | ||
+ | |||
+ | |||
+ | //SELECT UPDATE INSERT DELETE | ||
+ | //$statement = $connexion->query('SELECT * FROM verre '); | ||
+ | /*$statement = $connexion->query("SELECT nom_verre, nom_fichier FROM verre WHERE (provenance = 'Rome (It)' AND pied_fantaisie = 1) OR jambe_decoration = 0 ORDER BY nom_fichier DESC");*/ | ||
+ | |||
+ | |||
+ | //$statement = $connexion->query("SELECT verre.nom_verre, verre.nom_fichier FROM verre JOIN localisation ON localisation.id = verre.id_localisation WHERE localisation.nom = 'Musée des Arts Décoratifs, Paris (FR)' "); | ||
+ | |||
+ | //$results = $statement->fetchAll(PDO::FETCH_ASSOC); | ||
+ | |||
+ | $statement = $connexion->query("SELECT contenu FROM phrase JOIN phrase_theme ON phrase_theme.ID_phrase = phrase.ID JOIN theme ON phrase_theme.ID_theme = theme.ID WHERE theme.nom = 'Comportement'"); | ||
+ | $results = $statement->fetchAll(PDO::FETCH_ASSOC); | ||
+ | print_r($results); | ||
+ | |||
+ | ?> | ||
+ | |||
+ | <!doctype html> | ||
+ | <html> | ||
+ | <head> | ||
+ | <link rel="stylesheet" href="styles.css" type="text/css"> | ||
+ | <meta charset="utf-8"> | ||
+ | <title>Requete</title> | ||
+ | </head> | ||
+ | <body> | ||
+ | <?php | ||
+ | /*$i = 0; | ||
+ | |||
+ | |||
+ | foreach($results as $element){ | ||
+ | echo '<p class="verre" id="verre-'.$i.'">'.$element['nom_verre'].'</p>'; | ||
+ | echo '<img src="'.$element['nom_fichier'].'">'; | ||
+ | $i = $i+1; | ||
+ | }*/ | ||
+ | ?> | ||
+ | </body> | ||
+ | </html> | ||
+ | </syntaxhighlight> | ||
− | |||
− | |||
==Étapes du projet== | ==Étapes du projet== | ||
# choisir une source de données numériques. | # choisir une source de données numériques. | ||
## les données peuvent être de n'importe quel type de média (texte, vidéo, image, son) | ## les données peuvent être de n'importe quel type de média (texte, vidéo, image, son) | ||
− | ## types de sources possibles: un site web / un blog / un journal en ligne | + | ## types de sources possibles: un site web / un blog / un journal en ligne / un catalogue / une base de données de textes / de vidéos / de sons, etc. |
− | ## exemples: http://wikileaks.org, https://www.gutenberg.org/, https://freesound.org/, http://youtube.com, http://maps.google.com | + | ## exemples: http://wikileaks.org, https://www.gutenberg.org/, https://freesound.org/, http://youtube.com, http://maps.google.com, http://patents.google.com |
# définir un corpus. Il s'agit d'appliquer des limites à la source choisie pour ne s'intéresser qu'à une partie des données diffusées. | # définir un corpus. Il s'agit d'appliquer des limites à la source choisie pour ne s'intéresser qu'à une partie des données diffusées. | ||
## types de limites: temporelles, géographiques, thématiques, liées à un groupe, liées à une personne, liées à un type de média, etc. | ## types de limites: temporelles, géographiques, thématiques, liées à un groupe, liées à une personne, liées à un type de média, etc. | ||
− | ## exemples: une fuite de wikileaks, une rubrique d'un site, un auteur sur le projet Gutenberg, une recherche Youtube, etc. | + | ## exemples: une fuite de wikileaks, une rubrique d'un site, un auteur sur le projet Gutenberg, une recherche Youtube, le rayoon d'une bibliothèque etc. |
# extraire des spécimens. Il s'agit d'extraire du corpus une sélection limitée d'éléments, donc de définir les limites propres à ces éléments, avant de les analyser. | # extraire des spécimens. Il s'agit d'extraire du corpus une sélection limitée d'éléments, donc de définir les limites propres à ces éléments, avant de les analyser. | ||
− | ## exemples: un post, une image, une frame de vidéo, une séquence sonore, un paragraphe, etc. | + | ## exemples: un post, une image, une frame de vidéo, une séquence sonore, un paragraphe, une fiche, etc. |
## des spécimens de types différents peuvent être extraits du même corpus | ## des spécimens de types différents peuvent être extraits du même corpus | ||
# pour chaque spécimen, créer une fiche descriptive. Quelles propriétés des spécimens peuvent être intéressantes? | # pour chaque spécimen, créer une fiche descriptive. Quelles propriétés des spécimens peuvent être intéressantes? | ||
− | ## exemples: dates, | + | ## exemples: dates, occurrences de mots, couleur, dimensions, fréquence sonore, position d'un objet dans une image, etc. |
# choisir un type de base de données et définir une structure permettant d'encoder les fiches définies à l'étape précédente | # choisir un type de base de données et définir une structure permettant d'encoder les fiches définies à l'étape précédente | ||
## exemples: tableur, base de données mysql, dossier contenant des fichiers | ## exemples: tableur, base de données mysql, dossier contenant des fichiers | ||
− | # définir une méthode d'encodage des | + | ## cela implique de créer une schéma de la base de données (type de relations, type de requêtes) signifiant sa structure (et donc sa cohérence et sa faisabilité, son niveau de complexité). |
+ | # définir une méthode d'encodage des spécimens dans la base de données | ||
## soit automatiquement soit manuellement soit un mélange des deux | ## soit automatiquement soit manuellement soit un mélange des deux | ||
## définir la fréquence, la vitesse, les étapes propres à l'encodage | ## définir la fréquence, la vitesse, les étapes propres à l'encodage | ||
# encoder tout ou une partie du corpus | # encoder tout ou une partie du corpus | ||
# expérimenter des requêtes à envoyer à la base de données | # expérimenter des requêtes à envoyer à la base de données | ||
− | ## exemples: sélectionner tous les chapitres qui contiennent le mot "guerre", sélectionner tous les auteurs qui ont répondu par un smiley à un message | + | ## exemples: sélectionner tous les chapitres qui contiennent le mot "guerre", sélectionner tous les auteurs qui ont répondu par un smiley à un message, sélectionner tous les éléments ordonnés selon un certain champs, etc. |
Et tout le long: comment rendre accessible chaque étape du projet? Quelle mise en forme, quel accès? | Et tout le long: comment rendre accessible chaque étape du projet? Quelle mise en forme, quel accès? | ||
+ | |||
+ | ==Les projets== | ||
+ | |||
+ | [[Quentin Lamouroux - La fétichisation de l'Objet ]] | ||
+ | |||
+ | [[Charlotte Ecker]] | ||
+ | |||
+ | [[Simon Bouvier - ]] | ||
+ | |||
+ | [[Jade Rouanet]] | ||
+ | |||
+ | [[INSECAM|Laura Conant]] | ||
+ | |||
+ | [[Emma Cottin]] | ||
+ | |||
+ | [[Maxine Ying - RO]] | ||
+ | |||
+ | [[Clara - Fleurs]] | ||
+ | |||
+ | [[Zoe Dadamo - 02]] | ||
+ | |||
+ | [[Maud Hazgour]] | ||
+ | |||
+ | [[Worker.mturk.com|Lena Bruyère - Mturk]] | ||
+ | |||
+ | [[Salle de lecture-Frédéric Jaman]] | ||
+ | |||
+ | [[WAYBACK MACHINE|Ayasha Khan]] | ||
+ | |||
+ | [https://pratiquesnumeriques.be/index.php?title=The_Op%C3%A9ra#Pr.C3.A9sentation Adèle Boterf] | ||
+ | |||
+ | [[Zoe Flts Data Base]] | ||
+ | |||
+ | [[Alice Dutertre - Techniques d'Archivages ]] | ||
+ | |||
+ | [[Emile F - FakenewsBrowser]] | ||
==À voir, à lire== | ==À voir, à lire== | ||
<embedvideo service="youtube">https://www.youtube.com/watch?v=m4dc976GX0k&t=16s</embedvideo> | <embedvideo service="youtube">https://www.youtube.com/watch?v=m4dc976GX0k&t=16s</embedvideo> | ||
− | + | ||
+ | https://www.maribastashevski.com/nothing-personal-extract | ||
+ | |||
+ | https://mishkahenner.com/Dutch-Landscapes | ||
+ | |||
+ | <embedvideo service="vimeo">https://vimeo.com/204951759</embedvideo> | ||
+ | |||
+ | http://elahi.umd.edu/track/ | ||
+ | |||
+ | https://cloud.editionsdevisscher.be/apps/gallery/s/ke4D8S6r8AysJLJ | ||
+ | |||
+ | Les bibliothèques de l'ombre: alexiadevisscher.be/piratelibraries.html | ||
+ | |||
+ | La Trilogie d’'''On Kawara''' se compose d’''I GOT UP'', ''I WENT'' et ''I MET'', 36 volumes (13690 pages au total) permettant des croisements d'informations: https://www.youtube.com/watch?v=YxOynktWnMw | ||
+ | |||
+ | De 1993 à 2015, la Néerlandaise '''Dana Lixenberg''' a photographié les habitants d’[http://www.imperialcourtsproject.com Imperial Courts], qui fut l’épicentre des émeutes de 1991. 3 types d'infos (noms, années de prises de vue et liens de parenté) permettent de multiples navigations au sein du site Web et du livre qui documentent ce projet. |
Version actuelle datée du 14 mai 2019 à 13:22
Sommaire
Session #02: bases de données
Introduction
Cette session porte sur la récupération, l'archivage, l'analyse de données numériques. Il s'agira pour chacun.e de développer une ou plusieurs méthodologie(s) permettant de mener un travail d'enquête et de mise(s) en forme(s) à partir d'un corpus choisi. Durant cette session, nous nous intéresserons à ce qui délimite un corpus, ce qui définit un spécimen, ce qui le transforme en document. Nous aborderons ensuite différents paradigmes de bases de données et les types de d'opérations (et les requêtes) possibles pour chacun d'eux. Enfin, il sera question d'accessibilité à la fois des documents et du processus de travail (quoi partager et comment?).
Structures de données: intro
Exemple de source: https://www.thispersondoesnotexist.com Un script bash qui permet de télécharger les images de cette source:
i=0; while true; do file=$(printf "%04d" $i); wget -O Documents/WORK/images/deepf$file.jpeg https://www.thispersondoesnotexist.com; i=$((i+1)); sleep 1; done;
Pour définir une structure de données:
- Quelles entités?
- Quels champs?
- Pour chaque champ, quels types de valeurs?
- Quelles relations entre les entités?
- Types de relations possibles: 1:1, 1:n, n:n
- Dessiner la structure (par exemple avec https://textik.com/)
+--------------------------------------------+ | | | image | |--------------------------------------------| | --ID | +------------------------------------+ | - fichier -> text | | | | - date_capture -> date | | image_visage | ---| | |------------------------------------- -----/ | | | -- ID |--/ | | | -- ID_image | | | | -- ID_visage | | | | | | | | | | | +------------------------------------+ +--------------------------------------------+ \ | \ | +-------------------------------------------------------+ +------------------------------------------------------+ | | | | | visage | | emotion | | | | | --------------------------------------------------------| ------------------------------------------------------ | | - - ID -> integer -------------| - - ID -> integer | | - presence -> boolean -----------------------/ | | - nom -> texte | | - emotion -> ------------/ | | | | | | - indice -> integer (1 à 10) | | - description -> text | | | | | | | | | | | | | +------------------------------------------------------+ | | | | | | | | | | +----------------------------------------------------------+ | | +-----------------------------------------------------------+ | | | | | cheveux | | couleur | | | | | | ---------------------------------------------------------| | | |-----------------------------------------------------------| | | | | | | /| -- ID | | | | -- ID |\ / | - nom -> texte | | | | - souplesse -> integer (1 à 10) | \ / | | | | | | \ / | | | | | | \ / | | | | | | \ / | | | | | | | / | | | | | | \ / | | | | | | \ / | | | | +-----------------------------------------------------------+ \ / +----------------------------------------------------------+ | | ---/ \ / +-------------------------------------------------------+ ---/ \ / -----\ ---/ \ / ---------\ --/ +------|----------------+ +-----------------------+ | | | | | cheveux_couleur | | visage_cheveux | | | | --------------------- | |-----------------------| | -- ID | | -- ID_cheveux | | -- ID_visage | | -- ID_couleurs | | -- ID_cheveux | | -- ID | | | | | | | | | | | +-----------------------+ | | | | +-----------------------+
Stocker des données sans base de données
- Utiliser les noms de fichiers
- Utiliser des formats de données type json ou xml
Les bases de données relationnelles
- Langage de requête: Pouvoir écrire le quoi sans spécifier le comment
- SQL avec mySQL, MariaDB, PostgreSQL
- Des tables qui contiennent des enregistrements
Les bases de données noSQL (orientées documents)
- Une structure (champs) qui n'est pas prédéfinie, une base de données qui peut être distribuée
- javascript avec MongoDB
- Des collections qui contiennent des documents
Mise en place et utilisation d'une base de données mySQL
- Pour pouvoir utiliser une base de données mySQL (ou mariaDB), il faut installer un serveur mySQL soit sur une machine fournie par un hébergeur sur Internet (l'hébergeur le fait la plupart du temps pour vous), soit sur votre ordinateur (on parle alors d'une installation locale).
- La plupart du temps, on installe aussi ce que l'on appelle un serveur web (par exemple apache ou nginx), pour pouvoir interroger le serveur mySQL à partir d'une page web
- Et pour pouvoir précisément faire le lien entre une page web et la base de données il nous faudra un interpréteur de langage orienté serveur (par exemple php).
- La combinaison d'apache, mysql et php peut être installée d'un seul coup sur mac os ou windows avec le programme mamp (pour mac apache mysql php) ou wamp (pour windows apache mysql php). Sous linux, l'installation des 3 serveurs se fait séparément.
- Pour utiliser la base de données autrement que via le terminal ou un script, on peut utiliser un utilitaire de gestion de base de données tel que phpmyadmin (qui est aussi installé automatiquement avec mamp et wamp).
Un exemple de formulaire d'encodage
Pour un formulaire qui permet d'aider à l'encodage des images provenant du site thispersonisnotreal.com
formulaire.php
<?php
$conn = new PDO('mysql:host=localhost;dbname=tpdne', 'dede', '56FaSaoDZpILKlSz');
//SELECT UPDATE INSERT DELETE
$statement = $conn->query('SELECT * FROM emotion');
$emotions = $statement->fetchAll(PDO::FETCH_ASSOC);
$statement = $conn->query('SELECT * FROM couleur');
$couleurs = $statement->fetchAll(PDO::FETCH_ASSOC);
?>
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="styles.css" type="text/css">
<meta charset="utf-8">
<title>Formulaire</title>
</head>
<body>
<form action="envoi.php" method="post" enctype="multipart/form-data">
<section class="form-part" id="infos-generales">
<label for="filename">Nom du fichier</label>
<input name="filename" type="text" value="test">
<label for="date">Date et heure de récupération de l'image</label>
<input type="datetime" name="date">
</section>
<section class="form-part" id="infos-visage">
<label for="description">Description du visage</label>
<textarea name="description">
</textarea>
<label for="emotion">Emotion</label>
<select name="emotion">
<?php
foreach($emotions as $emotion){
echo '<option value="'.$emotion['id'].'">'.$emotion['nom'].'</option>';
}
?>
</select>
<label for="new_emotion">Emotion (si pas listée)</label>
<input type="text" name="new_emotion">
<label for="emotion_indice">Indice de l'émotion (entre 1 et 10)</label>
<input type="number" name="emotion_indice" min="1" max="10">
<label for="cheveux_souplesse">Souplesse des cheveux</label>
<input type="number" name="cheveux_souplesse" min="1" max="10">
<label for="couleurs">Couleurs des cheveux</label>
<select name="couleurs[]" multiple>
<?php
foreach($couleurs as $couleur){
echo '<option value="'.$couleur['id'].'">'.$couleur['nom'].'</option>';
}
?>
</select>
<label for="new_couleur">Couleur (si pas listée)</label>
<input type="text" name="new_couleur">
</section>
<!--input type="checkbox">
<input type="color">
<input type="radio" name="emotion" value="heureux">
<input type="radio" name="emotion" value="malheureux">
<input type="file"-->
<input type="submit" value="envoyer">
</form>
</body>
</html>
envoi.php
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
/* insertion avec un champ checkbox
$testbox = 0;
if(isset($_POST['testbox'])){
$testbox = 1;
}
$conn->exec("INSERT INTO image (box) VALUES ('".$testbox."')");
*/
$conn = new PDO('mysql:host=localhost;dbname=tpdne', 'dede', '56FaSaoDZpILKlSz');
//echo $_POST['filename'];
//echo $_POST['date'];
$conn->exec("INSERT INTO image (fichier, date_capture) VALUES ('".$_POST['filename']."', '".$_POST['date']."')");
print_r($conn->errorInfo());
$imageId = $conn->lastInsertId();
if($_POST['new_emotion'] != '' && $_POST['emotion_indice'] != ''){
$conn->exec("INSERT INTO emotion (nom, indice) VALUES ('".$_POST['new_emotion']."', '".$_POST['emotion_indice']."')");
$emotionId = $conn->lastInsertId();
}else{
$emotionId = $_POST['emotion'];
}
$conn->exec("INSERT INTO visage (emotion, description) VALUES ('".$emotionId."', '".$_POST['description']."')");
$visageId = $conn->lastInsertId();
$conn->exec("INSERT INTO image_visage (id_image, id_visage) VALUES ('".$imageId."', '".$visageId."')");
$couleursId = array();
if($_POST['new_couleur'] != ''){
$conn->exec("INSERT INTO couleur (nom) VALUES ('".$_POST['new_couleur']."')");
$couleursId[] = $conn->lastInsertId();
}
foreach($_POST['couleurs'] as $couleurId){
$couleursId[] = $couleurId;
}
//$conn->lastInsertId();
//print_r($_POST);
?>
Un exemple de script de requêtes
requete.php
<?php
//$connexion = new PDO('mysql:host=localhost;dbname=objet', 'quentin', 'bsZ7ut2ctNk6EgBm');
$connexion = new PDO('mysql:host=localhost;dbname=gracely', 'quentin', 'bsZ7ut2ctNk6EgBm');
//SELECT UPDATE INSERT DELETE
//$statement = $connexion->query('SELECT * FROM verre ');
/*$statement = $connexion->query("SELECT nom_verre, nom_fichier FROM verre WHERE (provenance = 'Rome (It)' AND pied_fantaisie = 1) OR jambe_decoration = 0 ORDER BY nom_fichier DESC");*/
//$statement = $connexion->query("SELECT verre.nom_verre, verre.nom_fichier FROM verre JOIN localisation ON localisation.id = verre.id_localisation WHERE localisation.nom = 'Musée des Arts Décoratifs, Paris (FR)' ");
//$results = $statement->fetchAll(PDO::FETCH_ASSOC);
$statement = $connexion->query("SELECT contenu FROM phrase JOIN phrase_theme ON phrase_theme.ID_phrase = phrase.ID JOIN theme ON phrase_theme.ID_theme = theme.ID WHERE theme.nom = 'Comportement'");
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
print_r($results);
?>
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="styles.css" type="text/css">
<meta charset="utf-8">
<title>Requete</title>
</head>
<body>
<?php
/*$i = 0;
foreach($results as $element){
echo '<p class="verre" id="verre-'.$i.'">'.$element['nom_verre'].'</p>';
echo '<img src="'.$element['nom_fichier'].'">';
$i = $i+1;
}*/
?>
</body>
</html>
Étapes du projet
- choisir une source de données numériques.
- les données peuvent être de n'importe quel type de média (texte, vidéo, image, son)
- types de sources possibles: un site web / un blog / un journal en ligne / un catalogue / une base de données de textes / de vidéos / de sons, etc.
- exemples: http://wikileaks.org, https://www.gutenberg.org/, https://freesound.org/, http://youtube.com, http://maps.google.com, http://patents.google.com
- définir un corpus. Il s'agit d'appliquer des limites à la source choisie pour ne s'intéresser qu'à une partie des données diffusées.
- types de limites: temporelles, géographiques, thématiques, liées à un groupe, liées à une personne, liées à un type de média, etc.
- exemples: une fuite de wikileaks, une rubrique d'un site, un auteur sur le projet Gutenberg, une recherche Youtube, le rayoon d'une bibliothèque etc.
- extraire des spécimens. Il s'agit d'extraire du corpus une sélection limitée d'éléments, donc de définir les limites propres à ces éléments, avant de les analyser.
- exemples: un post, une image, une frame de vidéo, une séquence sonore, un paragraphe, une fiche, etc.
- des spécimens de types différents peuvent être extraits du même corpus
- pour chaque spécimen, créer une fiche descriptive. Quelles propriétés des spécimens peuvent être intéressantes?
- exemples: dates, occurrences de mots, couleur, dimensions, fréquence sonore, position d'un objet dans une image, etc.
- choisir un type de base de données et définir une structure permettant d'encoder les fiches définies à l'étape précédente
- exemples: tableur, base de données mysql, dossier contenant des fichiers
- cela implique de créer une schéma de la base de données (type de relations, type de requêtes) signifiant sa structure (et donc sa cohérence et sa faisabilité, son niveau de complexité).
- définir une méthode d'encodage des spécimens dans la base de données
- soit automatiquement soit manuellement soit un mélange des deux
- définir la fréquence, la vitesse, les étapes propres à l'encodage
- encoder tout ou une partie du corpus
- expérimenter des requêtes à envoyer à la base de données
- exemples: sélectionner tous les chapitres qui contiennent le mot "guerre", sélectionner tous les auteurs qui ont répondu par un smiley à un message, sélectionner tous les éléments ordonnés selon un certain champs, etc.
Et tout le long: comment rendre accessible chaque étape du projet? Quelle mise en forme, quel accès?
Les projets
Quentin Lamouroux - La fétichisation de l'Objet
Salle de lecture-Frédéric Jaman
Alice Dutertre - Techniques d'Archivages
À voir, à lire
https://www.maribastashevski.com/nothing-personal-extract
https://mishkahenner.com/Dutch-Landscapes
https://cloud.editionsdevisscher.be/apps/gallery/s/ke4D8S6r8AysJLJ
Les bibliothèques de l'ombre: alexiadevisscher.be/piratelibraries.html
La Trilogie d’On Kawara se compose d’I GOT UP, I WENT et I MET, 36 volumes (13690 pages au total) permettant des croisements d'informations: https://www.youtube.com/watch?v=YxOynktWnMw
De 1993 à 2015, la Néerlandaise Dana Lixenberg a photographié les habitants d’Imperial Courts, qui fut l’épicentre des émeutes de 1991. 3 types d'infos (noms, années de prises de vue et liens de parenté) permettent de multiples navigations au sein du site Web et du livre qui documentent ce projet.