Review cours Terminale NSI — POO, SQL, Sécurité, Soc, Calculabilité, Réseau

This commit is contained in:
2026-06-15 11:28:37 +02:00
parent fcb20e45f9
commit 9ad5b99920
9 changed files with 1305 additions and 827 deletions

View File

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

View File

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

View File

@@ -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() |
--- ---

View File

@@ -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)

View File

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

View File

@@ -1,274 +1,549 @@
# TP : Introduction au langage SQL avec DB Browser for SQLite # Cours : Le langage SQL
Ce TP vous guidera à travers la création et la manipulation d'une base de données en utilisant le logiciel **DB Browser for SQLite**. Vous apprendrez à créer des tables, insérer des données et exécuter des requêtes SQL pour interroger la base de données. ---
> **Prérequis** : Avoir lu le cours [Cours_SQL.md](Cours_SQL.md) avant de commencer ce TP. ## 1. Introduction
## Prérequis ### 1.1. Historique
- Télécharger et installer [DB Browser for SQLite](https://sqlitebrowser.org/). **SQL** (*Structured Query Language*) est un langage de requêtes créé en 1974 par IBM, puis normalisé en 1986. Il permet d'interagir avec les **bases de données relationnelles**.
## Activité 3.1 : Création d'une base de données SQL est aujourd'hui le standard universel pour :
- Créer et modifier la structure des bases de données
- Insérer, modifier et supprimer des données
- Interroger les données (requêtes)
1. **Lancer DB Browser for SQLite**. Vous devriez obtenir l'écran suivant : ### 1.2. Les SGBD
![Écran d'accueil de DB Browser for SQLite](assets/1.png) Un **SGBD** (*Système de Gestion de Base de Données*) est un logiciel qui permet de stocker, organiser et manipuler des données. Exemples :
2. **Créer une nouvelle base de données** : | SGBD | Type | Utilisation |
|------|------|-------------|
- Cliquez sur "Nouvelle base de données". | SQLite | Léger, fichier local | Applications mobiles, embarqué |
- Nommez votre base de données, par exemple `db_livres.db`. | MySQL / MariaDB | Serveur | Sites web, applications |
- Vous verrez la fenêtre suivante : | PostgreSQL | Serveur avancé | Applications complexes |
| Oracle | Entreprise | Grandes entreprises |
![Fenêtre de création de la base de données](assets/2.png) | Microsoft SQL Server | Entreprise | Environnement Windows |
- Cliquez sur "Annuler" pour fermer cette fenêtre.
3. **Vérifier la création de la base de données** :
- Votre base de données est créée mais ne contient pas encore de tables.
![Base de données sans tables](assets/3.png) En NSI, nous utilisons principalement **SQLite** avec l'outil **DB Browser for SQLite**.
## Activité 3.2 : Création d'une table ---
1. **Accéder à l'onglet "Exécuter le SQL"** : ## 2. Structure d'une base de données
- 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 ### 2.1. Tables, attributs et enregistrements
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. Une base de données relationnelle est composée de **tables**. Chaque table contient :
- Un message "Requête exécutée avec succès" devrait apparaître. - Des **colonnes** (ou **attributs**) : les caractéristiques des données
- Des **lignes** (ou **enregistrements**) : les données elles-mêmes
![Table créée avec succès](assets/5.png) **Exemple : Table LIVRES**
## Activité 3.3 : Insertion de données | id | titre | auteur | ann_publi | note |
|----|-------|--------|-----------|------|
| 1 | 1984 | Orwell | 1949 | 10 |
| 2 | Dune | Herbert | 1965 | 8 |
| 3 | Fondation | Asimov | 1951 | 9 |
1. **Insérer des enregistrements dans la table `LIVRES`** : ### 2.2. Types de données
- Toujours dans l'onglet "Exécuter le SQL", saisissez la requête suivante :
```sql
INSERT INTO LIVRES (id, titre, auteur, ann_publi, note) VALUES
(1, '1984', 'Orwell', 1949, 10),
(2, 'Dune', 'Herbert', 1965, 8),
(3, 'Fondation', 'Asimov', 1951, 9),
(4, 'Le meilleur des mondes', 'Huxley', 1931, 7),
(5, 'Fahrenheit 451', 'Bradbury', 1953, 7),
(6, 'Ubik', 'K.Dick', 1969, 9),
(7, 'Chroniques martiennes', 'Bradbury', 1950, 8),
(8, 'La nuit des temps', 'Barjavel', 1968, 7),
(9, 'Blade Runner', 'K.Dick', 1968, 8),
(10, 'Les Robots', 'Asimov', 1950, 9),
(11, 'La Planète des singes', 'Boulle', 1963, 8),
(12, 'Ravage', 'Barjavel', 1943, 8),
(13, 'Le Maître du Haut Château', 'K.Dick', 1962, 8),
(14, 'Le monde des Ā', 'Van Vogt', 1945, 7),
(15, 'La Fin de léternité', 'Asimov', 1955, 8),
(16, 'De la Terre à la Lune', 'Verne', 1865, 10);
```
- Exécutez la requête en cliquant sur le bouton ▶ ou en appuyant sur F5.
- Un message de confirmation devrait apparaître.
![Données insérées avec succès](assets/6.png)
2. **Vérifier les données insérées** :
- Cliquez sur l'onglet "Parcourir les données" pour voir les enregistrements ajoutés.
![Données dans la table LIVRES](assets/7.png) | Type SQL | Description | Exemple |
|----------|-------------|---------|
| `INT` ou `INTEGER` | Nombre entier | 42, -7, 2024 |
| `REAL` ou `FLOAT` | Nombre décimal | 3.14, -0.5 |
| `TEXT` ou `VARCHAR` | Chaîne de caractères | 'Bonjour', 'Alice' |
| `DATE` | Date | '2024-01-15' |
| `BOOLEAN` | Booléen | TRUE, FALSE |
## Activité 3.4 : Exécution de requêtes SQL ### 2.3. Clés primaires et étrangères
1. **Sélectionner tous les enregistrements** : - **Clé primaire** (`PRIMARY KEY`) : Identifiant unique de chaque enregistrement
- Dans l'onglet "Exécuter le SQL", saisissez la requête suivante : - **Clé étrangère** (`FOREIGN KEY`) : Référence vers la clé primaire d'une autre table
```sql
SELECT id, titre, auteur, ann_publi, note FROM LIVRES;
```
- Exécutez la requête. Vous devriez obtenir tous les enregistrements de la table `LIVRES`.
![Résultat de la requête SELECT](assets/8.png)
2. **Sélectionner des colonnes spécifiques** :
- Pour obtenir uniquement les titres et auteurs des livres, utilisez la requête :
```sql
SELECT titre, auteur FROM LIVRES;
```
3. **Filtrer les enregistrements** :
- Pour obtenir les livres écrits par Asimov, utilisez :
```sql
SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov';
```
4. **Combiner des conditions** :
- Pour obtenir les livres d'Asimov publiés après 1953 :
```sql
SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov' AND ann_publi > 1953;
```
5. **Trier les résultats** :
- Pour trier les livres de K.Dick du plus ancien au plus récent :
```sql
SELECT titre FROM LIVRES WHERE auteur = 'K.Dick' ORDER BY ann_publi;
```
6. Écrivez et testez une requête permettant d'obtenir uniquement les titres des livres écrits par Philip K.Dick.
7. Saisissez et testez la requête SQL suivante :
```sql
SELECT titre, ann_publi
FROM LIVRES
WHERE auteur='Asimov' AND ann_publi>1953
```
Vérifiez que vous obtenez bien les livres écrits par Asimov publiés après 1953.
8. Écrivez une requête permettant d'obtenir les titres des livres publiés après 1945 qui ont une note supérieure ou égale à 9.
9. Écrivez une requête SQL permettant d'obtenir les livres de K.Dick classés du plus ancien au plus récent.
10. Créez une nouvelle base de données que vous nommerez par exemple db_livres_auteurs.db, puis créez une table AUTEURS à l'aide de la requête SQL suivante :
```sql
CREATE TABLE AUTEURS
(id INT, nom TEXT, prenom TEXT, ann_naissance INT, langue_ecriture TEXT, PRIMARY KEY (id));
```
Créez ensuite une deuxième table (LIVRES) :
``` ```
CREATE TABLE LIVRES Table AUTEURS Table LIVRES
(id INT, titre TEXT, id_auteur INT, ann_publi INT, note INT, PRIMARY KEY (id), FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id)); +----+--------+ +----+--------+-----------+
| id | nom | | id | titre | id_auteur |
+----+--------+ +----+--------+-----------+
| 1 | Orwell |<─────────────────| 1 | 1984 | 1 |
| 2 | Asimov |<─────────────────| 2 | Robots | 2 |
+----+--------+ +----+--------+-----------+
PK PK FK
``` ```
Comme vous l'avez sans doute remarqué nous avons précisé dans notre requête que l'attribut "id_auteur" jouera le rôle de clé étrangère : liaison entre "id_auteur" de la table LIVRES et "id" de la table AUTEURS (FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id)). ---
Ajoutez des données à la table AUTEURS à l'aide de la requête SQL suivante : ## 3. Création et modification de tables
### 3.1. Créer une table : CREATE TABLE
```sql ```sql
INSERT INTO AUTEURS CREATE TABLE LIVRES (
(id,nom,prenom,ann_naissance,langue_ecriture) id INTEGER PRIMARY KEY,
VALUES titre TEXT,
(1,'Orwell','George',1903,'anglais'), auteur TEXT,
(2,'Herbert','Frank',1920,'anglais'), ann_publi INTEGER,
(3,'Asimov','Isaac',1920,'anglais'), note INTEGER
(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 : ### 3.2. Créer une table avec clé étrangère
```sql ```sql
INSERT INTO LIVRES CREATE TABLE LIVRES (
(id,titre,id_auteur,ann_publi,note) id INTEGER PRIMARY KEY,
VALUES titre TEXT,
(1,'1984',1,1949,10), id_auteur INTEGER,
(2,'Dune',2,1965,8), ann_publi INTEGER,
(3,'Fondation',3,1951,9), FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id)
(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 : ### 3.3. Supprimer une table : DROP TABLE
```sql ```sql
SELECT titre,nom, prenom DROP TABLE LIVRES;
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). ⚠️ **Attention** : Cette opération est irréversible !
12. Écrivez une requête SQL permettant d'obtenir les titres des livres publiés après 1945 ainsi que le nom de leurs auteurs. ### 3.4. Modifier une table : ALTER TABLE
13. Nous allons repartir avec une nouvelle base de données. Créez une nouvelle base de données nommée "db_livres.db". ```sql
-- Ajouter une colonne
ALTER TABLE LIVRES ADD COLUMN editeur TEXT;
Créez ensuite une table LIVRES à l'aide de la requête suivante : -- Supprimer une colonne (selon le SGBD)
ALTER TABLE LIVRES DROP COLUMN editeur;
```
```sql ---
CREATE TABLE LIVRES
(id INT, titre TEXT, auteur TEXT, ann_publi INT, note INT, PRIMARY KEY (id));
```
Ajoutez des données à la table LIVRES à l'aide de la requête SQL suivante : ## 4. Manipulation des données
```sql ### 4.1. Insérer des données : INSERT INTO
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 : ```sql
- id : 17 -- Insérer un enregistrement
- titre : "2001 : L'Odyssée de l'espace" INSERT INTO LIVRES (id, titre, auteur, ann_publi, note)
- auteur : "Clarke" VALUES (1, '1984', 'Orwell', 1949, 10);
- année de publication : 1968
- note : 7
-- Insérer plusieurs enregistrements
INSERT INTO LIVRES (id, titre, auteur, ann_publi, note)
VALUES
(2, 'Dune', 'Herbert', 1965, 8),
(3, 'Fondation', 'Asimov', 1951, 9);
```
### 4.2. Modifier des données : UPDATE
15. Écrivez une requête permettant d'attribuer la note de 10 à tous les livres écrits par Asimov publiés après 1950. Testez cette requête. ```sql
16. Écrivez une requête permettant de supprimer les livres publiés avant 1945. Testez cette requête. -- Modifier tous les enregistrements correspondant à la condition
UPDATE LIVRES
SET note = 10
WHERE auteur = 'Asimov';
-------- -- Modifier plusieurs colonnes
UPDATE LIVRES
SET note = 9, ann_publi = 1950
WHERE id = 3;
```
Source : ⚠️ **Attention** : Sans clause `WHERE`, tous les enregistrements seront modifiés !
- [Pixees, site de David Roche](https://informatique-lycee.forge.apps.education.fr/terminale_nsi/cours-terminale/c3a/) ### 4.3. Supprimer des données : DELETE
```sql
-- Supprimer les enregistrements correspondant à la condition
DELETE FROM LIVRES
WHERE ann_publi < 1950;
-- Supprimer tous les enregistrements (vider la table)
DELETE FROM LIVRES;
```
⚠️ **Attention** : Sans clause `WHERE`, tous les enregistrements seront supprimés !
---
## 5. Requêtes de sélection : SELECT
### 5.1. Syntaxe de base
```sql
SELECT colonnes
FROM table
WHERE conditions
ORDER BY colonne [ASC|DESC];
```
### 5.2. Sélectionner des colonnes
```sql
-- Toutes les colonnes
SELECT * FROM LIVRES;
-- Colonnes spécifiques
SELECT titre, auteur FROM LIVRES;
-- Avec alias
SELECT titre AS "Titre du livre", auteur AS "Écrivain"
FROM LIVRES;
```
### 5.3. Filtrer avec WHERE
**Opérateurs de comparaison :**
| Opérateur | Signification |
|-----------|---------------|
| `=` | Égal à |
| `<>` ou `!=` | Différent de |
| `<`, `<=` | Inférieur (ou égal) |
| `>`, `>=` | Supérieur (ou égal) |
| `BETWEEN a AND b` | Entre a et b (inclus) |
| `IN (v1, v2, ...)` | Dans la liste |
| `LIKE` | Correspondance de motif |
| `IS NULL` | Est nul |
**Exemples :**
```sql
-- Égalité
SELECT * FROM LIVRES WHERE auteur = 'Asimov';
-- Comparaison
SELECT * FROM LIVRES WHERE ann_publi > 1960;
-- Entre deux valeurs
SELECT * FROM LIVRES WHERE ann_publi BETWEEN 1950 AND 1970;
-- Dans une liste
SELECT * FROM LIVRES WHERE auteur IN ('Asimov', 'Bradbury', 'K.Dick');
-- Correspondance de motif (LIKE)
SELECT * FROM LIVRES WHERE titre LIKE '%Robot%';
-- % = n'importe quelle suite de caractères
-- _ = un seul caractère
-- Valeur nulle
SELECT * FROM LIVRES WHERE note IS NULL;
```
### 5.4. Combiner les conditions : AND, OR, NOT
```sql
-- ET logique
SELECT * FROM LIVRES
WHERE auteur = 'Asimov' AND ann_publi > 1950;
-- OU logique
SELECT * FROM LIVRES
WHERE auteur = 'Asimov' OR auteur = 'Bradbury';
-- Négation
SELECT * FROM LIVRES
WHERE NOT auteur = 'Asimov';
-- Combinaison avec parenthèses
SELECT * FROM LIVRES
WHERE (auteur = 'Asimov' OR auteur = 'Bradbury') AND note >= 8;
```
### 5.5. Trier les résultats : ORDER BY
```sql
-- Tri croissant (par défaut)
SELECT * FROM LIVRES ORDER BY ann_publi;
SELECT * FROM LIVRES ORDER BY ann_publi ASC;
-- Tri décroissant
SELECT * FROM LIVRES ORDER BY note DESC;
-- Tri multiple
SELECT * FROM LIVRES ORDER BY auteur ASC, ann_publi DESC;
```
### 5.6. Éliminer les doublons : DISTINCT
```sql
-- Liste des auteurs (sans doublons)
SELECT DISTINCT auteur FROM LIVRES;
```
### 5.7. Limiter les résultats : LIMIT
```sql
-- Les 5 premiers résultats
SELECT * FROM LIVRES LIMIT 5;
-- Pagination : 5 résultats à partir du 10e
SELECT * FROM LIVRES LIMIT 5 OFFSET 10;
```
---
## 6. Fonctions d'agrégation
Les fonctions d'agrégation effectuent des calculs sur un ensemble de valeurs.
### 6.1. Les fonctions principales
| Fonction | Description |
|----------|-------------|
| `COUNT(*)` | Nombre d'enregistrements |
| `COUNT(colonne)` | Nombre de valeurs non nulles |
| `SUM(colonne)` | Somme des valeurs |
| `AVG(colonne)` | Moyenne des valeurs |
| `MIN(colonne)` | Valeur minimale |
| `MAX(colonne)` | Valeur maximale |
### 6.2. Exemples
```sql
-- Nombre total de livres
SELECT COUNT(*) FROM LIVRES;
-- Nombre de livres par auteur
SELECT COUNT(*) FROM LIVRES WHERE auteur = 'Asimov';
-- Note moyenne
SELECT AVG(note) FROM LIVRES;
-- Note minimale et maximale
SELECT MIN(note), MAX(note) FROM LIVRES;
-- Somme des notes (peu utile ici, mais illustratif)
SELECT SUM(note) FROM LIVRES;
-- Année du livre le plus ancien
SELECT MIN(ann_publi) FROM LIVRES;
```
### 6.3. Regrouper les données : GROUP BY
`GROUP BY` permet de regrouper les enregistrements par valeur d'une colonne.
```sql
-- Nombre de livres par auteur
SELECT auteur, COUNT(*) AS nb_livres
FROM LIVRES
GROUP BY auteur;
-- Note moyenne par auteur
SELECT auteur, AVG(note) AS note_moyenne
FROM LIVRES
GROUP BY auteur;
-- Résultat :
-- +----------+--------------+
-- | auteur | note_moyenne |
-- +----------+--------------+
-- | Asimov | 8.67 |
-- | Bradbury | 7.50 |
-- | K.Dick | 8.33 |
-- +----------+--------------+
```
### 6.4. Filtrer les groupes : HAVING
`HAVING` filtre les résultats **après** le regroupement (contrairement à `WHERE` qui filtre **avant**).
```sql
-- Auteurs ayant écrit plus de 2 livres
SELECT auteur, COUNT(*) AS nb_livres
FROM LIVRES
GROUP BY auteur
HAVING COUNT(*) > 2;
-- Auteurs avec une note moyenne >= 8
SELECT auteur, AVG(note) AS note_moyenne
FROM LIVRES
GROUP BY auteur
HAVING AVG(note) >= 8;
```
**Différence WHERE / HAVING :**
```sql
-- WHERE filtre les lignes AVANT le regroupement
SELECT auteur, AVG(note)
FROM LIVRES
WHERE ann_publi > 1950 -- Filtre les livres publiés après 1950
GROUP BY auteur;
-- HAVING filtre les groupes APRÈS le regroupement
SELECT auteur, AVG(note)
FROM LIVRES
GROUP BY auteur
HAVING AVG(note) > 8; -- Garde les auteurs avec moyenne > 8
```
---
## 7. Jointures
Les jointures permettent de combiner des données provenant de plusieurs tables.
### 7.1. INNER JOIN (jointure interne)
Retourne uniquement les enregistrements qui ont une correspondance dans les deux tables.
```sql
SELECT LIVRES.titre, AUTEURS.nom, AUTEURS.prenom
FROM LIVRES
INNER JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id;
```
**Schéma :**
```
LIVRES AUTEURS Résultat INNER JOIN
+----+------+ +----+------+ +------+------+
| id | id_a | | id | nom | | titre| nom |
+----+------+ +----+------+ +------+------+
| 1 | 1 | | 1 | Orwell| | 1984 | Orwell|
| 2 | 2 | | 2 | Asimov| | Fond.| Asimov|
| 3 | NULL | | 3 | Dick | +------+------+
+----+------+ +----+------+ (le livre 3 est exclu car id_a est NULL)
```
### 7.2. LEFT JOIN (jointure externe gauche)
Retourne tous les enregistrements de la table de gauche, même sans correspondance.
```sql
SELECT LIVRES.titre, AUTEURS.nom
FROM LIVRES
LEFT JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id;
```
### 7.3. Alias de tables
Pour simplifier l'écriture :
```sql
SELECT L.titre, A.nom, A.prenom
FROM LIVRES L
INNER JOIN AUTEURS A ON L.id_auteur = A.id
WHERE A.langue_ecriture = 'français';
```
### 7.4. Jointures multiples
```sql
SELECT L.titre, A.nom, E.nom_editeur
FROM LIVRES L
INNER JOIN AUTEURS A ON L.id_auteur = A.id
INNER JOIN EDITEURS E ON L.id_editeur = E.id;
```
---
## 8. Ordre d'exécution des clauses
L'ordre d'écriture et l'ordre d'exécution sont différents :
**Ordre d'écriture :**
```sql
SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT ...
```
**Ordre d'exécution :**
1. `FROM` et `JOIN` : Sélection des tables
2. `WHERE` : Filtrage des lignes
3. `GROUP BY` : Regroupement
4. `HAVING` : Filtrage des groupes
5. `SELECT` : Sélection des colonnes
6. `DISTINCT` : Élimination des doublons
7. `ORDER BY` : Tri
8. `LIMIT` : Limitation du nombre de résultats
---
## 9. Bonnes pratiques
### 9.1. Conventions d'écriture
- Mots-clés SQL en **MAJUSCULES** : `SELECT`, `FROM`, `WHERE`
- Noms de tables en **MAJUSCULES** : `LIVRES`, `AUTEURS`
- Noms de colonnes en **minuscules** : `titre`, `auteur`
- Indentation pour la lisibilité
```sql
SELECT L.titre,
A.nom,
A.prenom
FROM LIVRES L
INNER JOIN AUTEURS A ON L.id_auteur = A.id
WHERE A.langue_ecriture = 'français'
AND L.ann_publi > 1950
ORDER BY L.ann_publi DESC;
```
### 9.2. Sécurité : Injections SQL
⚠️ Ne jamais construire des requêtes SQL par concaténation de chaînes avec des entrées utilisateur !
```python
# DANGEREUX - Injection SQL possible
requete = "SELECT * FROM USERS WHERE nom = '" + nom_utilisateur + "'"
# SÉCURISÉ - Requête paramétrée
cursor.execute("SELECT * FROM USERS WHERE nom = ?", (nom_utilisateur,))
```
---
## 10. Synthèse
```
┌─────────────────────────────────────────────────────────────────┐
│ REQUÊTE SQL │
├─────────────────────────────────────────────────────────────────┤
│ SELECT [DISTINCT] colonnes, AGG(colonne) │
│ FROM table1 │
│ [INNER|LEFT] JOIN table2 ON condition │
│ WHERE conditions │
│ GROUP BY colonne │
│ HAVING condition_agregation │
│ ORDER BY colonne [ASC|DESC] │
│ LIMIT n [OFFSET m] │
└─────────────────────────────────────────────────────────────────┘
┌──────────────┬────────────────────────────────────────────────┐
│ Commande │ Action │
├──────────────┼────────────────────────────────────────────────┤
│ CREATE TABLE │ Créer une table │
│ DROP TABLE │ Supprimer une table │
│ INSERT INTO │ Insérer des données │
│ UPDATE │ Modifier des données │
│ DELETE │ Supprimer des données │
│ SELECT │ Interroger des données │
└──────────────┴────────────────────────────────────────────────┘
┌──────────────┬────────────────────────────────────────────────┐
│ Agrégation │ Description │
├──────────────┼────────────────────────────────────────────────┤
│ COUNT(*) │ Nombre d'enregistrements │
│ SUM(col) │ Somme │
│ AVG(col) │ Moyenne │
│ MIN(col) │ Minimum │
│ MAX(col) │ Maximum │
└──────────────┴────────────────────────────────────────────────┘
```
---
## Pour aller plus loin
- **SQL Murder Mystery** : Un jeu pour apprendre SQL en résolvant un meurtre
[https://mystery.knightlab.com](https://mystery.knightlab.com)
- **SQLBolt** : Tutoriel interactif
[https://sqlbolt.com](https://sqlbolt.com)
- **W3Schools SQL** : Référence complète
[https://www.w3schools.com/sql/](https://www.w3schools.com/sql/)
--- ---
@@ -277,4 +552,3 @@ Auteur : Florian Mathieu
Licence CC BY NC Licence 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
View 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 :
![Écran d'accueil de DB Browser for SQLite](assets/1.png)
2. **Créer une nouvelle base de données** :
- Cliquez sur "Nouvelle base de données".
- Nommez votre base de données, par exemple `db_livres.db`.
- Vous verrez la fenêtre suivante :
![Fenêtre de création de la base de données](assets/2.png)
- Cliquez sur "Annuler" pour fermer cette fenêtre.
3. **Vérifier la création de la base de données** :
- Votre base de données est créée mais ne contient pas encore de tables.
![Base de données sans tables](assets/3.png)
## Activité 3.2 : Création d'une table
1. **Accéder à l'onglet "Exécuter le SQL"** :
- Cliquez sur l'onglet "Exécuter le SQL".
2. **Créer la table `LIVRES`** :
- Dans la fenêtre "SQL 1", saisissez la requête suivante :
```sql
CREATE TABLE LIVRES (
id INT PRIMARY KEY,
titre TEXT,
auteur TEXT,
ann_publi INT,
note INT
);
```
- Cliquez sur le bouton ▶ (ou appuyez sur F5) pour exécuter la requête.
- Un message "Requête exécutée avec succès" devrait apparaître.
![Table créée avec succès](assets/5.png)
## Activité 3.3 : Insertion de données
1. **Insérer des enregistrements dans la table `LIVRES`** :
- Toujours dans l'onglet "Exécuter le SQL", saisissez la requête suivante :
```sql
INSERT INTO LIVRES (id, titre, auteur, ann_publi, note) VALUES
(1, '1984', 'Orwell', 1949, 10),
(2, 'Dune', 'Herbert', 1965, 8),
(3, 'Fondation', 'Asimov', 1951, 9),
(4, 'Le meilleur des mondes', 'Huxley', 1931, 7),
(5, 'Fahrenheit 451', 'Bradbury', 1953, 7),
(6, 'Ubik', 'K.Dick', 1969, 9),
(7, 'Chroniques martiennes', 'Bradbury', 1950, 8),
(8, 'La nuit des temps', 'Barjavel', 1968, 7),
(9, 'Blade Runner', 'K.Dick', 1968, 8),
(10, 'Les Robots', 'Asimov', 1950, 9),
(11, 'La Planète des singes', 'Boulle', 1963, 8),
(12, 'Ravage', 'Barjavel', 1943, 8),
(13, 'Le Maître du Haut Château', 'K.Dick', 1962, 8),
(14, 'Le monde des Ā', 'Van Vogt', 1945, 7),
(15, 'La Fin de léternité', 'Asimov', 1955, 8),
(16, 'De la Terre à la Lune', 'Verne', 1865, 10);
```
- Exécutez la requête en cliquant sur le bouton ▶ ou en appuyant sur F5.
- Un message de confirmation devrait apparaître.
![Données insérées avec succès](assets/6.png)
2. **Vérifier les données insérées** :
- Cliquez sur l'onglet "Parcourir les données" pour voir les enregistrements ajoutés.
![Données dans la table LIVRES](assets/7.png)
## Activité 3.4 : Exécution de requêtes SQL
1. **Sélectionner tous les enregistrements** :
- Dans l'onglet "Exécuter le SQL", saisissez la requête suivante :
```sql
SELECT id, titre, auteur, ann_publi, note FROM LIVRES;
```
- Exécutez la requête. Vous devriez obtenir tous les enregistrements de la table `LIVRES`.
![Résultat de la requête SELECT](assets/8.png)
2. **Sélectionner des colonnes spécifiques** :
- Pour obtenir uniquement les titres et auteurs des livres, utilisez la requête :
```sql
SELECT titre, auteur FROM LIVRES;
```
3. **Filtrer les enregistrements** :
- Pour obtenir les livres écrits par Asimov, utilisez :
```sql
SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov';
```
4. **Combiner des conditions** :
- Pour obtenir les livres d'Asimov publiés après 1953 :
```sql
SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov' AND ann_publi > 1953;
```
5. **Trier les résultats** :
- Pour trier les livres de K.Dick du plus ancien au plus récent :
```sql
SELECT titre FROM LIVRES WHERE auteur = 'K.Dick' ORDER BY ann_publi;
```
6. Écrivez et testez une requête permettant d'obtenir uniquement les titres des livres écrits par Philip K.Dick.
7. Saisissez et testez la requête SQL suivante :
```sql
SELECT titre, ann_publi
FROM LIVRES
WHERE auteur='Asimov' AND ann_publi>1953
```
Vérifiez que vous obtenez bien les livres écrits par Asimov publiés après 1953.
8. Écrivez une requête permettant d'obtenir les titres des livres publiés après 1945 qui ont une note supérieure ou égale à 9.
9. Écrivez une requête SQL permettant d'obtenir les livres de K.Dick classés du plus ancien au plus récent.
10. Créez une nouvelle base de données que vous nommerez par exemple db_livres_auteurs.db, puis créez une table AUTEURS à l'aide de la requête SQL suivante :
```sql
CREATE TABLE AUTEURS
(id INT, nom TEXT, prenom TEXT, ann_naissance INT, langue_ecriture TEXT, PRIMARY KEY (id));
```
Créez ensuite une deuxième table (LIVRES) :
```
CREATE TABLE LIVRES
(id INT, titre TEXT, id_auteur INT, ann_publi INT, note INT, PRIMARY KEY (id), FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id));
```
Comme vous l'avez sans doute remarqué nous avons précisé dans notre requête que l'attribut "id_auteur" jouera le rôle de clé étrangère : liaison entre "id_auteur" de la table LIVRES et "id" de la table AUTEURS (FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id)).
Ajoutez des données à la table AUTEURS à l'aide de la requête SQL suivante :
```sql
INSERT INTO AUTEURS
(id,nom,prenom,ann_naissance,langue_ecriture)
VALUES
(1,'Orwell','George',1903,'anglais'),
(2,'Herbert','Frank',1920,'anglais'),
(3,'Asimov','Isaac',1920,'anglais'),
(4,'Huxley','Aldous',1894,'anglais'),
(5,'Bradbury','Ray',1920,'anglais'),
(6,'K.Dick','Philip',1928,'anglais'),
(7,'Barjavel','René',1911,'français'),
(8,'Boulle','Pierre',1912,'français'),
(9,'Van Vogt','Alfred Elton',1912,'anglais'),
(10,'Verne','Jules',1828,'français');
```
Ajoutez des données à la table LIVRES à l'aide de la requête SQL suivante :
```sql
INSERT INTO LIVRES
(id,titre,id_auteur,ann_publi,note)
VALUES
(1,'1984',1,1949,10),
(2,'Dune',2,1965,8),
(3,'Fondation',3,1951,9),
(4,'Le meilleur des mondes',4,1931,7),
(5,'Fahrenheit 451',5,1953,7),
(6,'Ubik',6,1969,9),
(7,'Chroniques martiennes',5,1950,8),
(8,'La nuit des temps',7,1968,7),
(9,'Blade Runner',6,1968,8),
(10,'Les Robots',3,1950,9),
(11,'La Planète des singes',8,1963,8),
(12,'Ravage',7,1943,8),
(13,'Le Maître du Haut Château',6,1962,8),
(14,'Le monde des Ā',9,1945,7),
(15,'La Fin de léternité',3,1955,8),
(16,'De la Terre à la Lune',10,1865,10);
```
11. Saisissez et testez la requête SQL suivante :
```sql
SELECT titre,nom, prenom
FROM LIVRES
INNER JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id
```
Rappel : attention, si un même nom d'attribut est présent dans les 2 tables (par exemple ici l'attribut id), il est nécessaire d'ajouter le nom de la table devant afin de pouvoir les distinguer (AUTEURS.id et LIVRES.id).
12. Écrivez une requête SQL permettant d'obtenir les titres des livres publiés après 1945 ainsi que le nom de leurs auteurs.
13. Nous allons repartir avec une nouvelle base de données. Créez une nouvelle base de données nommée "db_livres.db".
Créez ensuite une table LIVRES à l'aide de la requête suivante :
```sql
CREATE TABLE LIVRES
(id INT, titre TEXT, auteur TEXT, ann_publi INT, note INT, PRIMARY KEY (id));
```
Ajoutez des données à la table LIVRES à l'aide de la requête SQL suivante :
```sql
INSERT INTO LIVRES
(id,titre,auteur,ann_publi,note)
VALUES
(1,'1984','Orwell',1949,10),
(2,'Dune','Herbert',1965,8),
(3,'Fondation','Asimov',1951,9),
(4,'Le meilleur des mondes','Huxley',1931,7),
(5,'Fahrenheit 451','Bradbury',1953,7),
(6,'Ubik','K.Dick',1969,9),
(7,'Chroniques martiennes','Bradbury',1950,8),
(8,'La nuit des temps','Barjavel',1968,7),
(9,'Blade Runner','K.Dick',1968,8),
(10,'Les Robots','Asimov',1950,9),
(11,'La Planète des singes','Boulle',1963,8),
(12,'Ravage','Barjavel',1943,8),
(13,'Le Maître du Haut Château','K.Dick',1962,8),
(14,'Le monde des Ā','Van Vogt',1945,7),
(15,'La Fin de léternité','Asimov',1955,8),
(16,'De la Terre à la Lune','Verne',1865,10);
```
14. À l'aide d'une requête SQL, ajoutez à la table LIVRES le livre suivant :
- id : 17
- titre : "2001 : L'Odyssée de l'espace"
- auteur : "Clarke"
- année de publication : 1968
- note : 7
15. Écrivez une requête permettant d'attribuer la note de 10 à tous les livres écrits par Asimov publiés après 1950. Testez cette requête.
16. Écrivez une requête permettant de supprimer les livres publiés avant 1945. Testez cette requête.
## Activité 3.5 : Fonctions d'agrégation
> **Prérequis** : utiliser la base `db_livres.db` créée à l'activité 3.4 (avec la table LIVRES simple, avant les suppressions de la question 16 — si vous avez supprimé des lignes, réinsérez les données avec le `INSERT INTO` de l'activité 3.4).
Les fonctions d'agrégation effectuent un calcul sur un ensemble de lignes et renvoient **une seule valeur**.
### 1. Compter des enregistrements : COUNT
Exécutez les requêtes suivantes et notez les résultats :
```sql
-- Nombre total de livres
SELECT COUNT(*) FROM LIVRES;
-- Nombre de livres écrits par Asimov
SELECT COUNT(*) FROM LIVRES WHERE auteur = 'Asimov';
```
> `COUNT(*)` compte toutes les lignes. La clause `WHERE` s'applique **avant** le comptage.
### 2. Calculer une moyenne, un min, un max : AVG, MIN, MAX
```sql
-- Note moyenne de tous les livres
SELECT AVG(note) FROM LIVRES;
-- Note la plus basse et la plus haute
SELECT MIN(note), MAX(note) FROM LIVRES;
-- Livre le plus ancien
SELECT MIN(ann_publi) FROM LIVRES;
```
> Les alias permettent de nommer le résultat :
> ```sql
> SELECT AVG(note) AS note_moyenne FROM LIVRES;
> ```
17. Écrivez une requête donnant la note moyenne des livres de Bradbury.
18. Écrivez une requête donnant l'année de publication du livre le plus récent dans la base.
### 3. Regrouper les résultats : GROUP BY
`GROUP BY` divise les lignes en groupes selon les valeurs d'une colonne, et applique la fonction d'agrégation à chaque groupe séparément.
```sql
-- Nombre de livres par auteur
SELECT auteur, COUNT(*) AS nb_livres
FROM LIVRES
GROUP BY auteur;
```
Exécutez cette requête. Vous devriez obtenir une ligne par auteur avec son nombre de livres.
```sql
-- Note moyenne par auteur
SELECT auteur, AVG(note) AS note_moyenne
FROM LIVRES
GROUP BY auteur
ORDER BY note_moyenne DESC;
```
19. Écrivez une requête donnant, pour chaque auteur, l'année de son livre le plus ancien.
### 4. Filtrer les groupes : HAVING
`WHERE` filtre les lignes **avant** le regroupement. Pour filtrer les groupes **après**, on utilise `HAVING`.
```sql
-- Auteurs ayant écrit au moins 2 livres dans la base
SELECT auteur, COUNT(*) AS nb_livres
FROM LIVRES
GROUP BY auteur
HAVING COUNT(*) >= 2;
```
> **À retenir :** `WHERE` porte sur les lignes individuelles, `HAVING` porte sur les groupes.
```sql
-- Auteurs dont la note moyenne dépasse 8
SELECT auteur, AVG(note) AS note_moyenne
FROM LIVRES
GROUP BY auteur
HAVING AVG(note) > 8;
```
20. Écrivez une requête listant les auteurs ayant publié des livres dans **deux décennies différentes** au minimum.
*(Indice : `MIN(ann_publi)` et `MAX(ann_publi)` dans le même GROUP BY, puis filtrer avec HAVING sur la différence)*
21. Écrivez une requête donnant, parmi les auteurs ayant au moins 2 livres, celui dont la note moyenne est la plus élevée. Triez de façon appropriée et limitez à 1 résultat.
--------
Source :
- [Pixees, site de David Roche](https://informatique-lycee.forge.apps.education.fr/terminale_nsi/cours-terminale/c3a/)
---
Auteur : Florian Mathieu
Licence CC BY NC
<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>.

View File

@@ -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
``` ```

View File

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