Review cours Terminale NSI — POO, SQL, Sécurité, Soc, Calculabilité, Réseau
This commit is contained in:
@@ -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.
|
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.
|
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.
|
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.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
#### Vous suivez toujours ?
|
#### 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 ?
|
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.
|
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.
|
||||||
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 !
|
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|||||||
@@ -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
|
## Résumé des classes
|
||||||
|
|
||||||
| Classe | Attributs | Méthodes principales |
|
| Classe | Hérite de | Attributs supplémentaires | Méthodes modifiées |
|
||||||
|--------|-----------|----------------------|
|
|--------|-----------|---------------------------|--------------------|
|
||||||
| `Pokemon` | nom, type, niveau, pv, attaque | attaquer(), subir_degats(), est_ko() |
|
| `Pokemon` | — | nom, type, niveau, pv, attaque | attaquer(), subir_degats(), est_ko() |
|
||||||
| `Dresseur` | nom, equipe | ajouter_pokemon(), tous_ko() |
|
| `PokemonFeu` | `Pokemon` | — | attaquer() |
|
||||||
| `Combat` | dresseur1, dresseur2, tour | lancer_combat() |
|
| `PokemonEau` | `Pokemon` | — | attaquer() |
|
||||||
| `CentrePokemon` | ville | soigner_equipe() |
|
| `PokemonPlante` | `Pokemon` | — | attaquer() |
|
||||||
|
| `Dresseur` | — | nom, equipe | ajouter_pokemon(), tous_ko() |
|
||||||
|
| `Combat` | — | dresseur1, dresseur2, tour | lancer_combat() |
|
||||||
|
| `CentrePokemon` | — | ville | soigner_equipe() |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
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 |
|
| 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 |
|
| 2 | Internet | IP, ICMP |
|
||||||
| 1 | Accès réseau | Ethernet, Wi-Fi |
|
| 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 :
|
1. Trouvez votre adresse IP locale avec la commande :
|
||||||
```sh
|
```sh
|
||||||
ipconfig (Windows) ou ifconfig / ip a (Linux/Mac)
|
ipconfig (Windows) ou ifconfig / ip a (Linux/Mac)
|
||||||
|
|||||||
554
SQL/Cours_SQL.md
554
SQL/Cours_SQL.md
@@ -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
|
|
||||||
|
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
|
||||||
670
SQL/README.md
670
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
|
||||||
|
|
||||||

|
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** :
|
| 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 |
|
||||||
|
|
||||||
- Cliquez sur "Nouvelle base de données".
|
En NSI, nous utilisons principalement **SQLite** avec l'outil **DB Browser for SQLite**.
|
||||||
- Nommez votre base de données, par exemple `db_livres.db`.
|
|
||||||
- Vous verrez la fenêtre suivante :
|
|
||||||
|
|
||||||

|
---
|
||||||
|
|
||||||
- Cliquez sur "Annuler" pour fermer cette fenêtre.
|
## 2. Structure d'une base de données
|
||||||
|
|
||||||
3. **Vérifier la création de la base de données** :
|
### 2.1. Tables, attributs et enregistrements
|
||||||
- Votre base de données est créée mais ne contient pas encore de tables.
|
|
||||||
|
|
||||||

