(BDD) est un logiciel qui permet d'organiser des données sur un disque dur de manière organisée. • Répond au besoin de stocker de l'information dans un système informatique de manière optimisée • Le modèle de données est à définir en fonction de la finalité de la base de données • La taille d'une base de données dépend de la complexité de ce que l'on modélise et de la popularité du système informatique (quelques Mo à plusieurs To) • Permet de stocker de l'information de manière structurée la plupart du temps • Il existe plusieurs acteurs de système de gestion de bases de données 3
dans une base de données permettent de stocker de l'information. Dans chaque table, on stocke un concept (un utilisateur, un moyen de secours, un message etc.). On ne stocke pas des concepts différents dans une même table. Les tables peuvent avoir des liaisons entre elles ("un utilisateur possède 0..n comptes bancaires"). Si le domaine métier est complexe, la base de données aura un schéma complexe et ainsi un grand nombre de tables. Les tables ressemblent à des feuilles de tableur : ce sont des tableaux à structure fixe qui comportent plusieurs champs / colonnes et plusieurs lignes. 4
des tables peuvent être de différents types : • texte : adresse e-mail, nom d'un établissement • entiers : nombre de portes d'une maison, identifiant numérique • nombres décimaux : prix, température en degrés • booléens : vrai / faux • dates : date de création, date d'expédition Le type d'une colonne ne peut pas être changé. Ce type définit ce qu'il est possible de stocker et quelles seront les utilisations possibles des données. 5
données, on utilise le langage SQL • Le langage SQL est apparu dans les années 70-80 et a très peu évolué depuis • Une immense majorité des acteurs de bases de données relationnelles respectent le standard du langage, avec quelques modifications mineures • On utilise le langage SQL pour créer des tables, insérer des données, récupérer des données, mettre à jour des données, supprimer des données 8
classique comporte 3 parties : • SELECT : spécifie quels champs des tables nous intéressent • FROM : spécifie depuis quelle table nous récupérons les données • WHERE : spécifie les contraintes à appliquer lorsque nous récupérons les données Exemple : sélection de tous les noms des CROSS et des numéros d'opération depuis 2017 SELECT "operation_id", "cross" FROM "operations" WHERE "date_heure_reception_alerte" >= '2017-01-01' 9
"operation_id", "cross", "cross_sitrep" FROM "operations" WHERE "date_heure_reception_alerte" >= '2017-01-01' AND "evenement" IN ('Abordage', 'Baignade') AND ("mer_force" BETWEEN 2 AND 5 OR "vent_force" BETWEEN 5 AND 8) AND "cross" <> 'La Garde' 10
doublons en effectuant une comparaison stricte (Bob est différent de BOB). SELECT DISTINCT "evenement" FROM "operations" SELECT COUNT(DISTINCT "cross") FROM "operations" 11
Garde en 2018 avec un vent supérieur à 2. Trouver la date d'alerte, le CROSS et la position GPS pour les opérations concernant une activité de plongée entre 2010 et 2015 qui ne se déroulent pas à La Garde. 12
AND "vent_force" > 2 SELECT "date_heure_reception_alerte", "cross", "latitude", "longitude" FROM "operations" WHERE "evenement" = 'Plongée à bouteille' AND "date_heure_reception_alerte" BETWEEN '2010-01-01' AND '2015-12-31' AND "cross" <> 'La Garde' 13
produire des agrégats quand on ne s'intéresse pas au détail de chaque ligne. Pour ceci, on utilise l'opérateur GROUP BY et des fonctions d'agrégats. Fonctions d'agrégats classiques : • AVG : calcule une moyenne dans un groupe • COUNT : compte le nombre de lignes dans un groupe • MIN : trouve la valeur minimale dans un groupe • MAX : trouve la valeur maximale dans un groupe • SUM : calcule une somme de valeurs dans un groupe 14
d'opérations par CROSS et par moyen d'alerte sur l'année 2017. SELECT "cross", "moyen_alerte", count("operation_id") as "nombre_operations" FROM "operations" WHERE "date_heure_reception_alerte" BETWEEN '2017-01-01' AND '2018-01-01' GROUP BY "cross", "moyen_alerte" 15
spécifier qu'une valeur est absente (et non pas vide). Elle peut être utilisée pour tous les types de données. Lors de la création d'une table, il est possible de spécifier qu'aucune valeur ne peut valoir la valeur NULL au niveau de chaque colonne. SELECT "departement", count("operation_id") FROM "operations" GROUP BY "departement" SELECT "cross_sitrep", "latitude", "longitude" FROM "operations" WHERE "latitude" IS NULL AND "longitude" IS NOT NULL 16
requête. Trouvons les journées avec plus de 100 opérations CROSS. select * from ( select "annee", "mois", "jour", count("operation_id") as "nb_operations" from "operations_stats" group by "annee", "mois", "jour" ) as "t" where "nb_operations" > 100 17 Nouveautés : ◦ Alias d'une colonne ◦ Création d'une table virtuelle aliassée ◦ Sélection de toutes les colonnes avec *
la combinant avec un IN ou un NOT IN, on peut combiner les résultats de plusieurs sources. select "cross", count("operation_id") as "nb_operations" from "operations" where "operation_id" in ( select "operation_id" from "operations_stats" where "nombre_moyens_aeriens_engages" > 0 and "nombre_personnes_tous_deces_ou_disparues_sans_clandestins" > 0 and "annee" = 2017 ) group by "cross" 18
données provenant de plusieurs tables en même temps ? Avec des jointures. Trouvons tous les numéros de SITREP qui rentrent dans le cadre du SNOSAN en 2017. select "op"."cross_sitrep" from "operations" as "op" join "operations_stats" as "stats" on "stats"."operation_id" = "op"."operation_id" where "stats"."concerne_snosan" = true and "stats"."annee" = 2017 19
depuis 2010, qui rentrent dans le cadre d'étude du SNOSAN. Trouver le nombre de personnes décédées ou disparues en omettant les clandestins par année et par CROSS, lors de la saison estivale (d'avril à octobre inclus). Trouver le nombre de moyens nautiques et aériens engagés suite à un isolement par la marée par année depuis 2000. 20
op JOIN "operations_stats" stats ON stats."operation_id" = op."operation_id" WHERE stats."concerne_snosan" = true AND stats."annee" >= 2010 GROUP BY op."evenement", op."cross", stats."annee" SELECT op."cross", stats."annee", sum(stats."nombre_personnes_tous_deces_ou_disparues_sans_clande stins") total_decedes_disparus FROM "operations" op JOIN "operations_stats" stats ON stats."operation_id" = op."operation_id" WHERE stats."mois" BETWEEN 4 AND 10 GROUP BY op."cross", stats."annee" 21
JOIN "operations_stats" stats ON stats."operation_id" = op."operation_id" WHERE stats."annee" >= 2000 AND op."evenement" = 'Isolé par la marée / Envasé' GROUP BY stats."annee" 22
par année pour les opérations impliquant au moins un kitesurf. Trouvez le nombre d'opérations et le nombre de personnes décédées ou disparues suite à une chute à la mer par phase de la journée entre 2010 et 2017 pour les opérations dans le cadre d'étude du SNOSAN 23
JOIN "operations_stats" stats ON stats."operation_id" = op."operation_id" WHERE stats."nombre_flotteurs_kitesurf_impliques" >= 1 GROUP BY stats."annee", op."moyen_alerte" SELECT stats."phase_journee", sum(stats."nombre_personnes_tous_deces_ou_disparues_sans_clande stins") as total_decedes_disparus, count(op."operation_id") as nb_operations FROM "operations" op JOIN "operations_stats" stats ON stats."operation_id" = op."operation_id" WHERE stats."concerne_snosan" = true AND op."evenement" = 'Homme à la mer' AND stats."annee" BETWEEN 2010 AND 2017 GROUP BY stats."phase_journee" 24
colonnes ou la position des colonnes dans le GROUP BY. Les requêtes suivantes sont équivalentes. Ceci est très utile quand on applique des fonctions à des colonnes et qu'elles n'ont pas de nom. select marque, nom_serie, count(1) from flotteurs group by marque, nom_serie select marque, nom_serie, count(1) from flotteurs group by 1, 2 Raccourcis dans les requêtes d'agrégation 25
SQL pour simplifier la lecture. select stats.annee, o."cross", count(1) from operations o join operations_stats stats on stats.operation_id = o.operation_id group by 1, 2 order by 1 asc, 3 desc Ordonner le résultat d'une requête 26
une jointure interne et une jointure à gauche. Il n'y a pas de différence entre une jointure à gauche et une jointure à droite. Il suffit d'inverser les ensembles. select count(op.operation_id) from operations op left join flotteurs f on f.operation_id = op.operation_id select count(op.operation_id) from operations op join flotteurs f on f.operation_id = op.operation_id 28
applique-t-on des contraintes avec des jointures. On peut se retrouver à écrire malgré soi une jointure interne alors qu'on pense écrire une jointure à gauche. select count(op.operation_id) from operations op left join flotteurs f on f.operation_id = op.operation_id where f.resultat_flotteur = 'Remorqué' select count(op.operation_id) from operations op left join flotteurs f on f.operation_id = op.operation_id and f.resultat_flotteur = 'Remorqué' 29
Marine Nationale par année et par CROSS pour les opérations dans le cadre d'étude du SNOSAN depuis 2005. Trouver le nombre d'opérations sans bilan humain par année depuis 2010, sans utiliser la table operations_stats. 30
colonnes pour transformer les valeurs de celles-ci. • LOWER / UPPER : transformer en minuscules / majuscules • ROUND : arrondir des chiffres • || : concaténer du texte • at time zone : convertir des dates à un fuseau horaire select o.date_heure_reception_alerte at time zone 'utc', o.date_heure_reception_alerte at time zone o.fuseau_horaire, round(o.latitude), UPPER(o."cross") || ' ' || o.numero_sitrep from operations o Fonctions SQL 31
champs textes. Ceci est par exemple utile si l'on s'intéresse aux marques et modèles de navires. On utilise l'opérateur LIKE dans ce cas. Les pourcentages indique que l'on peut avoir n'importe quoi avant ou après le mot first dans la colonne nom_serie. select marque, nom_serie, count(1) from flotteurs where lower(nom_serie) like '%first%' group by marque, nom_serie Recherche par motif 32