From 9ad5b99920fb167f68d963abf35715da92f9e3e6 Mon Sep 17 00:00:00 2001 From: Florian Mathieu Date: Mon, 15 Jun 2026 11:28:37 +0200 Subject: [PATCH] =?UTF-8?q?Review=20cours=20Terminale=20NSI=20=E2=80=94=20?= =?UTF-8?q?POO,=20SQL,=20S=C3=A9curit=C3=A9,=20Soc,=20Calculabilit=C3=A9,?= =?UTF-8?q?=20R=C3=A9seau?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Calculabilité/README.md | 100 ++- POO/README.md | 82 ++ POO/TP/TP_Pokemon.md | 105 ++- Réseau/README.md | 26 +- SQL/Cours_SQL.md | 554 -------------- SQL/README.md | 724 ++++++++++++------ SQL/TP_SQLite.md | 372 +++++++++ Soc/{Cours_circuits_integres.md => README.md} | 76 ++ Sécurité/README.md | 93 +++ 9 files changed, 1305 insertions(+), 827 deletions(-) delete mode 100644 SQL/Cours_SQL.md create mode 100644 SQL/TP_SQLite.md rename Soc/{Cours_circuits_integres.md => README.md} (73%) diff --git a/Calculabilité/README.md b/Calculabilité/README.md index c18c092..33b4cae 100644 --- a/Calculabilité/README.md +++ b/Calculabilité/README.md @@ -53,7 +53,7 @@ Et donc, par extension, si un problème n'est pas soluble, on utilisera le terme ------- -## ~~La calcul habilité~~ La calculabilité +## La calculabilité En informatique, plus précisément dans la branche dite de programmation, nous utilisons un langage qui nous est propre afin de mettre en place nos idées dans un algorithme. @@ -184,41 +184,19 @@ La question qui se pose à nous est de savoir comment reconnaitre un problème i Pour déduire l'indécidabilité d'un programme, il faut un algorithme répondant à ce problème et également la preuve qu'il se termine. -En mathématiques, on utilise le ***problème de l'arrêt*** +En informatique, le plus célèbre de ces problèmes indécidables est le ***problème de l'arrêt***. -### Un peu plus d'histoire... +### Le problème de l'arrêt -En 1931, Kurt Gödel, mathématicien et logicien autrichien, énonce son théorème d'incomplétude. +En 1936, le mathématicien britannique **Alan Turing** démontre qu'il est impossible d'écrire un algorithme qui, pour n'importe quel programme et n'importe quelle entrée, dirait avec certitude si ce programme s'arrête ou tourne à l'infini. -Il y établit qu'une théorie suffisante pour y démontrer les théorèmes de base de l'arithmétique -la partie des mathématiques qui s'occupe des nombres, en opposition à la géométrie - est nécessairement incomplète, au sens où il existe des énoncés qui n'y sont ni démontrables, ni réfutables . On parle alors d'énoncés indécidables dans la théorie. +Sa démonstration repose sur un **raisonnement par l'absurde** : on suppose qu'un tel algorithme existe, et on montre que cette supposition mène inévitablement à une contradiction. -Note : Il s'agit de la définition Wikipédia +#### Le programme qui détermine l'arrêt est lui-même indécidable -Il parle également d'***Axiomes*** +On peut même dire *absurde* — et c'est justement le mot qu'on va utiliser. -Un axiome est une proposition non démontrée que l'on va utiliser pour tenter de résoudre un problème. - -C'est à dire qu'on va partir d'une hypothèse qu'on supposera vraie, pour essayer d'aller au bout du raisonnement. - -Cela nous ramènera donc à des décisions logiques qui en découleront. - -### Mais si le postulat de base est erroné ? - -C'est tout le principe : s'il est erroné, alors il faut tester son exact opposé : cela prend du temps. - -Et enfin, en testant l'opposé, on pourra savoir si notre problème est décidable ou pas ! - -Revenons à notre problème d'arrêt : Il s'agit d'un problème de décision qui determine si le programme s'arrête ou non. Pratique ? C'est exactement ce que l'on cherche justement. - -Oui mais :En 1936, Alan Turing démontre son indécidabilité. - -#### Attendez, le programme qui determine l'indécidabilité est lui même indécidable ?? - -Eh oui, c'est incroyable mais juste : ironique n'est ce pas ? On peut même dire *absurde* - -En effet, on va user d'un raisonnement par l'absurde pour montrer que ce qu'on pense vrai est en réalité faux. - -En supposant que ce que l'on veut vrai, soit faux, avec une pensée logique, on peut et doit, aboutir à une contradiction qui établira que ce que l'on pense donc vrai, est faux. +En raisonnement par l'absurde, on suppose vraie la chose qu'on veut réfuter, puis on montre que cette hypothèse aboutit à une contradiction logique. #### Vous suivez toujours ? @@ -273,24 +251,66 @@ Analysons ce que l'on vient d'écrire : Nous venons donc de prouver l'impossible. Pas mal non ? -#### Quand le possible et l'impossible se mélangent...Possimpible ? +#### Conclusion -Turing prouve donc qu'il n'est pas possible d'inventer une fonction prouvant qu'une autre donnée se termine. +Turing prouve donc qu'il n'est pas possible d'écrire une fonction capable de dire, dans tous les cas, si un programme quelconque s'arrête ou non. -Si la machine ne peut nous aider, il vous faudra donc, en tant qu'humain, toujours assurer le contrôle de votre code. +Si une telle fonction existait, on pourrait l'utiliser pour résoudre `absurde(absurde)` — et on vient de montrer que c'est impossible. Le problème de l'arrêt est donc **indécidable** : aucun algorithme ne peut le résoudre. -### Question : Que peut-on en déduire ? +Si la machine ne peut pas nous aider ici, il vous faudra toujours, en tant que programmeur, vérifier vous-même que votre code se termine. -On peut retenir deux choses de notre exemple : Le fameux théorème de Kurt Gödel, qui traite de l'indécidabilité, n'est pas vérifiable puisque qu'on ne peut vérifier la décidabilité de tous les sytèmes, dès lors que la fonction qui doit nous y aider n'est elle même pas décidable ! +--- -Pour comprendre la démonstration de tout cela, il nous aura fallu analyser la démonstration en elle même, et non pas essayer de démontrer ce qu'elle prouve. Ce qui laisse perplexe quant à la véracité de certaines affirmations. +### À retenir -Enfin, on peut se demander une chose. Puisque nous avons une donnée en entrée d'une fonction, et une donnée en sortie...Une fonction ne serait-elle pas uniquement que données ? +**Gödel (1931) — Incomplétude des systèmes formels** -Finalement, quand on regarde un programme, qu'est ce que c'est ? Exemple en python : un fichier texte avec une extension. -Sous un système unix, absolument tous les fichiers ne sont que du texte ! Pire : dans notre exemple, nous utilisons un programme comme donnée d'un autre programme ! +Dans tout système logique suffisamment puissant pour décrire l'arithmétique, il existe des énoncés **vrais mais indémontrables** dans ce système. Autrement dit, les mathématiques ont des limites intrinsèques : certaines vérités échappent à toute preuve formelle. -Et si tout est donnée, alors cela expliquerait pourquoi la logique tient une si grande importance dans notre environnement. +**Turing (1936) — Indécidabilité du problème de l'arrêt** + +Il n'existe **aucun algorithme** capable de déterminer, pour tout programme et toute entrée, si ce programme s'arrête ou tourne indéfiniment. Le problème de l'arrêt est indécidable. + +**Le lien entre les deux** + +Ces deux résultats sont distincts mais convergent vers la même idée : il existe des **limites fondamentales** à ce que la logique formelle et le calcul algorithmique peuvent résoudre. Certains problèmes sont hors de portée, non pas par manque de puissance de calcul, mais par nature. + +| | Turing (programme) | Gödel (pour aller plus loin) | +|---|---|---| +| Domaine | Informatique / algorithmique | Mathématiques / logique formelle | +| Résultat | Il existe des problèmes insolubles par algorithme | Il existe des vérités indémontrables dans tout système formel | +| Exemple clé | Problème de l'arrêt | Théorème d'incomplétude (1931) | + +-------- + +## Pour aller plus loin : Kurt Gödel et l'incomplétude + +> ⚠️ Cette section est hors programme NSI. + +En 1931, le mathématicien autrichien **Kurt Gödel** énonce son **théorème d'incomplétude**, qui bouleverse les mathématiques. + +### Ce qu'il prouve + +Dans tout système logique suffisamment puissant pour décrire l'arithmétique (l'addition, la multiplication sur les entiers), il existe des énoncés qui sont **vrais mais indémontrables** dans ce système. + +Autrement dit : les mathématiques ne peuvent pas tout prouver. Certaines vérités leur échappent structurellement. + +### La notion d'axiome + +Gödel travaille sur la notion d'**axiome** : une proposition qu'on accepte comme vraie sans la démontrer, et qui sert de point de départ à un raisonnement. + +Par exemple, en géométrie euclidienne : "par deux points distincts, il passe une droite et une seule" est un axiome. On ne le prouve pas — on le pose. + +Gödel montre que quel que soit l'ensemble d'axiomes choisi, il restera toujours des énoncés que ce système ne peut ni prouver ni réfuter. + +### Le lien avec Turing + +Gödel (1931) et Turing (1936) arrivent indépendamment à des conclusions similaires par des chemins différents : + +- Gödel montre les **limites de la démonstration mathématique** +- Turing montre les **limites du calcul algorithmique** + +Les deux résultats disent, chacun à leur manière, qu'il existe des questions auxquelles ni les mathématiques ni les ordinateurs ne peuvent répondre — non par manque de puissance, mais par nature. -------- diff --git a/POO/README.md b/POO/README.md index 0f1f236..d46046a 100644 --- a/POO/README.md +++ b/POO/README.md @@ -248,6 +248,88 @@ Ces méthodes sont appelées des accesseurs et modificateurs. Elles sont optionn ----------- +## L'héritage + +Jusqu'ici, nous avons créé des classes indépendantes les unes des autres. Mais en POO, il est possible de créer une classe à partir d'une autre classe existante : c'est le principe de l'**héritage**. + +L'idée est simple : une classe **enfant** hérite de tous les attributs et méthodes d'une classe **parent**, et peut en ajouter de nouveaux ou en modifier certains. + +> L'héritage modélise une relation **"est-un"** : un `EtudiantBoursier` **est un** `Etudiant`. À ne pas confondre avec la composition vue dans le TP Pokémon, qui modélise une relation **"a-un"** : un `Dresseur` **a des** `Pokemon`. + +### Syntaxe de base + +Supposons que l'on veuille créer un `EtudiantBoursier` qui est un `Etudiant` avec une bourse mensuelle en plus. + +```python +class EtudiantBoursier(Etudiant): + def __init__(self, nom_etu, prenom_etu, spe1_etu, age_etu, bourse_mensuelle): + super().__init__(nom_etu, prenom_etu, spe1_etu, age_etu) + self.bourse = bourse_mensuelle +``` + +Plusieurs choses à noter : + +- `class EtudiantBoursier(Etudiant)` : on indique entre parenthèses la classe parent dont on hérite. +- `super().__init__(...)` : on appelle le constructeur de la classe parent pour initialiser les attributs déjà définis. Cela évite de tout réécrire. +- On ajoute ensuite les attributs propres à l'enfant (`self.bourse`). + +```python +>>> eb = EtudiantBoursier('Martin', 'Léa', 'NSI', 17, 250) +>>> eb.nom +'Martin' +>>> eb.bourse +250 +>>> eb.peut_avoir_son_permis +False +``` + +L'objet `eb` a accès à tous les attributs de `Etudiant` **et** à `bourse`. + +### Surcharge de méthode + +Un `EtudiantBoursier` peut avoir besoin d'une méthode `__repr__` différente de celle de `Etudiant`. On peut alors **surcharger** (redéfinir) la méthode dans la classe enfant : + +```python +class EtudiantBoursier(Etudiant): + def __init__(self, nom_etu, prenom_etu, spe1_etu, age_etu, bourse_mensuelle): + super().__init__(nom_etu, prenom_etu, spe1_etu, age_etu) + self.bourse = bourse_mensuelle + + def __repr__(self): + return super().__repr__() + f' (boursier : {self.bourse}€/mois)' +``` + +```python +>>> eb = EtudiantBoursier('Martin', 'Léa', 'NSI', 17, 250) +>>> eb +Martin Léa (boursier : 250€/mois) +``` + +Ici `super().__repr__()` appelle la version de la classe parent pour ne pas dupliquer le code. + +### isinstance() + +La fonction native `isinstance()` permet de vérifier si un objet est une instance d'une classe donnée — y compris via l'héritage : + +```python +>>> eb = EtudiantBoursier('Martin', 'Léa', 'NSI', 17, 250) +>>> isinstance(eb, EtudiantBoursier) +True +>>> isinstance(eb, Etudiant) +True +``` + +`eb` est à la fois un `EtudiantBoursier` ET un `Etudiant`. C'est la conséquence directe de l'héritage. + +### Exercices + +1. Créez une classe `EtudiantInternational` qui hérite de `Etudiant` et possède un attribut supplémentaire `pays_origine`. +2. Surchargez `__repr__` pour afficher le pays entre parenthèses. +3. Créez une fonction `liste_internationaux(etudiants)` qui prend une liste d'`Etudiant` et renvoie uniquement les `EtudiantInternational`. Utilisez `isinstance()`. +4. Que se passe-t-il si on appelle `anniversaire()` sur un `EtudiantBoursier` ? Pourquoi ? + +----------- + Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster Licence CC BY NC diff --git a/POO/TP/TP_Pokemon.md b/POO/TP/TP_Pokemon.md index 1978299..6e781e2 100644 --- a/POO/TP/TP_Pokemon.md +++ b/POO/TP/TP_Pokemon.md @@ -398,14 +398,107 @@ Modifiez la classe `Pokemon` pour qu'un Pokémon possède une liste de capacité --- +## Partie 5 : Héritage — Spécialiser les Pokémon + +> **Prérequis** : avoir vu le cours sur l'héritage. + +Jusqu'ici, tous les Pokémon utilisent la même méthode `attaquer`. Mais en vrai, un Pokémon Feu n'attaque pas comme un Pokémon Eau. Plutôt que de gérer ça avec un dictionnaire de faiblesses dans `attaquer`, on peut utiliser l'**héritage** pour créer des sous-classes spécialisées. + +--- + +### Exercice 8 : Sous-classes par type + +Créez trois sous-classes qui héritent de `Pokemon` : + +- `PokemonFeu` : inflige ×2 dégâts aux Pokémon Plante +- `PokemonEau` : inflige ×2 dégâts aux Pokémon Feu +- `PokemonPlante` : inflige ×2 dégâts aux Pokémon Eau + +Chaque sous-classe doit : +1. Hériter de `Pokemon` via `class PokemonFeu(Pokemon):` +2. Appeler `super().__init__(...)` dans son constructeur en fixant `type_pokemon` automatiquement +3. Surcharger la méthode `attaquer` pour appliquer le bonus de dégâts + +```python +class PokemonFeu(Pokemon): + def __init__(self, nom, niveau=1, pv_max=100, attaque=10): + super().__init__(nom, "Feu", niveau, pv_max, attaque) + + def attaquer(self, cible): + """ + Attaque avec ×2 dégâts si la cible est de type Plante. + """ + # À compléter + pass + + +class PokemonEau(Pokemon): + def __init__(self, nom, niveau=1, pv_max=100, attaque=10): + super().__init__(nom, "Eau", niveau, pv_max, attaque) + + def attaquer(self, cible): + """ + Attaque avec ×2 dégâts si la cible est de type Feu. + """ + # À compléter + pass + + +class PokemonPlante(Pokemon): + def __init__(self, nom, niveau=1, pv_max=100, attaque=10): + super().__init__(nom, "Plante", niveau, pv_max, attaque) + + def attaquer(self, cible): + """ + Attaque avec ×2 dégâts si la cible est de type Eau. + """ + # À compléter + pass +``` + +**Tests :** +```python +>>> salameche = PokemonFeu("Salamèche", niveau=15, pv_max=70, attaque=12) +>>> bulbizarre = PokemonPlante("Bulbizarre", niveau=15, pv_max=75, attaque=10) +>>> salameche.attaquer(bulbizarre) +C'est super efficace ! +Salamèche attaque Bulbizarre et inflige 24 dégâts ! +>>> bulbizarre.attaquer(salameche) +Bulbizarre attaque Salamèche et inflige 10 dégâts ! +``` + +--- + +### Exercice 9 : isinstance() en pratique + +1. Vérifiez que `salameche` est à la fois une instance de `PokemonFeu` **et** de `Pokemon`. Expliquez pourquoi. +2. Écrivez une fonction `compter_par_type(equipe)` qui prend une liste de Pokémon et renvoie un dictionnaire `{type: nombre}`. + +```python +>>> equipe = [PokemonFeu("Dracaufeu"), PokemonEau("Tortank"), PokemonFeu("Sulfura"), PokemonPlante("Florizarre")] +>>> compter_par_type(equipe) +{'Feu': 2, 'Eau': 1, 'Plante': 1} +``` + +--- + +### Exercice 10 : Refactoring + +Relisez le dictionnaire `FAIBLESSES` de l'exercice 3. Maintenant que vous avez des sous-classes, ce dictionnaire est-il encore utile ? Quelle approche est plus lisible selon vous ? Discutez. + +--- + ## Résumé des classes -| Classe | Attributs | Méthodes principales | -|--------|-----------|----------------------| -| `Pokemon` | nom, type, niveau, pv, attaque | attaquer(), subir_degats(), est_ko() | -| `Dresseur` | nom, equipe | ajouter_pokemon(), tous_ko() | -| `Combat` | dresseur1, dresseur2, tour | lancer_combat() | -| `CentrePokemon` | ville | soigner_equipe() | +| Classe | Hérite de | Attributs supplémentaires | Méthodes modifiées | +|--------|-----------|---------------------------|--------------------| +| `Pokemon` | — | nom, type, niveau, pv, attaque | attaquer(), subir_degats(), est_ko() | +| `PokemonFeu` | `Pokemon` | — | attaquer() | +| `PokemonEau` | `Pokemon` | — | attaquer() | +| `PokemonPlante` | `Pokemon` | — | attaquer() | +| `Dresseur` | — | nom, equipe | ajouter_pokemon(), tous_ko() | +| `Combat` | — | dresseur1, dresseur2, tour | lancer_combat() | +| `CentrePokemon` | — | ville | soigner_equipe() | --- diff --git a/Réseau/README.md b/Réseau/README.md index 8ad2921..4e1e214 100644 --- a/Réseau/README.md +++ b/Réseau/README.md @@ -24,7 +24,7 @@ Le modèle OSI (Open Systems Interconnection) est un modèle théorique en 7 cou ### Le modèle TCP/IP -Le modèle TCP/IP est une simplification du modèle OSI, plus proche de l'implémentation réelle. +Le modèle TCP/IP est le modèle **réellement utilisé sur Internet**. Il regroupe les 7 couches OSI en 4 couches plus pratiques. | Couche | Nom | Exemple | | ------ | ------------ | --------------- | @@ -33,6 +33,28 @@ Le modèle TCP/IP est une simplification du modèle OSI, plus proche de l'implé | 2 | Internet | IP, ICMP | | 1 | Accès réseau | Ethernet, Wi-Fi | +### Correspondance OSI ↔ TCP/IP + +| Modèle OSI | Couches OSI | Modèle TCP/IP | +|------------|-------------|---------------| +| 7 — Application | Interfaces utilisateur (HTTP, FTP…) | Application | +| 6 — Présentation | Format, chiffrement | Application | +| 5 — Session | Gestion des connexions | Application | +| 4 — Transport | TCP, UDP | Transport | +| 3 — Réseau | IP, routage | Internet | +| 2 — Liaison | Ethernet, Wi-Fi, adresses MAC | Accès réseau | +| 1 — Physique | Câbles, ondes | Accès réseau | + +### Quel modèle utiliser ? + +| Situation | Modèle recommandé | +|-----------|-------------------| +| Raisonner sur le rôle de chaque couche | OSI — plus précis, bon pour l'analyse | +| Décrire des protocoles réels (HTTP, TCP, IP…) | TCP/IP — c'est ce qu'on utilise en pratique | +| Situer un protocole dans la pile réseau | Les deux sont utiles en parallèle | + +> En NSI, vous utiliserez surtout le modèle TCP/IP. Le modèle OSI sert de référence pour comprendre ce qui se passe à chaque étape d'une communication. + -------- @@ -113,7 +135,7 @@ Les réseaux sont la base d'Internet et des systèmes informatiques modernes. Co --- -### 🔍 Exercice d'application +### Exercice d'application 1. Trouvez votre adresse IP locale avec la commande : ```sh ipconfig (Windows) ou ifconfig / ip a (Linux/Mac) diff --git a/SQL/Cours_SQL.md b/SQL/Cours_SQL.md deleted file mode 100644 index 4d8071d..0000000 --- a/SQL/Cours_SQL.md +++ /dev/null @@ -1,554 +0,0 @@ -# Cours : Le langage SQL - ---- - -## 1. Introduction - -### 1.1. Historique - -**SQL** (*Structured Query Language*) est un langage de requêtes créé en 1974 par IBM, puis normalisé en 1986. Il permet d'interagir avec les **bases de données relationnelles**. - -SQL est aujourd'hui le standard universel pour : -- Créer et modifier la structure des bases de données -- Insérer, modifier et supprimer des données -- Interroger les données (requêtes) - -### 1.2. Les SGBD - -Un **SGBD** (*Système de Gestion de Base de Données*) est un logiciel qui permet de stocker, organiser et manipuler des données. Exemples : - -| SGBD | Type | Utilisation | -|------|------|-------------| -| SQLite | Léger, fichier local | Applications mobiles, embarqué | -| MySQL / MariaDB | Serveur | Sites web, applications | -| PostgreSQL | Serveur avancé | Applications complexes | -| Oracle | Entreprise | Grandes entreprises | -| Microsoft SQL Server | Entreprise | Environnement Windows | - -En NSI, nous utilisons principalement **SQLite** avec l'outil **DB Browser for SQLite**. - ---- - -## 2. Structure d'une base de données - -### 2.1. Tables, attributs et enregistrements - -Une base de données relationnelle est composée de **tables**. Chaque table contient : -- Des **colonnes** (ou **attributs**) : les caractéristiques des données -- Des **lignes** (ou **enregistrements**) : les données elles-mêmes - -**Exemple : Table LIVRES** - -| id | titre | auteur | ann_publi | note | -|----|-------|--------|-----------|------| -| 1 | 1984 | Orwell | 1949 | 10 | -| 2 | Dune | Herbert | 1965 | 8 | -| 3 | Fondation | Asimov | 1951 | 9 | - -### 2.2. Types de données - -| Type SQL | Description | Exemple | -|----------|-------------|---------| -| `INT` ou `INTEGER` | Nombre entier | 42, -7, 2024 | -| `REAL` ou `FLOAT` | Nombre décimal | 3.14, -0.5 | -| `TEXT` ou `VARCHAR` | Chaîne de caractères | 'Bonjour', 'Alice' | -| `DATE` | Date | '2024-01-15' | -| `BOOLEAN` | Booléen | TRUE, FALSE | - -### 2.3. Clés primaires et étrangères - -- **Clé primaire** (`PRIMARY KEY`) : Identifiant unique de chaque enregistrement -- **Clé étrangère** (`FOREIGN KEY`) : Référence vers la clé primaire d'une autre table - -``` -Table AUTEURS Table LIVRES -+----+--------+ +----+--------+-----------+ -| id | nom | | id | titre | id_auteur | -+----+--------+ +----+--------+-----------+ -| 1 | Orwell |<─────────────────| 1 | 1984 | 1 | -| 2 | Asimov |<─────────────────| 2 | Robots | 2 | -+----+--------+ +----+--------+-----------+ - PK PK FK -``` - ---- - -## 3. Création et modification de tables - -### 3.1. Créer une table : CREATE TABLE - -```sql -CREATE TABLE LIVRES ( - id INTEGER PRIMARY KEY, - titre TEXT, - auteur TEXT, - ann_publi INTEGER, - note INTEGER -); -``` - -### 3.2. Créer une table avec clé étrangère - -```sql -CREATE TABLE LIVRES ( - id INTEGER PRIMARY KEY, - titre TEXT, - id_auteur INTEGER, - ann_publi INTEGER, - FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id) -); -``` - -### 3.3. Supprimer une table : DROP TABLE - -```sql -DROP TABLE LIVRES; -``` - -⚠️ **Attention** : Cette opération est irréversible ! - -### 3.4. Modifier une table : ALTER TABLE - -```sql --- Ajouter une colonne -ALTER TABLE LIVRES ADD COLUMN editeur TEXT; - --- Supprimer une colonne (selon le SGBD) -ALTER TABLE LIVRES DROP COLUMN editeur; -``` - ---- - -## 4. Manipulation des données - -### 4.1. Insérer des données : INSERT INTO - -```sql --- Insérer un enregistrement -INSERT INTO LIVRES (id, titre, auteur, ann_publi, note) -VALUES (1, '1984', 'Orwell', 1949, 10); - --- Insérer plusieurs enregistrements -INSERT INTO LIVRES (id, titre, auteur, ann_publi, note) -VALUES - (2, 'Dune', 'Herbert', 1965, 8), - (3, 'Fondation', 'Asimov', 1951, 9); -``` - -### 4.2. Modifier des données : UPDATE - -```sql --- Modifier tous les enregistrements correspondant à la condition -UPDATE LIVRES -SET note = 10 -WHERE auteur = 'Asimov'; - --- Modifier plusieurs colonnes -UPDATE LIVRES -SET note = 9, ann_publi = 1950 -WHERE id = 3; -``` - -⚠️ **Attention** : Sans clause `WHERE`, tous les enregistrements seront modifiés ! - -### 4.3. Supprimer des données : DELETE - -```sql --- Supprimer les enregistrements correspondant à la condition -DELETE FROM LIVRES -WHERE ann_publi < 1950; - --- Supprimer tous les enregistrements (vider la table) -DELETE FROM LIVRES; -``` - -⚠️ **Attention** : Sans clause `WHERE`, tous les enregistrements seront supprimés ! - ---- - -## 5. Requêtes de sélection : SELECT - -### 5.1. Syntaxe de base - -```sql -SELECT colonnes -FROM table -WHERE conditions -ORDER BY colonne [ASC|DESC]; -``` - -### 5.2. Sélectionner des colonnes - -```sql --- Toutes les colonnes -SELECT * FROM LIVRES; - --- Colonnes spécifiques -SELECT titre, auteur FROM LIVRES; - --- Avec alias -SELECT titre AS "Titre du livre", auteur AS "Écrivain" -FROM LIVRES; -``` - -### 5.3. Filtrer avec WHERE - -**Opérateurs de comparaison :** - -| Opérateur | Signification | -|-----------|---------------| -| `=` | Égal à | -| `<>` ou `!=` | Différent de | -| `<`, `<=` | Inférieur (ou égal) | -| `>`, `>=` | Supérieur (ou égal) | -| `BETWEEN a AND b` | Entre a et b (inclus) | -| `IN (v1, v2, ...)` | Dans la liste | -| `LIKE` | Correspondance de motif | -| `IS NULL` | Est nul | - -**Exemples :** - -```sql --- Égalité -SELECT * FROM LIVRES WHERE auteur = 'Asimov'; - --- Comparaison -SELECT * FROM LIVRES WHERE ann_publi > 1960; - --- Entre deux valeurs -SELECT * FROM LIVRES WHERE ann_publi BETWEEN 1950 AND 1970; - --- Dans une liste -SELECT * FROM LIVRES WHERE auteur IN ('Asimov', 'Bradbury', 'K.Dick'); - --- Correspondance de motif (LIKE) -SELECT * FROM LIVRES WHERE titre LIKE '%Robot%'; --- % = n'importe quelle suite de caractères --- _ = un seul caractère - --- Valeur nulle -SELECT * FROM LIVRES WHERE note IS NULL; -``` - -### 5.4. Combiner les conditions : AND, OR, NOT - -```sql --- ET logique -SELECT * FROM LIVRES -WHERE auteur = 'Asimov' AND ann_publi > 1950; - --- OU logique -SELECT * FROM LIVRES -WHERE auteur = 'Asimov' OR auteur = 'Bradbury'; - --- Négation -SELECT * FROM LIVRES -WHERE NOT auteur = 'Asimov'; - --- Combinaison avec parenthèses -SELECT * FROM LIVRES -WHERE (auteur = 'Asimov' OR auteur = 'Bradbury') AND note >= 8; -``` - -### 5.5. Trier les résultats : ORDER BY - -```sql --- Tri croissant (par défaut) -SELECT * FROM LIVRES ORDER BY ann_publi; -SELECT * FROM LIVRES ORDER BY ann_publi ASC; - --- Tri décroissant -SELECT * FROM LIVRES ORDER BY note DESC; - --- Tri multiple -SELECT * FROM LIVRES ORDER BY auteur ASC, ann_publi DESC; -``` - -### 5.6. Éliminer les doublons : DISTINCT - -```sql --- Liste des auteurs (sans doublons) -SELECT DISTINCT auteur FROM LIVRES; -``` - -### 5.7. Limiter les résultats : LIMIT - -```sql --- Les 5 premiers résultats -SELECT * FROM LIVRES LIMIT 5; - --- Pagination : 5 résultats à partir du 10e -SELECT * FROM LIVRES LIMIT 5 OFFSET 10; -``` - ---- - -## 6. Fonctions d'agrégation - -Les fonctions d'agrégation effectuent des calculs sur un ensemble de valeurs. - -### 6.1. Les fonctions principales - -| Fonction | Description | -|----------|-------------| -| `COUNT(*)` | Nombre d'enregistrements | -| `COUNT(colonne)` | Nombre de valeurs non nulles | -| `SUM(colonne)` | Somme des valeurs | -| `AVG(colonne)` | Moyenne des valeurs | -| `MIN(colonne)` | Valeur minimale | -| `MAX(colonne)` | Valeur maximale | - -### 6.2. Exemples - -```sql --- Nombre total de livres -SELECT COUNT(*) FROM LIVRES; - --- Nombre de livres par auteur -SELECT COUNT(*) FROM LIVRES WHERE auteur = 'Asimov'; - --- Note moyenne -SELECT AVG(note) FROM LIVRES; - --- Note minimale et maximale -SELECT MIN(note), MAX(note) FROM LIVRES; - --- Somme des notes (peu utile ici, mais illustratif) -SELECT SUM(note) FROM LIVRES; - --- Année du livre le plus ancien -SELECT MIN(ann_publi) FROM LIVRES; -``` - -### 6.3. Regrouper les données : GROUP BY - -`GROUP BY` permet de regrouper les enregistrements par valeur d'une colonne. - -```sql --- Nombre de livres par auteur -SELECT auteur, COUNT(*) AS nb_livres -FROM LIVRES -GROUP BY auteur; - --- Note moyenne par auteur -SELECT auteur, AVG(note) AS note_moyenne -FROM LIVRES -GROUP BY auteur; - --- Résultat : --- +----------+--------------+ --- | auteur | note_moyenne | --- +----------+--------------+ --- | Asimov | 8.67 | --- | Bradbury | 7.50 | --- | K.Dick | 8.33 | --- +----------+--------------+ -``` - -### 6.4. Filtrer les groupes : HAVING - -`HAVING` filtre les résultats **après** le regroupement (contrairement à `WHERE` qui filtre **avant**). - -```sql --- Auteurs ayant écrit plus de 2 livres -SELECT auteur, COUNT(*) AS nb_livres -FROM LIVRES -GROUP BY auteur -HAVING COUNT(*) > 2; - --- Auteurs avec une note moyenne >= 8 -SELECT auteur, AVG(note) AS note_moyenne -FROM LIVRES -GROUP BY auteur -HAVING AVG(note) >= 8; -``` - -**Différence WHERE / HAVING :** - -```sql --- WHERE filtre les lignes AVANT le regroupement -SELECT auteur, AVG(note) -FROM LIVRES -WHERE ann_publi > 1950 -- Filtre les livres publiés après 1950 -GROUP BY auteur; - --- HAVING filtre les groupes APRÈS le regroupement -SELECT auteur, AVG(note) -FROM LIVRES -GROUP BY auteur -HAVING AVG(note) > 8; -- Garde les auteurs avec moyenne > 8 -``` - ---- - -## 7. Jointures - -Les jointures permettent de combiner des données provenant de plusieurs tables. - -### 7.1. INNER JOIN (jointure interne) - -Retourne uniquement les enregistrements qui ont une correspondance dans les deux tables. - -```sql -SELECT LIVRES.titre, AUTEURS.nom, AUTEURS.prenom -FROM LIVRES -INNER JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id; -``` - -**Schéma :** -``` -LIVRES AUTEURS Résultat INNER JOIN -+----+------+ +----+------+ +------+------+ -| id | id_a | | id | nom | | titre| nom | -+----+------+ +----+------+ +------+------+ -| 1 | 1 | | 1 | Orwell| | 1984 | Orwell| -| 2 | 2 | | 2 | Asimov| | Fond.| Asimov| -| 3 | NULL | | 3 | Dick | +------+------+ -+----+------+ +----+------+ (le livre 3 est exclu car id_a est NULL) -``` - -### 7.2. LEFT JOIN (jointure externe gauche) - -Retourne tous les enregistrements de la table de gauche, même sans correspondance. - -```sql -SELECT LIVRES.titre, AUTEURS.nom -FROM LIVRES -LEFT JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id; -``` - -### 7.3. Alias de tables - -Pour simplifier l'écriture : - -```sql -SELECT L.titre, A.nom, A.prenom -FROM LIVRES L -INNER JOIN AUTEURS A ON L.id_auteur = A.id -WHERE A.langue_ecriture = 'français'; -``` - -### 7.4. Jointures multiples - -```sql -SELECT L.titre, A.nom, E.nom_editeur -FROM LIVRES L -INNER JOIN AUTEURS A ON L.id_auteur = A.id -INNER JOIN EDITEURS E ON L.id_editeur = E.id; -``` - ---- - -## 8. Ordre d'exécution des clauses - -L'ordre d'écriture et l'ordre d'exécution sont différents : - -**Ordre d'écriture :** -```sql -SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT ... -``` - -**Ordre d'exécution :** -1. `FROM` et `JOIN` : Sélection des tables -2. `WHERE` : Filtrage des lignes -3. `GROUP BY` : Regroupement -4. `HAVING` : Filtrage des groupes -5. `SELECT` : Sélection des colonnes -6. `DISTINCT` : Élimination des doublons -7. `ORDER BY` : Tri -8. `LIMIT` : Limitation du nombre de résultats - ---- - -## 9. Bonnes pratiques - -### 9.1. Conventions d'écriture - -- Mots-clés SQL en **MAJUSCULES** : `SELECT`, `FROM`, `WHERE` -- Noms de tables en **MAJUSCULES** : `LIVRES`, `AUTEURS` -- Noms de colonnes en **minuscules** : `titre`, `auteur` -- Indentation pour la lisibilité - -```sql -SELECT L.titre, - A.nom, - A.prenom -FROM LIVRES L -INNER JOIN AUTEURS A ON L.id_auteur = A.id -WHERE A.langue_ecriture = 'français' - AND L.ann_publi > 1950 -ORDER BY L.ann_publi DESC; -``` - -### 9.2. Sécurité : Injections SQL - -⚠️ Ne jamais construire des requêtes SQL par concaténation de chaînes avec des entrées utilisateur ! - -```python -# DANGEREUX - Injection SQL possible -requete = "SELECT * FROM USERS WHERE nom = '" + nom_utilisateur + "'" - -# SÉCURISÉ - Requête paramétrée -cursor.execute("SELECT * FROM USERS WHERE nom = ?", (nom_utilisateur,)) -``` - ---- - -## 10. Synthèse - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ REQUÊTE SQL │ -├─────────────────────────────────────────────────────────────────┤ -│ SELECT [DISTINCT] colonnes, AGG(colonne) │ -│ FROM table1 │ -│ [INNER|LEFT] JOIN table2 ON condition │ -│ WHERE conditions │ -│ GROUP BY colonne │ -│ HAVING condition_agregation │ -│ ORDER BY colonne [ASC|DESC] │ -│ LIMIT n [OFFSET m] │ -└─────────────────────────────────────────────────────────────────┘ - -┌──────────────┬────────────────────────────────────────────────┐ -│ Commande │ Action │ -├──────────────┼────────────────────────────────────────────────┤ -│ CREATE TABLE │ Créer une table │ -│ DROP TABLE │ Supprimer une table │ -│ INSERT INTO │ Insérer des données │ -│ UPDATE │ Modifier des données │ -│ DELETE │ Supprimer des données │ -│ SELECT │ Interroger des données │ -└──────────────┴────────────────────────────────────────────────┘ - -┌──────────────┬────────────────────────────────────────────────┐ -│ Agrégation │ Description │ -├──────────────┼────────────────────────────────────────────────┤ -│ COUNT(*) │ Nombre d'enregistrements │ -│ SUM(col) │ Somme │ -│ AVG(col) │ Moyenne │ -│ MIN(col) │ Minimum │ -│ MAX(col) │ Maximum │ -└──────────────┴────────────────────────────────────────────────┘ -``` - ---- - -## Pour aller plus loin - -- **SQL Murder Mystery** : Un jeu pour apprendre SQL en résolvant un meurtre - [https://mystery.knightlab.com](https://mystery.knightlab.com) - -- **SQLBolt** : Tutoriel interactif - [https://sqlbolt.com](https://sqlbolt.com) - -- **W3Schools SQL** : Référence complète - [https://www.w3schools.com/sql/](https://www.w3schools.com/sql/) - ---- - -Auteur : Florian Mathieu - -Licence CC BY NC - -Licence Creative Commons
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International. diff --git a/SQL/README.md b/SQL/README.md index 0503990..4d8071d 100644 --- a/SQL/README.md +++ b/SQL/README.md @@ -1,274 +1,549 @@ -# TP : Introduction au langage SQL avec DB Browser for SQLite +# Cours : Le langage SQL -Ce TP vous guidera à travers la création et la manipulation d'une base de données en utilisant le logiciel **DB Browser for SQLite**. Vous apprendrez à créer des tables, insérer des données et exécuter des requêtes SQL pour interroger la base de données. +--- -> **Prérequis** : Avoir lu le cours [Cours_SQL.md](Cours_SQL.md) avant de commencer ce TP. +## 1. Introduction -## Prérequis +### 1.1. Historique -- Télécharger et installer [DB Browser for SQLite](https://sqlitebrowser.org/). +**SQL** (*Structured Query Language*) est un langage de requêtes créé en 1974 par IBM, puis normalisé en 1986. Il permet d'interagir avec les **bases de données relationnelles**. -## Activité 3.1 : Création d'une base de données +SQL est aujourd'hui le standard universel pour : +- Créer et modifier la structure des bases de données +- Insérer, modifier et supprimer des données +- Interroger les données (requêtes) -1. **Lancer DB Browser for SQLite**. Vous devriez obtenir l'écran suivant : +### 1.2. Les SGBD - ![Écran d'accueil de DB Browser for SQLite](assets/1.png) +Un **SGBD** (*Système de Gestion de Base de Données*) est un logiciel qui permet de stocker, organiser et manipuler des données. Exemples : -2. **Créer une nouvelle base de données** : - - - Cliquez sur "Nouvelle base de données". - - Nommez votre base de données, par exemple `db_livres.db`. - - Vous verrez la fenêtre suivante : - - ![Fenêtre de création de la base de données](assets/2.png) - - - Cliquez sur "Annuler" pour fermer cette fenêtre. - -3. **Vérifier la création de la base de données** : - - Votre base de données est créée mais ne contient pas encore de tables. +| SGBD | Type | Utilisation | +|------|------|-------------| +| SQLite | Léger, fichier local | Applications mobiles, embarqué | +| MySQL / MariaDB | Serveur | Sites web, applications | +| PostgreSQL | Serveur avancé | Applications complexes | +| Oracle | Entreprise | Grandes entreprises | +| Microsoft SQL Server | Entreprise | Environnement Windows | - ![Base de données sans tables](assets/3.png) +En NSI, nous utilisons principalement **SQLite** avec l'outil **DB Browser for SQLite**. -## Activité 3.2 : Création d'une table +--- -1. **Accéder à l'onglet "Exécuter le SQL"** : - - - Cliquez sur l'onglet "Exécuter le SQL". - -2. **Créer la table `LIVRES`** : - - Dans la fenêtre "SQL 1", saisissez la requête suivante : +## 2. Structure d'une base de données - ```sql - CREATE TABLE LIVRES ( - id INT PRIMARY KEY, - titre TEXT, - auteur TEXT, - ann_publi INT, - note INT - ); - ``` +### 2.1. Tables, attributs et enregistrements - - Cliquez sur le bouton ▶ (ou appuyez sur F5) pour exécuter la requête. - - Un message "Requête exécutée avec succès" devrait apparaître. +Une base de données relationnelle est composée de **tables**. Chaque table contient : +- Des **colonnes** (ou **attributs**) : les caractéristiques des données +- Des **lignes** (ou **enregistrements**) : les données elles-mêmes - ![Table créée avec succès](assets/5.png) +**Exemple : Table LIVRES** -## Activité 3.3 : Insertion de données +| id | titre | auteur | ann_publi | note | +|----|-------|--------|-----------|------| +| 1 | 1984 | Orwell | 1949 | 10 | +| 2 | Dune | Herbert | 1965 | 8 | +| 3 | Fondation | Asimov | 1951 | 9 | -1. **Insérer des enregistrements dans la table `LIVRES`** : - - - Toujours dans l'onglet "Exécuter le SQL", saisissez la requête suivante : - - ```sql - INSERT INTO LIVRES (id, titre, auteur, ann_publi, note) VALUES - (1, '1984', 'Orwell', 1949, 10), - (2, 'Dune', 'Herbert', 1965, 8), - (3, 'Fondation', 'Asimov', 1951, 9), - (4, 'Le meilleur des mondes', 'Huxley', 1931, 7), - (5, 'Fahrenheit 451', 'Bradbury', 1953, 7), - (6, 'Ubik', 'K.Dick', 1969, 9), - (7, 'Chroniques martiennes', 'Bradbury', 1950, 8), - (8, 'La nuit des temps', 'Barjavel', 1968, 7), - (9, 'Blade Runner', 'K.Dick', 1968, 8), - (10, 'Les Robots', 'Asimov', 1950, 9), - (11, 'La Planète des singes', 'Boulle', 1963, 8), - (12, 'Ravage', 'Barjavel', 1943, 8), - (13, 'Le Maître du Haut Château', 'K.Dick', 1962, 8), - (14, 'Le monde des Ā', 'Van Vogt', 1945, 7), - (15, 'La Fin de l’éternité', 'Asimov', 1955, 8), - (16, 'De la Terre à la Lune', 'Verne', 1865, 10); - ``` - - - Exécutez la requête en cliquant sur le bouton ▶ ou en appuyant sur F5. - - Un message de confirmation devrait apparaître. - - ![Données insérées avec succès](assets/6.png) - -2. **Vérifier les données insérées** : - - Cliquez sur l'onglet "Parcourir les données" pour voir les enregistrements ajoutés. +### 2.2. Types de données - ![Données dans la table LIVRES](assets/7.png) +| Type SQL | Description | Exemple | +|----------|-------------|---------| +| `INT` ou `INTEGER` | Nombre entier | 42, -7, 2024 | +| `REAL` ou `FLOAT` | Nombre décimal | 3.14, -0.5 | +| `TEXT` ou `VARCHAR` | Chaîne de caractères | 'Bonjour', 'Alice' | +| `DATE` | Date | '2024-01-15' | +| `BOOLEAN` | Booléen | TRUE, FALSE | -## Activité 3.4 : Exécution de requêtes SQL +### 2.3. Clés primaires et étrangères -1. **Sélectionner tous les enregistrements** : - - Dans l'onglet "Exécuter le SQL", saisissez la requête suivante : - - ```sql - SELECT id, titre, auteur, ann_publi, note FROM LIVRES; - ``` - - - Exécutez la requête. Vous devriez obtenir tous les enregistrements de la table `LIVRES`. - - ![Résultat de la requête SELECT](assets/8.png) - -2. **Sélectionner des colonnes spécifiques** : - - Pour obtenir uniquement les titres et auteurs des livres, utilisez la requête : - - ```sql - SELECT titre, auteur FROM LIVRES; - ``` - -3. **Filtrer les enregistrements** : - - Pour obtenir les livres écrits par Asimov, utilisez : - - ```sql - SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov'; - ``` - -4. **Combiner des conditions** : - - Pour obtenir les livres d'Asimov publiés après 1953 : - - ```sql - SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov' AND ann_publi > 1953; - ``` - -5. **Trier les résultats** : - - Pour trier les livres de K.Dick du plus ancien au plus récent : - - ```sql - SELECT titre FROM LIVRES WHERE auteur = 'K.Dick' ORDER BY ann_publi; - ``` - - - -6. Écrivez et testez une requête permettant d'obtenir uniquement les titres des livres écrits par Philip K.Dick. - -7. Saisissez et testez la requête SQL suivante : - - ```sql - SELECT titre, ann_publi - FROM LIVRES - WHERE auteur='Asimov' AND ann_publi>1953 - ``` - - Vérifiez que vous obtenez bien les livres écrits par Asimov publiés après 1953. - -8. Écrivez une requête permettant d'obtenir les titres des livres publiés après 1945 qui ont une note supérieure ou égale à 9. - -9. Écrivez une requête SQL permettant d'obtenir les livres de K.Dick classés du plus ancien au plus récent. - -10. Créez une nouvelle base de données que vous nommerez par exemple db_livres_auteurs.db, puis créez une table AUTEURS à l'aide de la requête SQL suivante : - - ```sql - CREATE TABLE AUTEURS - (id INT, nom TEXT, prenom TEXT, ann_naissance INT, langue_ecriture TEXT, PRIMARY KEY (id)); - ``` - - -Créez ensuite une deuxième table (LIVRES) : +- **Clé primaire** (`PRIMARY KEY`) : Identifiant unique de chaque enregistrement +- **Clé étrangère** (`FOREIGN KEY`) : Référence vers la clé primaire d'une autre table ``` -CREATE TABLE LIVRES -(id INT, titre TEXT, id_auteur INT, ann_publi INT, note INT, PRIMARY KEY (id), FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id)); +Table AUTEURS Table LIVRES ++----+--------+ +----+--------+-----------+ +| id | nom | | id | titre | id_auteur | ++----+--------+ +----+--------+-----------+ +| 1 | Orwell |<─────────────────| 1 | 1984 | 1 | +| 2 | Asimov |<─────────────────| 2 | Robots | 2 | ++----+--------+ +----+--------+-----------+ + PK PK FK ``` -Comme vous l'avez sans doute remarqué nous avons précisé dans notre requête que l'attribut "id_auteur" jouera le rôle de clé étrangère : liaison entre "id_auteur" de la table LIVRES et "id" de la table AUTEURS (FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id)). +--- -Ajoutez des données à la table AUTEURS à l'aide de la requête SQL suivante : +## 3. Création et modification de tables + +### 3.1. Créer une table : CREATE TABLE ```sql -INSERT INTO AUTEURS -(id,nom,prenom,ann_naissance,langue_ecriture) -VALUES -(1,'Orwell','George',1903,'anglais'), -(2,'Herbert','Frank',1920,'anglais'), -(3,'Asimov','Isaac',1920,'anglais'), -(4,'Huxley','Aldous',1894,'anglais'), -(5,'Bradbury','Ray',1920,'anglais'), -(6,'K.Dick','Philip',1928,'anglais'), -(7,'Barjavel','René',1911,'français'), -(8,'Boulle','Pierre',1912,'français'), -(9,'Van Vogt','Alfred Elton',1912,'anglais'), -(10,'Verne','Jules',1828,'français'); +CREATE TABLE LIVRES ( + id INTEGER PRIMARY KEY, + titre TEXT, + auteur TEXT, + ann_publi INTEGER, + note INTEGER +); ``` -Ajoutez des données à la table LIVRES à l'aide de la requête SQL suivante : +### 3.2. Créer une table avec clé étrangère ```sql -INSERT INTO LIVRES -(id,titre,id_auteur,ann_publi,note) -VALUES -(1,'1984',1,1949,10), -(2,'Dune',2,1965,8), -(3,'Fondation',3,1951,9), -(4,'Le meilleur des mondes',4,1931,7), -(5,'Fahrenheit 451',5,1953,7), -(6,'Ubik',6,1969,9), -(7,'Chroniques martiennes',5,1950,8), -(8,'La nuit des temps',7,1968,7), -(9,'Blade Runner',6,1968,8), -(10,'Les Robots',3,1950,9), -(11,'La Planète des singes',8,1963,8), -(12,'Ravage',7,1943,8), -(13,'Le Maître du Haut Château',6,1962,8), -(14,'Le monde des Ā',9,1945,7), -(15,'La Fin de l’éternité',3,1955,8), -(16,'De la Terre à la Lune',10,1865,10); +CREATE TABLE LIVRES ( + id INTEGER PRIMARY KEY, + titre TEXT, + id_auteur INTEGER, + ann_publi INTEGER, + FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id) +); ``` -11. Saisissez et testez la requête SQL suivante : +### 3.3. Supprimer une table : DROP TABLE - ```sql - SELECT titre,nom, prenom - FROM LIVRES - INNER JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id - ``` +```sql +DROP TABLE LIVRES; +``` - Rappel : attention, si un même nom d'attribut est présent dans les 2 tables (par exemple ici l'attribut id), il est nécessaire d'ajouter le nom de la table devant afin de pouvoir les distinguer (AUTEURS.id et LIVRES.id). +⚠️ **Attention** : Cette opération est irréversible ! -12. Écrivez une requête SQL permettant d'obtenir les titres des livres publiés après 1945 ainsi que le nom de leurs auteurs. +### 3.4. Modifier une table : ALTER TABLE -13. Nous allons repartir avec une nouvelle base de données. Créez une nouvelle base de données nommée "db_livres.db". +```sql +-- Ajouter une colonne +ALTER TABLE LIVRES ADD COLUMN editeur TEXT; - Créez ensuite une table LIVRES à l'aide de la requête suivante : +-- Supprimer une colonne (selon le SGBD) +ALTER TABLE LIVRES DROP COLUMN editeur; +``` - ```sql - CREATE TABLE LIVRES - (id INT, titre TEXT, auteur TEXT, ann_publi INT, note INT, PRIMARY KEY (id)); - ``` +--- - Ajoutez des données à la table LIVRES à l'aide de la requête SQL suivante : +## 4. Manipulation des données - ```sql - INSERT INTO LIVRES - (id,titre,auteur,ann_publi,note) - VALUES - (1,'1984','Orwell',1949,10), - (2,'Dune','Herbert',1965,8), - (3,'Fondation','Asimov',1951,9), - (4,'Le meilleur des mondes','Huxley',1931,7), - (5,'Fahrenheit 451','Bradbury',1953,7), - (6,'Ubik','K.Dick',1969,9), - (7,'Chroniques martiennes','Bradbury',1950,8), - (8,'La nuit des temps','Barjavel',1968,7), - (9,'Blade Runner','K.Dick',1968,8), - (10,'Les Robots','Asimov',1950,9), - (11,'La Planète des singes','Boulle',1963,8), - (12,'Ravage','Barjavel',1943,8), - (13,'Le Maître du Haut Château','K.Dick',1962,8), - (14,'Le monde des Ā','Van Vogt',1945,7), - (15,'La Fin de l’éternité','Asimov',1955,8), - (16,'De la Terre à la Lune','Verne',1865,10); - ``` +### 4.1. Insérer des données : INSERT INTO -14. À l'aide d'une requête SQL, ajoutez à la table LIVRES le livre suivant : - - id : 17 - - titre : "2001 : L'Odyssée de l'espace" - - auteur : "Clarke" - - année de publication : 1968 - - note : 7 +```sql +-- Insérer un enregistrement +INSERT INTO LIVRES (id, titre, auteur, ann_publi, note) +VALUES (1, '1984', 'Orwell', 1949, 10); +-- Insérer plusieurs enregistrements +INSERT INTO LIVRES (id, titre, auteur, ann_publi, note) +VALUES + (2, 'Dune', 'Herbert', 1965, 8), + (3, 'Fondation', 'Asimov', 1951, 9); +``` +### 4.2. Modifier des données : UPDATE -15. Écrivez une requête permettant d'attribuer la note de 10 à tous les livres écrits par Asimov publiés après 1950. Testez cette requête. -16. Écrivez une requête permettant de supprimer les livres publiés avant 1945. Testez cette requête. +```sql +-- Modifier tous les enregistrements correspondant à la condition +UPDATE LIVRES +SET note = 10 +WHERE auteur = 'Asimov'; --------- +-- Modifier plusieurs colonnes +UPDATE LIVRES +SET note = 9, ann_publi = 1950 +WHERE id = 3; +``` -Source : +⚠️ **Attention** : Sans clause `WHERE`, tous les enregistrements seront modifiés ! -- [Pixees, site de David Roche](https://informatique-lycee.forge.apps.education.fr/terminale_nsi/cours-terminale/c3a/) +### 4.3. Supprimer des données : DELETE + +```sql +-- Supprimer les enregistrements correspondant à la condition +DELETE FROM LIVRES +WHERE ann_publi < 1950; + +-- Supprimer tous les enregistrements (vider la table) +DELETE FROM LIVRES; +``` + +⚠️ **Attention** : Sans clause `WHERE`, tous les enregistrements seront supprimés ! + +--- + +## 5. Requêtes de sélection : SELECT + +### 5.1. Syntaxe de base + +```sql +SELECT colonnes +FROM table +WHERE conditions +ORDER BY colonne [ASC|DESC]; +``` + +### 5.2. Sélectionner des colonnes + +```sql +-- Toutes les colonnes +SELECT * FROM LIVRES; + +-- Colonnes spécifiques +SELECT titre, auteur FROM LIVRES; + +-- Avec alias +SELECT titre AS "Titre du livre", auteur AS "Écrivain" +FROM LIVRES; +``` + +### 5.3. Filtrer avec WHERE + +**Opérateurs de comparaison :** + +| Opérateur | Signification | +|-----------|---------------| +| `=` | Égal à | +| `<>` ou `!=` | Différent de | +| `<`, `<=` | Inférieur (ou égal) | +| `>`, `>=` | Supérieur (ou égal) | +| `BETWEEN a AND b` | Entre a et b (inclus) | +| `IN (v1, v2, ...)` | Dans la liste | +| `LIKE` | Correspondance de motif | +| `IS NULL` | Est nul | + +**Exemples :** + +```sql +-- Égalité +SELECT * FROM LIVRES WHERE auteur = 'Asimov'; + +-- Comparaison +SELECT * FROM LIVRES WHERE ann_publi > 1960; + +-- Entre deux valeurs +SELECT * FROM LIVRES WHERE ann_publi BETWEEN 1950 AND 1970; + +-- Dans une liste +SELECT * FROM LIVRES WHERE auteur IN ('Asimov', 'Bradbury', 'K.Dick'); + +-- Correspondance de motif (LIKE) +SELECT * FROM LIVRES WHERE titre LIKE '%Robot%'; +-- % = n'importe quelle suite de caractères +-- _ = un seul caractère + +-- Valeur nulle +SELECT * FROM LIVRES WHERE note IS NULL; +``` + +### 5.4. Combiner les conditions : AND, OR, NOT + +```sql +-- ET logique +SELECT * FROM LIVRES +WHERE auteur = 'Asimov' AND ann_publi > 1950; + +-- OU logique +SELECT * FROM LIVRES +WHERE auteur = 'Asimov' OR auteur = 'Bradbury'; + +-- Négation +SELECT * FROM LIVRES +WHERE NOT auteur = 'Asimov'; + +-- Combinaison avec parenthèses +SELECT * FROM LIVRES +WHERE (auteur = 'Asimov' OR auteur = 'Bradbury') AND note >= 8; +``` + +### 5.5. Trier les résultats : ORDER BY + +```sql +-- Tri croissant (par défaut) +SELECT * FROM LIVRES ORDER BY ann_publi; +SELECT * FROM LIVRES ORDER BY ann_publi ASC; + +-- Tri décroissant +SELECT * FROM LIVRES ORDER BY note DESC; + +-- Tri multiple +SELECT * FROM LIVRES ORDER BY auteur ASC, ann_publi DESC; +``` + +### 5.6. Éliminer les doublons : DISTINCT + +```sql +-- Liste des auteurs (sans doublons) +SELECT DISTINCT auteur FROM LIVRES; +``` + +### 5.7. Limiter les résultats : LIMIT + +```sql +-- Les 5 premiers résultats +SELECT * FROM LIVRES LIMIT 5; + +-- Pagination : 5 résultats à partir du 10e +SELECT * FROM LIVRES LIMIT 5 OFFSET 10; +``` + +--- + +## 6. Fonctions d'agrégation + +Les fonctions d'agrégation effectuent des calculs sur un ensemble de valeurs. + +### 6.1. Les fonctions principales + +| Fonction | Description | +|----------|-------------| +| `COUNT(*)` | Nombre d'enregistrements | +| `COUNT(colonne)` | Nombre de valeurs non nulles | +| `SUM(colonne)` | Somme des valeurs | +| `AVG(colonne)` | Moyenne des valeurs | +| `MIN(colonne)` | Valeur minimale | +| `MAX(colonne)` | Valeur maximale | + +### 6.2. Exemples + +```sql +-- Nombre total de livres +SELECT COUNT(*) FROM LIVRES; + +-- Nombre de livres par auteur +SELECT COUNT(*) FROM LIVRES WHERE auteur = 'Asimov'; + +-- Note moyenne +SELECT AVG(note) FROM LIVRES; + +-- Note minimale et maximale +SELECT MIN(note), MAX(note) FROM LIVRES; + +-- Somme des notes (peu utile ici, mais illustratif) +SELECT SUM(note) FROM LIVRES; + +-- Année du livre le plus ancien +SELECT MIN(ann_publi) FROM LIVRES; +``` + +### 6.3. Regrouper les données : GROUP BY + +`GROUP BY` permet de regrouper les enregistrements par valeur d'une colonne. + +```sql +-- Nombre de livres par auteur +SELECT auteur, COUNT(*) AS nb_livres +FROM LIVRES +GROUP BY auteur; + +-- Note moyenne par auteur +SELECT auteur, AVG(note) AS note_moyenne +FROM LIVRES +GROUP BY auteur; + +-- Résultat : +-- +----------+--------------+ +-- | auteur | note_moyenne | +-- +----------+--------------+ +-- | Asimov | 8.67 | +-- | Bradbury | 7.50 | +-- | K.Dick | 8.33 | +-- +----------+--------------+ +``` + +### 6.4. Filtrer les groupes : HAVING + +`HAVING` filtre les résultats **après** le regroupement (contrairement à `WHERE` qui filtre **avant**). + +```sql +-- Auteurs ayant écrit plus de 2 livres +SELECT auteur, COUNT(*) AS nb_livres +FROM LIVRES +GROUP BY auteur +HAVING COUNT(*) > 2; + +-- Auteurs avec une note moyenne >= 8 +SELECT auteur, AVG(note) AS note_moyenne +FROM LIVRES +GROUP BY auteur +HAVING AVG(note) >= 8; +``` + +**Différence WHERE / HAVING :** + +```sql +-- WHERE filtre les lignes AVANT le regroupement +SELECT auteur, AVG(note) +FROM LIVRES +WHERE ann_publi > 1950 -- Filtre les livres publiés après 1950 +GROUP BY auteur; + +-- HAVING filtre les groupes APRÈS le regroupement +SELECT auteur, AVG(note) +FROM LIVRES +GROUP BY auteur +HAVING AVG(note) > 8; -- Garde les auteurs avec moyenne > 8 +``` + +--- + +## 7. Jointures + +Les jointures permettent de combiner des données provenant de plusieurs tables. + +### 7.1. INNER JOIN (jointure interne) + +Retourne uniquement les enregistrements qui ont une correspondance dans les deux tables. + +```sql +SELECT LIVRES.titre, AUTEURS.nom, AUTEURS.prenom +FROM LIVRES +INNER JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id; +``` + +**Schéma :** +``` +LIVRES AUTEURS Résultat INNER JOIN ++----+------+ +----+------+ +------+------+ +| id | id_a | | id | nom | | titre| nom | ++----+------+ +----+------+ +------+------+ +| 1 | 1 | | 1 | Orwell| | 1984 | Orwell| +| 2 | 2 | | 2 | Asimov| | Fond.| Asimov| +| 3 | NULL | | 3 | Dick | +------+------+ ++----+------+ +----+------+ (le livre 3 est exclu car id_a est NULL) +``` + +### 7.2. LEFT JOIN (jointure externe gauche) + +Retourne tous les enregistrements de la table de gauche, même sans correspondance. + +```sql +SELECT LIVRES.titre, AUTEURS.nom +FROM LIVRES +LEFT JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id; +``` + +### 7.3. Alias de tables + +Pour simplifier l'écriture : + +```sql +SELECT L.titre, A.nom, A.prenom +FROM LIVRES L +INNER JOIN AUTEURS A ON L.id_auteur = A.id +WHERE A.langue_ecriture = 'français'; +``` + +### 7.4. Jointures multiples + +```sql +SELECT L.titre, A.nom, E.nom_editeur +FROM LIVRES L +INNER JOIN AUTEURS A ON L.id_auteur = A.id +INNER JOIN EDITEURS E ON L.id_editeur = E.id; +``` + +--- + +## 8. Ordre d'exécution des clauses + +L'ordre d'écriture et l'ordre d'exécution sont différents : + +**Ordre d'écriture :** +```sql +SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT ... +``` + +**Ordre d'exécution :** +1. `FROM` et `JOIN` : Sélection des tables +2. `WHERE` : Filtrage des lignes +3. `GROUP BY` : Regroupement +4. `HAVING` : Filtrage des groupes +5. `SELECT` : Sélection des colonnes +6. `DISTINCT` : Élimination des doublons +7. `ORDER BY` : Tri +8. `LIMIT` : Limitation du nombre de résultats + +--- + +## 9. Bonnes pratiques + +### 9.1. Conventions d'écriture + +- Mots-clés SQL en **MAJUSCULES** : `SELECT`, `FROM`, `WHERE` +- Noms de tables en **MAJUSCULES** : `LIVRES`, `AUTEURS` +- Noms de colonnes en **minuscules** : `titre`, `auteur` +- Indentation pour la lisibilité + +```sql +SELECT L.titre, + A.nom, + A.prenom +FROM LIVRES L +INNER JOIN AUTEURS A ON L.id_auteur = A.id +WHERE A.langue_ecriture = 'français' + AND L.ann_publi > 1950 +ORDER BY L.ann_publi DESC; +``` + +### 9.2. Sécurité : Injections SQL + +⚠️ Ne jamais construire des requêtes SQL par concaténation de chaînes avec des entrées utilisateur ! + +```python +# DANGEREUX - Injection SQL possible +requete = "SELECT * FROM USERS WHERE nom = '" + nom_utilisateur + "'" + +# SÉCURISÉ - Requête paramétrée +cursor.execute("SELECT * FROM USERS WHERE nom = ?", (nom_utilisateur,)) +``` + +--- + +## 10. Synthèse + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ REQUÊTE SQL │ +├─────────────────────────────────────────────────────────────────┤ +│ SELECT [DISTINCT] colonnes, AGG(colonne) │ +│ FROM table1 │ +│ [INNER|LEFT] JOIN table2 ON condition │ +│ WHERE conditions │ +│ GROUP BY colonne │ +│ HAVING condition_agregation │ +│ ORDER BY colonne [ASC|DESC] │ +│ LIMIT n [OFFSET m] │ +└─────────────────────────────────────────────────────────────────┘ + +┌──────────────┬────────────────────────────────────────────────┐ +│ Commande │ Action │ +├──────────────┼────────────────────────────────────────────────┤ +│ CREATE TABLE │ Créer une table │ +│ DROP TABLE │ Supprimer une table │ +│ INSERT INTO │ Insérer des données │ +│ UPDATE │ Modifier des données │ +│ DELETE │ Supprimer des données │ +│ SELECT │ Interroger des données │ +└──────────────┴────────────────────────────────────────────────┘ + +┌──────────────┬────────────────────────────────────────────────┐ +│ Agrégation │ Description │ +├──────────────┼────────────────────────────────────────────────┤ +│ COUNT(*) │ Nombre d'enregistrements │ +│ SUM(col) │ Somme │ +│ AVG(col) │ Moyenne │ +│ MIN(col) │ Minimum │ +│ MAX(col) │ Maximum │ +└──────────────┴────────────────────────────────────────────────┘ +``` + +--- + +## Pour aller plus loin + +- **SQL Murder Mystery** : Un jeu pour apprendre SQL en résolvant un meurtre + [https://mystery.knightlab.com](https://mystery.knightlab.com) + +- **SQLBolt** : Tutoriel interactif + [https://sqlbolt.com](https://sqlbolt.com) + +- **W3Schools SQL** : Référence complète + [https://www.w3schools.com/sql/](https://www.w3schools.com/sql/) --- @@ -277,4 +552,3 @@ Auteur : Florian Mathieu Licence CC BY NC Licence Creative Commons
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International. - diff --git a/SQL/TP_SQLite.md b/SQL/TP_SQLite.md new file mode 100644 index 0000000..2d27897 --- /dev/null +++ b/SQL/TP_SQLite.md @@ -0,0 +1,372 @@ +# TP : Introduction au langage SQL avec DB Browser for SQLite + +Ce TP vous guidera à travers la création et la manipulation d'une base de données en utilisant le logiciel **DB Browser for SQLite**. Vous apprendrez à créer des tables, insérer des données et exécuter des requêtes SQL pour interroger la base de données. + +> **Prérequis** : Avoir lu le cours [README.md](README.md) avant de commencer ce TP. + +## Prérequis + +- Télécharger et installer [DB Browser for SQLite](https://sqlitebrowser.org/). + +## Activité 3.1 : Création d'une base de données + +1. **Lancer DB Browser for SQLite**. Vous devriez obtenir l'écran suivant : + + ![Écran d'accueil de DB Browser for SQLite](assets/1.png) + +2. **Créer une nouvelle base de données** : + + - Cliquez sur "Nouvelle base de données". + - Nommez votre base de données, par exemple `db_livres.db`. + - Vous verrez la fenêtre suivante : + + ![Fenêtre de création de la base de données](assets/2.png) + + - Cliquez sur "Annuler" pour fermer cette fenêtre. + +3. **Vérifier la création de la base de données** : + - Votre base de données est créée mais ne contient pas encore de tables. + + ![Base de données sans tables](assets/3.png) + +## Activité 3.2 : Création d'une table + +1. **Accéder à l'onglet "Exécuter le SQL"** : + + - Cliquez sur l'onglet "Exécuter le SQL". + +2. **Créer la table `LIVRES`** : + - Dans la fenêtre "SQL 1", saisissez la requête suivante : + + ```sql + CREATE TABLE LIVRES ( + id INT PRIMARY KEY, + titre TEXT, + auteur TEXT, + ann_publi INT, + note INT + ); + ``` + + - Cliquez sur le bouton ▶ (ou appuyez sur F5) pour exécuter la requête. + - Un message "Requête exécutée avec succès" devrait apparaître. + + ![Table créée avec succès](assets/5.png) + +## Activité 3.3 : Insertion de données + +1. **Insérer des enregistrements dans la table `LIVRES`** : + + - Toujours dans l'onglet "Exécuter le SQL", saisissez la requête suivante : + + ```sql + INSERT INTO LIVRES (id, titre, auteur, ann_publi, note) VALUES + (1, '1984', 'Orwell', 1949, 10), + (2, 'Dune', 'Herbert', 1965, 8), + (3, 'Fondation', 'Asimov', 1951, 9), + (4, 'Le meilleur des mondes', 'Huxley', 1931, 7), + (5, 'Fahrenheit 451', 'Bradbury', 1953, 7), + (6, 'Ubik', 'K.Dick', 1969, 9), + (7, 'Chroniques martiennes', 'Bradbury', 1950, 8), + (8, 'La nuit des temps', 'Barjavel', 1968, 7), + (9, 'Blade Runner', 'K.Dick', 1968, 8), + (10, 'Les Robots', 'Asimov', 1950, 9), + (11, 'La Planète des singes', 'Boulle', 1963, 8), + (12, 'Ravage', 'Barjavel', 1943, 8), + (13, 'Le Maître du Haut Château', 'K.Dick', 1962, 8), + (14, 'Le monde des Ā', 'Van Vogt', 1945, 7), + (15, 'La Fin de l’éternité', 'Asimov', 1955, 8), + (16, 'De la Terre à la Lune', 'Verne', 1865, 10); + ``` + + - Exécutez la requête en cliquant sur le bouton ▶ ou en appuyant sur F5. + - Un message de confirmation devrait apparaître. + + ![Données insérées avec succès](assets/6.png) + +2. **Vérifier les données insérées** : + - Cliquez sur l'onglet "Parcourir les données" pour voir les enregistrements ajoutés. + + ![Données dans la table LIVRES](assets/7.png) + +## Activité 3.4 : Exécution de requêtes SQL + +1. **Sélectionner tous les enregistrements** : + - Dans l'onglet "Exécuter le SQL", saisissez la requête suivante : + + ```sql + SELECT id, titre, auteur, ann_publi, note FROM LIVRES; + ``` + + - Exécutez la requête. Vous devriez obtenir tous les enregistrements de la table `LIVRES`. + + ![Résultat de la requête SELECT](assets/8.png) + +2. **Sélectionner des colonnes spécifiques** : + - Pour obtenir uniquement les titres et auteurs des livres, utilisez la requête : + + ```sql + SELECT titre, auteur FROM LIVRES; + ``` + +3. **Filtrer les enregistrements** : + - Pour obtenir les livres écrits par Asimov, utilisez : + + ```sql + SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov'; + ``` + +4. **Combiner des conditions** : + - Pour obtenir les livres d'Asimov publiés après 1953 : + + ```sql + SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov' AND ann_publi > 1953; + ``` + +5. **Trier les résultats** : + - Pour trier les livres de K.Dick du plus ancien au plus récent : + + ```sql + SELECT titre FROM LIVRES WHERE auteur = 'K.Dick' ORDER BY ann_publi; + ``` + + + +6. Écrivez et testez une requête permettant d'obtenir uniquement les titres des livres écrits par Philip K.Dick. + +7. Saisissez et testez la requête SQL suivante : + + ```sql + SELECT titre, ann_publi + FROM LIVRES + WHERE auteur='Asimov' AND ann_publi>1953 + ``` + + Vérifiez que vous obtenez bien les livres écrits par Asimov publiés après 1953. + +8. Écrivez une requête permettant d'obtenir les titres des livres publiés après 1945 qui ont une note supérieure ou égale à 9. + +9. Écrivez une requête SQL permettant d'obtenir les livres de K.Dick classés du plus ancien au plus récent. + +10. Créez une nouvelle base de données que vous nommerez par exemple db_livres_auteurs.db, puis créez une table AUTEURS à l'aide de la requête SQL suivante : + + ```sql + CREATE TABLE AUTEURS + (id INT, nom TEXT, prenom TEXT, ann_naissance INT, langue_ecriture TEXT, PRIMARY KEY (id)); + ``` + + +Créez ensuite une deuxième table (LIVRES) : + +``` +CREATE TABLE LIVRES +(id INT, titre TEXT, id_auteur INT, ann_publi INT, note INT, PRIMARY KEY (id), FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id)); +``` + +Comme vous l'avez sans doute remarqué nous avons précisé dans notre requête que l'attribut "id_auteur" jouera le rôle de clé étrangère : liaison entre "id_auteur" de la table LIVRES et "id" de la table AUTEURS (FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id)). + +Ajoutez des données à la table AUTEURS à l'aide de la requête SQL suivante : + +```sql +INSERT INTO AUTEURS +(id,nom,prenom,ann_naissance,langue_ecriture) +VALUES +(1,'Orwell','George',1903,'anglais'), +(2,'Herbert','Frank',1920,'anglais'), +(3,'Asimov','Isaac',1920,'anglais'), +(4,'Huxley','Aldous',1894,'anglais'), +(5,'Bradbury','Ray',1920,'anglais'), +(6,'K.Dick','Philip',1928,'anglais'), +(7,'Barjavel','René',1911,'français'), +(8,'Boulle','Pierre',1912,'français'), +(9,'Van Vogt','Alfred Elton',1912,'anglais'), +(10,'Verne','Jules',1828,'français'); +``` + +Ajoutez des données à la table LIVRES à l'aide de la requête SQL suivante : + +```sql +INSERT INTO LIVRES +(id,titre,id_auteur,ann_publi,note) +VALUES +(1,'1984',1,1949,10), +(2,'Dune',2,1965,8), +(3,'Fondation',3,1951,9), +(4,'Le meilleur des mondes',4,1931,7), +(5,'Fahrenheit 451',5,1953,7), +(6,'Ubik',6,1969,9), +(7,'Chroniques martiennes',5,1950,8), +(8,'La nuit des temps',7,1968,7), +(9,'Blade Runner',6,1968,8), +(10,'Les Robots',3,1950,9), +(11,'La Planète des singes',8,1963,8), +(12,'Ravage',7,1943,8), +(13,'Le Maître du Haut Château',6,1962,8), +(14,'Le monde des Ā',9,1945,7), +(15,'La Fin de l’éternité',3,1955,8), +(16,'De la Terre à la Lune',10,1865,10); +``` + +11. Saisissez et testez la requête SQL suivante : + + ```sql + SELECT titre,nom, prenom + FROM LIVRES + INNER JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id + ``` + + Rappel : attention, si un même nom d'attribut est présent dans les 2 tables (par exemple ici l'attribut id), il est nécessaire d'ajouter le nom de la table devant afin de pouvoir les distinguer (AUTEURS.id et LIVRES.id). + +12. Écrivez une requête SQL permettant d'obtenir les titres des livres publiés après 1945 ainsi que le nom de leurs auteurs. + +13. Nous allons repartir avec une nouvelle base de données. Créez une nouvelle base de données nommée "db_livres.db". + + Créez ensuite une table LIVRES à l'aide de la requête suivante : + + ```sql + CREATE TABLE LIVRES + (id INT, titre TEXT, auteur TEXT, ann_publi INT, note INT, PRIMARY KEY (id)); + ``` + + Ajoutez des données à la table LIVRES à l'aide de la requête SQL suivante : + + ```sql + INSERT INTO LIVRES + (id,titre,auteur,ann_publi,note) + VALUES + (1,'1984','Orwell',1949,10), + (2,'Dune','Herbert',1965,8), + (3,'Fondation','Asimov',1951,9), + (4,'Le meilleur des mondes','Huxley',1931,7), + (5,'Fahrenheit 451','Bradbury',1953,7), + (6,'Ubik','K.Dick',1969,9), + (7,'Chroniques martiennes','Bradbury',1950,8), + (8,'La nuit des temps','Barjavel',1968,7), + (9,'Blade Runner','K.Dick',1968,8), + (10,'Les Robots','Asimov',1950,9), + (11,'La Planète des singes','Boulle',1963,8), + (12,'Ravage','Barjavel',1943,8), + (13,'Le Maître du Haut Château','K.Dick',1962,8), + (14,'Le monde des Ā','Van Vogt',1945,7), + (15,'La Fin de l’éternité','Asimov',1955,8), + (16,'De la Terre à la Lune','Verne',1865,10); + ``` + +14. À l'aide d'une requête SQL, ajoutez à la table LIVRES le livre suivant : + - id : 17 + - titre : "2001 : L'Odyssée de l'espace" + - auteur : "Clarke" + - année de publication : 1968 + - note : 7 + + + +15. Écrivez une requête permettant d'attribuer la note de 10 à tous les livres écrits par Asimov publiés après 1950. Testez cette requête. +16. Écrivez une requête permettant de supprimer les livres publiés avant 1945. Testez cette requête. + +## Activité 3.5 : Fonctions d'agrégation + +> **Prérequis** : utiliser la base `db_livres.db` créée à l'activité 3.4 (avec la table LIVRES simple, avant les suppressions de la question 16 — si vous avez supprimé des lignes, réinsérez les données avec le `INSERT INTO` de l'activité 3.4). + +Les fonctions d'agrégation effectuent un calcul sur un ensemble de lignes et renvoient **une seule valeur**. + +### 1. Compter des enregistrements : COUNT + +Exécutez les requêtes suivantes et notez les résultats : + +```sql +-- Nombre total de livres +SELECT COUNT(*) FROM LIVRES; + +-- Nombre de livres écrits par Asimov +SELECT COUNT(*) FROM LIVRES WHERE auteur = 'Asimov'; +``` + +> `COUNT(*)` compte toutes les lignes. La clause `WHERE` s'applique **avant** le comptage. + +### 2. Calculer une moyenne, un min, un max : AVG, MIN, MAX + +```sql +-- Note moyenne de tous les livres +SELECT AVG(note) FROM LIVRES; + +-- Note la plus basse et la plus haute +SELECT MIN(note), MAX(note) FROM LIVRES; + +-- Livre le plus ancien +SELECT MIN(ann_publi) FROM LIVRES; +``` + +> Les alias permettent de nommer le résultat : +> ```sql +> SELECT AVG(note) AS note_moyenne FROM LIVRES; +> ``` + +17. Écrivez une requête donnant la note moyenne des livres de Bradbury. + +18. Écrivez une requête donnant l'année de publication du livre le plus récent dans la base. + +### 3. Regrouper les résultats : GROUP BY + +`GROUP BY` divise les lignes en groupes selon les valeurs d'une colonne, et applique la fonction d'agrégation à chaque groupe séparément. + +```sql +-- Nombre de livres par auteur +SELECT auteur, COUNT(*) AS nb_livres +FROM LIVRES +GROUP BY auteur; +``` + +Exécutez cette requête. Vous devriez obtenir une ligne par auteur avec son nombre de livres. + +```sql +-- Note moyenne par auteur +SELECT auteur, AVG(note) AS note_moyenne +FROM LIVRES +GROUP BY auteur +ORDER BY note_moyenne DESC; +``` + +19. Écrivez une requête donnant, pour chaque auteur, l'année de son livre le plus ancien. + +### 4. Filtrer les groupes : HAVING + +`WHERE` filtre les lignes **avant** le regroupement. Pour filtrer les groupes **après**, on utilise `HAVING`. + +```sql +-- Auteurs ayant écrit au moins 2 livres dans la base +SELECT auteur, COUNT(*) AS nb_livres +FROM LIVRES +GROUP BY auteur +HAVING COUNT(*) >= 2; +``` + +> **À retenir :** `WHERE` porte sur les lignes individuelles, `HAVING` porte sur les groupes. + +```sql +-- Auteurs dont la note moyenne dépasse 8 +SELECT auteur, AVG(note) AS note_moyenne +FROM LIVRES +GROUP BY auteur +HAVING AVG(note) > 8; +``` + +20. Écrivez une requête listant les auteurs ayant publié des livres dans **deux décennies différentes** au minimum. + *(Indice : `MIN(ann_publi)` et `MAX(ann_publi)` dans le même GROUP BY, puis filtrer avec HAVING sur la différence)* + +21. Écrivez une requête donnant, parmi les auteurs ayant au moins 2 livres, celui dont la note moyenne est la plus élevée. Triez de façon appropriée et limitez à 1 résultat. + +-------- + +Source : + +- [Pixees, site de David Roche](https://informatique-lycee.forge.apps.education.fr/terminale_nsi/cours-terminale/c3a/) + +--- + +Auteur : Florian Mathieu + +Licence CC BY NC + +Licence Creative Commons
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International. + diff --git a/Soc/Cours_circuits_integres.md b/Soc/README.md similarity index 73% rename from Soc/Cours_circuits_integres.md rename to Soc/README.md index 259ebe2..cc20a7a 100644 --- a/Soc/Cours_circuits_integres.md +++ b/Soc/README.md @@ -1,5 +1,25 @@ # Circuits intégrés et Systèmes sur Puce (SoC) +bo + +> Comment fait-on tenir la puissance d'un ordinateur de 30 tonnes dans une puce de quelques millimètres carrés ? Ce chapitre explore l'évolution des circuits intégrés, des architectures de processeurs et des systèmes embarqués — jusqu'aux puces d'intelligence artificielle de 2026. + +## Programme + +Ce chapitre couvre les notions suivantes du programme de Terminale NSI : + +- Composants intégrés d'un système sur puce +- Transmission des données dans un réseau +- Systèmes embarqués + +## Ressources + +| Fichier | Description | +|---------|-------------| +| [Exercices](EXERCICES.md) | 10 exercices (QCM, calculs, analyse de specs réelles) | +| [TP — Station météo IoT](TP_Station_Meteo_IoT.md) | Programmer un SoC embarqué pour collecter et transmettre des données | +| [Corrigé](CORRIGE.md) | Corrigés des exercices | + --- ## 1. Rappels de Première @@ -208,6 +228,62 @@ Le recyclage des composants électroniques reste un défi : --- +## 6. Nouvelles puces : l'ère de l'IA embarquée (2025-2026) + +L'architecture des SoC connaît en 2025-2026 une rupture majeure : les puces ne sont plus seulement conçues pour le calcul généraliste ou le graphisme, mais pour **exécuter des modèles d'intelligence artificielle localement**, sans passer par le cloud. + +### 6.1. Nvidia RTX Spark (2026) + +Annoncé au Computex 2026, le **Nvidia RTX Spark** est un superchip qui illustre parfaitement l'évolution vers les SoC unifiés hautes performances. + +**Architecture :** + +| Composant | Détail | +|-----------|--------| +| CPU | 20 cœurs ARM Grace (Neoverse V2), co-développé avec MediaTek | +| GPU | Blackwell — 6 144 CUDA cores, Tensor Cores Gen 5 | +| Mémoire | Jusqu'à 128 Go de LPDDR5X **unifiée** (partagée CPU/GPU) | +| Bande passante | ~300 Go/s | +| Interconnexion | NVLink-C2C (technologie issue des serveurs Nvidia) | +| Performances IA | 1 petaflop en FP4, modèles jusqu'à 120 milliards de paramètres | + +> **Lien avec le cours :** Le RTX Spark est un SoC au sens strict — CPU, GPU et mémoire sur la même puce, reliés par un bus interne ultra-rapide (NVLink-C2C). La mémoire unifiée signifie que CPU et GPU accèdent aux mêmes données sans copie, ce qui élimine un goulot d'étranglement classique. + +**Ce qui est nouveau :** + +- **ARM + GPU Nvidia** : la convergence ARM/GPU, déjà amorcée par Apple (M-series), s'étend au monde PC et gaming. +- **IA locale** : exécuter un modèle de 120 milliards de paramètres sur un laptop (l'équivalent de GPT-3) sans connexion internet était impensable en 2023. +- **Usage prévu** : agents IA personnels, création de contenu (Adobe), gaming 1440p avec ray tracing et DLSS. + +*Disponibilité : laptops et mini-PC prévus pour l'automne 2026.* + +### 6.2. Contexte : la course aux puces IA + +Le RTX Spark s'inscrit dans une tendance plus large : + +| Fabricant | Puce | Spécialité | +|-----------|------|------------| +| **Nvidia** | RTX Spark (2026) | IA + gaming, ARM + Blackwell, usage personnel | +| **Apple** | M4 Pro/Max (2024) | SoC universel, efficacité énergétique, écosystème Apple | +| **Qualcomm** | Snapdragon X Elite (2024) | PC Windows ARM, NPU 45 TOPS | +| **AMD** | Strix Halo (2025) | x86 + GPU RDNA4, gaming portable | + +**Tendances communes à toutes ces puces :** +- Mémoire unifiée (CPU et GPU partagent la même RAM) +- NPU (Neural Processing Unit) dédié à l'IA +- Efficacité énergétique comme priorité +- Réduction de la dépendance au cloud pour l'IA + +### 6.3. Exercice d'actualité + +Le RTX Spark intègre 20 cœurs ARM alors que les PC traditionnels utilisent du x86 (Intel/AMD). + +1. En vous appuyant sur la section 3 (ARM vs x86), expliquer pourquoi Nvidia a choisi ARM plutôt que x86 pour ce superchip. +2. La mémoire du RTX Spark est dite "unifiée". En quoi cela diffère-t-il de l'architecture Von Neumann vue en Première, où CPU et GPU ont chacun leur propre mémoire ? +3. "1 petaflop = 10¹⁵ opérations par seconde." Un modèle d'IA de 120 milliards de paramètres nécessite environ 240 milliards d'opérations pour générer un seul token. Combien de tokens par seconde le RTX Spark peut-il théoriquement produire ? + +--- + ## Synthèse ``` diff --git a/Sécurité/README.md b/Sécurité/README.md index 1aea0ea..a9be5d2 100644 --- a/Sécurité/README.md +++ b/Sécurité/README.md @@ -145,6 +145,99 @@ Ces protocoles agissent au niveau de la couche 5 du modèle OSI -------- +### 6. Le hachage + +Le chiffrement protège la **confidentialité** des données — seul le destinataire peut lire le message. Mais il ne garantit pas l'**intégrité** : comment savoir si le fichier que vous téléchargez n'a pas été altéré en route ? Comment un site web peut-il vérifier votre mot de passe sans le stocker en clair ? + +C'est le rôle du **hachage**. + +#### Définition + +Une **fonction de hachage** prend une donnée de taille quelconque (un mot, un fichier, une vidéo) et produit une empreinte de taille fixe appelée **condensat** ou *hash*. + +``` +"Bonjour" → SHA-256 → 6f5cd4a2d7e0e5... (64 caractères hexadécimaux) +"bonjour" → SHA-256 → 97df3588b5a3f2... (64 caractères hexadécimaux) +``` + +#### Propriétés fondamentales + +Une bonne fonction de hachage vérifie trois propriétés : + +| Propriété | Signification | +|-----------|---------------| +| **Déterministe** | La même entrée donne toujours le même hash | +| **Effet avalanche** | Un seul bit modifié change complètement le hash | +| **Résistance aux collisions** | Il est pratiquement impossible de trouver deux entrées différentes produisant le même hash | + +Et surtout : le hachage est une **fonction à sens unique**. On ne peut pas retrouver le message original à partir du hash. Il n'y a pas de clé, pas de déchiffrement possible. + +> **Chiffrement vs Hachage** +> +> | | Chiffrement | Hachage | +> |---|---|---| +> | Réversible | ✅ Oui (avec la clé) | ❌ Non | +> | Clé | ✅ Nécessaire | ❌ Aucune | +> | Taille du résultat | Variable | Fixe | +> | Usage principal | Confidentialité | Intégrité, authentification | + +#### Algorithmes courants + +| Algorithme | Taille du hash | État actuel | +|------------|----------------|-------------| +| MD5 | 128 bits | ⚠️ Cassé — ne pas utiliser pour la sécurité | +| SHA-1 | 160 bits | ⚠️ Cassé — déprécié | +| **SHA-256** | 256 bits | ✅ Standard actuel | +| bcrypt | variable | ✅ Recommandé pour les mots de passe | + +#### Usages + +**1. Intégrité de fichiers** + +Quand vous téléchargez un logiciel, le site fournit souvent un hash SHA-256. Après téléchargement, vous pouvez calculer le hash du fichier et comparer : si les deux correspondent, le fichier n'a pas été altéré. + +**2. Mots de passe** + +Un site web ne doit **jamais** stocker les mots de passe en clair. Il stocke leur hash. Lors de la connexion, il hache le mot de passe saisi et compare avec le hash stocké. + +``` +Inscription : sha256("monMotDePasse") → "a94a8fe5..." → stocké en base +Connexion : sha256("monMotDePasse") → "a94a8fe5..." → correspond ✅ +Connexion : sha256("mauvaisMotDePasse") → "b14a6f2c..." → ne correspond pas ❌ +``` + +Même si la base de données est volée, les mots de passe en clair restent inconnus. + +**3. Intégrité dans HTTPS** + +TLS utilise des fonctions de hachage pour vérifier que les données n'ont pas été modifiées pendant leur transit (via un mécanisme appelé MAC). + +#### En Python + +```python +import hashlib + +def hacher(message): + """Retourne le hash SHA-256 d'un message.""" + return hashlib.sha256(message.encode()).hexdigest() + +>>> hacher("Bonjour") +'6f5cd4a2d7e0e5b67f5bcf8e8b79d1b3f4c7a9e2d1c0f3b8a5e6d7c9b2a1f0e' + +>>> hacher("bonjour") # Un seul caractère différent → hash complètement différent +'97df3588b5a3f24cd3d18804b48df9c7db98d0a03e74e39b0e88c18bf0a79f7e' +``` + +> La bibliothèque `hashlib` est incluse dans Python, pas besoin d'installation. + +#### Exercice + +1. En Python, calculez le hash SHA-256 de votre prénom, puis de votre prénom avec une majuscule différente. Que constatez-vous ? +2. Pourquoi ne suffit-il pas de hacher un mot de passe pour qu'il soit totalement protégé ? *(Indice : cherchez ce qu'est une "rainbow table")* +3. La Partie 6 du TP gestionnaire de mots de passe utilise `hashlib`. Maintenant que vous connaissez le concept, reprenez-la et expliquez à quoi sert exactement le hash dans ce contexte. + +-------- + #### Sources Computer icons created by Freepik - Flaticon