|
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
|
||||||
|
|
||||||
## Activité 3.2 : Création d'une table
|
**Exemple : Table LIVRES**
|
||||||
|
|
||||||
1. **Accéder à l'onglet "Exécuter le SQL"** :
|
| id | titre | auteur | ann_publi | note |
|
||||||
|
|----|-------|--------|-----------|------|
|
||||||
|
| 1 | 1984 | Orwell | 1949 | 10 |
|
||||||
|
| 2 | Dune | Herbert | 1965 | 8 |
|
||||||
|
| 3 | Fondation | Asimov | 1951 | 9 |
|
||||||
|
|
||||||
- Cliquez sur l'onglet "Exécuter le SQL".
|
### 2.2. Types de données
|
||||||
|
|
||||||
2. **Créer la table `LIVRES`** :
|
| Type SQL | Description | Exemple |
|
||||||
- Dans la fenêtre "SQL 1", saisissez la requête suivante :
|
|----------|-------------|---------|
|
||||||
|
| `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
|
```sql
|
||||||
CREATE TABLE LIVRES (
|
CREATE TABLE LIVRES (
|
||||||
id INT PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
titre TEXT,
|
titre TEXT,
|
||||||
auteur TEXT,
|
auteur TEXT,
|
||||||
ann_publi INT,
|
ann_publi INTEGER,
|
||||||
note INT
|
note INTEGER
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
- Cliquez sur le bouton ▶ (ou appuyez sur F5) pour exécuter la requête.
|
### 3.2. Créer une table avec clé étrangère
|
||||||
- Un message "Requête exécutée avec succès" devrait apparaître.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 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
|
```sql
|
||||||
INSERT INTO LIVRES (id, titre, auteur, ann_publi, note) VALUES
|
CREATE TABLE LIVRES (
|
||||||
(1, '1984', 'Orwell', 1949, 10),
|
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),
|
(2, 'Dune', 'Herbert', 1965, 8),
|
||||||
(3, 'Fondation', 'Asimov', 1951, 9),
|
(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.
|
### 4.2. Modifier des données : UPDATE
|
||||||
- Un message de confirmation devrait apparaître.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
2. **Vérifier les données insérées** :
|
|
||||||
- Cliquez sur l'onglet "Parcourir les données" pour voir les enregistrements ajoutés.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 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
|
```sql
|
||||||
SELECT id, titre, auteur, ann_publi, note FROM LIVRES;
|
-- 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;
|
||||||
```
|
```
|
||||||
|
|
||||||
- Exécutez la requête. Vous devriez obtenir tous les enregistrements de la table `LIVRES`.
|
⚠️ **Attention** : Sans clause `WHERE`, tous les enregistrements seront modifiés !
|
||||||
|
|
||||||

|
### 4.3. Supprimer des données : DELETE
|
||||||
|
|
||||||
2. **Sélectionner des colonnes spécifiques** :
|
|
||||||
- Pour obtenir uniquement les titres et auteurs des livres, utilisez la requête :
|
|
||||||
|
|
||||||
```sql
|
```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;
|
SELECT titre, auteur FROM LIVRES;
|
||||||
|
|
||||||
|
-- Avec alias
|
||||||
|
SELECT titre AS "Titre du livre", auteur AS "Écrivain"
|
||||||
|
FROM LIVRES;
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Filtrer les enregistrements** :
|
### 5.3. Filtrer avec WHERE
|
||||||
- Pour obtenir les livres écrits par Asimov, utilisez :
|
|
||||||
|
**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
|
```sql
|
||||||
SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov';
|
-- É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;
|
||||||
```
|
```
|
||||||
|
|
||||||
4. **Combiner des conditions** :
|
### 5.4. Combiner les conditions : AND, OR, NOT
|
||||||
- Pour obtenir les livres d'Asimov publiés après 1953 :
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov' AND ann_publi > 1953;
|
-- 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. **Trier les résultats** :
|
### 5.5. Trier les résultats : ORDER BY
|
||||||
- Pour trier les livres de K.Dick du plus ancien au plus récent :
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SELECT titre FROM LIVRES WHERE auteur = 'K.Dick' ORDER BY ann_publi;
|
-- 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
|
||||||
|
|
||||||
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
|
```sql
|
||||||
SELECT titre, ann_publi
|
-- 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
|
FROM LIVRES
|
||||||
WHERE auteur='Asimov' AND ann_publi>1953
|
GROUP BY auteur;
|
||||||
```
|
|
||||||
|
|
||||||
Vérifiez que vous obtenez bien les livres écrits par Asimov publiés après 1953.
|
-- Note moyenne par auteur
|
||||||
|
SELECT auteur, AVG(note) AS note_moyenne
|
||||||
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
|
FROM LIVRES
|
||||||
INNER JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id
|
GROUP BY auteur;
|
||||||
|
|
||||||
|
-- Résultat :
|
||||||
|
-- +----------+--------------+
|
||||||
|
-- | auteur | note_moyenne |
|
||||||
|
-- +----------+--------------+
|
||||||
|
-- | Asimov | 8.67 |
|
||||||
|
-- | Bradbury | 7.50 |
|
||||||
|
-- | K.Dick | 8.33 |
|
||||||
|
-- +----------+--------------+
|
||||||
```
|
```
|
||||||
|
|
||||||
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).
|
### 6.4. Filtrer les groupes : HAVING
|
||||||
|
|
||||||
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.
|
`HAVING` filtre les résultats **après** le regroupement (contrairement à `WHERE` qui filtre **avant**).
|
||||||
|
|
||||||
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
|
```sql
|
||||||
CREATE TABLE LIVRES
|
-- Auteurs ayant écrit plus de 2 livres
|
||||||
(id INT, titre TEXT, auteur TEXT, ann_publi INT, note INT, PRIMARY KEY (id));
|
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;
|
||||||
```
|
```
|
||||||
|
|
||||||
Ajoutez des données à la table LIVRES à l'aide de la requête SQL suivante :
|
**Différence WHERE / HAVING :**
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
INSERT INTO LIVRES
|
-- WHERE filtre les lignes AVANT le regroupement
|
||||||
(id,titre,auteur,ann_publi,note)
|
SELECT auteur, AVG(note)
|
||||||
VALUES
|
FROM LIVRES
|
||||||
(1,'1984','Orwell',1949,10),
|
WHERE ann_publi > 1950 -- Filtre les livres publiés après 1950
|
||||||
(2,'Dune','Herbert',1965,8),
|
GROUP BY auteur;
|
||||||
(3,'Fondation','Asimov',1951,9),
|
|
||||||
(4,'Le meilleur des mondes','Huxley',1931,7),
|
-- HAVING filtre les groupes APRÈS le regroupement
|
||||||
(5,'Fahrenheit 451','Bradbury',1953,7),
|
SELECT auteur, AVG(note)
|
||||||
(6,'Ubik','K.Dick',1969,9),
|
FROM LIVRES
|
||||||
(7,'Chroniques martiennes','Bradbury',1950,8),
|
GROUP BY auteur
|
||||||
(8,'La nuit des temps','Barjavel',1968,7),
|
HAVING AVG(note) > 8; -- Garde les auteurs avec moyenne > 8
|
||||||
(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
|
|
||||||
|
|
||||||
|
## 7. Jointures
|
||||||
|
|
||||||
|
Les jointures permettent de combiner des données provenant de plusieurs tables.
|
||||||
|
|
||||||
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.
|
### 7.1. INNER JOIN (jointure interne)
|
||||||
16. Écrivez une requête permettant de supprimer les livres publiés avant 1945. Testez cette requête.
|
|
||||||
|
|
||||||
--------
|
Retourne uniquement les enregistrements qui ont une correspondance dans les deux tables.
|
||||||
|
|
||||||
Source :
|
```sql
|
||||||
|
SELECT LIVRES.titre, AUTEURS.nom, AUTEURS.prenom
|
||||||
|
FROM LIVRES
|
||||||
|
INNER JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id;
|
||||||
|
```
|
||||||
|
|
||||||
- [Pixees, site de David Roche](https://informatique-lycee.forge.apps.education.fr/terminale_nsi/cours-terminale/c3a/)
|
**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 CC BY NC
|
||||||
|
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||||
|
|
||||||
|
|||||||
372
SQL/TP_SQLite.md
Normal file
372
SQL/TP_SQLite.md
Normal file
@@ -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 :
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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 :
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 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.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
2. **Vérifier les données insérées** :
|
||||||
|
- Cliquez sur l'onglet "Parcourir les données" pour voir les enregistrements ajoutés.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 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`.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||||
|
|
||||||
@@ -1,5 +1,25 @@
|
|||||||
# Circuits intégrés et Systèmes sur Puce (SoC)
|
# Circuits intégrés et Systèmes sur Puce (SoC)
|
||||||
|
|
||||||
|
<img src="assets/bo.png" alt="bo" style="zoom:50%;" />
|
||||||
|
|
||||||
|
> 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
|
## 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
|
## Synthèse
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -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
|
#### Sources
|
||||||
|
|
||||||
<a href="https://www.flaticon.com/free-icons/computer" title="computer icons">Computer icons created by Freepik - Flaticon</a>
|
<a href="https://www.flaticon.com/free-icons/computer" title="computer icons">Computer icons created by Freepik - Flaticon</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user