Bases de Données: Concepts Fondamentaux
1. Introduction aux Bases de Données
Une base de données est un système organisé pour stocker et gérer des données de manière structurée. Les systèmes de gestion de bases de données relationnelles (SGBDR) comme MySQL, PostgreSQL ou SQLite organisent les données en tables avec des relations entre elles. Ce modèle relationnel, formalisé par Edgar Codd dans les années 1970, repose sur l'algèbre relationnelle et les opérateurs ensemblistes (UNION, INTERSECTION, DIFFÉRENCE).
Les caractéristiques ACID garantissent la fiabilité des transactions: Atomicité (tout ou rien), Cohérence (intégrité des données préservée), Isolation (transactions indépendantes), Durabilité (persistance). Le modèle client-serveur permet une gestion centralisée des données avec contrôle d'accès granulaire.
1.1 Schéma SQL de base et contraintes
-- Création avec contraintes d'intégrité CREATE TABLE students ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL VARCHAR(100), email TEXT UNIQUE NOT NULL, grade REAL CHECK(grade >= 0 AND grade <= 20), created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- Index pour améliorer les performances CREATE INDEX idx_students_name ON students(name); -- Requête avec agrégation et jointure SELECT s.name, COUNT(e.book_id) as borrowed_books FROM students s LEFT JOIN enrollments e ON s.id = e.student_id GROUP BY s.id, s.name;
2. Conception des Bases de Données
La conception d'une base de données suit une méthode systématique en plusieurs phases:
- Analyse des besoins: Recenser les entités, leurs attributs, et les associations entre elles
- Modèle Entité-Association (EA): Diagramme UML/MCD avec entités (rectangles), associations (losanges), et cardinalités
- Normalisation: Application des formes normales pour éliminer redondances (1FN, 2FN, 3FN, BCNF)
- Conversion: Transformation en tables relationnelles avec clés primaires et étrangères
2.1 Formes normales et exemples
-- Exemple d'entité avec relations CREATE TABLE authors ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, nationality TEXT ); CREATE TABLE books ( id INTEGER PRIMARY KEY, title TEXT NOT NULL, author_id INTEGER, publication_year INTEGER, FOREIGN KEY (author_id) REFERENCES authors(id) ); -- Table de jointure pour relation many-to-many CREATE TABLE student_courses ( student_id INTEGER, course_id INTEGER, enrollment_date DATE, PRIMARY KEY (student_id, course_id), FOREIGN KEY (student_id) REFERENCES students(id), FOREIGN KEY (course_id) REFERENCES courses(id) );
3. Langage SQL - Structured Query Language
SQL est le langage standard ANSI/ISO-9075 pour interagir avec les bases de données relationnelles. Il se compose de sous-ensembles: DDL (Data Definition), DML (Data Manipulation), DCL (Data Control), et TCL (Transaction Control).
3.1 Requêtes de sélection avancées
-- Sélection avec filtres complexes SELECT s.name, s.email, AVG(g.grade) as average_grade FROM students s JOIN grades g ON s.id = g.student_id WHERE g.date >= '2024-01-01' GROUP BY s.id, s.name, s.email HAVING AVG(g.grade) > 15 ORDER BY average_grade DESC LIMIT 10; -- Sous-requête corrélative SELECT name FROM students s WHERE EXISTS ( SELECT 1 FROM enrollments e WHERE e.student_id = s.id AND e.status = 'active' ); -- Union de résultats SELECT name FROM students UNION SELECT name FROM teachers;
3.2 Opérations de modification
-- Insertion avec valeurs par défaut
INSERT INTO courses (title, credits, department) VALUES ('Mathématiques', 3, 'STEM');
-- Mise à jour conditionnelle
UPDATE students
SET status = 'alumni'
WHERE graduation_date < '2020-01-01' AND status = 'inactive';
-- Suppression avec cascade
DELETE FROM authors WHERE id NOT IN (SELECT author_id FROM books);
4. Indexation et Optimisation
Les index améliorent les performances des requêtes en créant des structures de recherche (B-tree, Hash, GiST). Ils accélèrent les clauses WHERE, JOIN, et ORDER BY mais ralentissent les opérations d'écriture (INSERT, UPDATE, DELETE). Une index unique garantit l'unicité des valeurs.
-- Index composites pour requêtes multi-colonnes CREATE INDEX idx_student_dept_grade ON students(department, grade DESC); -- Index partiel pour sous-ensemble de données CREATE INDEX idx_active_students ON students(id) WHERE status = 'active'; -- Analyse des performances EXPLAIN QUERY PLAN SELECT * FROM students WHERE department = 'Computer Science';
JavaScript: Programmation Web Dynamique
5. Introduction à JavaScript
JavaScript (ECMAScript) est un langage de programmation interprété, orienté objet et fonctionnel. Il est exécuté côté client dans les navigateurs via le moteur JavaScript (V8, SpiderMonkey) et côté serveur avec NodeJS. Le moteur utilise un Garbage Collector pour la gestion automatique de la mémoire.
L'environnement d'exécution comprend le moteur JS, le Runtime (Web APIs ou libuv), et la file d'attente de callbacks. L'Event Loop permet la programmation asynchrone non bloquante grâce aux callbacks et Promises.
5.1 Types primitifs et structures de données
// Types primitifs: string, number, boolean, null, undefined, symbol, bigint
const message = 'Hello World';
const count = 42;
const isActive = true;
// Structures: Array, Object, Map, Set, WeakMap, WeakSet
const students = [
{ id: 1, name: 'Alice', grades: [15, 17, 14] },
{ id: 2, name: 'Bob', grades: [12, 19, 16] }
];
const gradeCache = new Map();
const uniqueSubjects = new Set(['Math', 'Physics', 'Chemistry']);
// Spread operator et destructuring
const [first, ...others] = students;
const studentCopy = { ...students[0], active: true };
6. Fonctions et Closures
Les fonctions en JavaScript sont des objets de première classe. Elles peuvent être déclarées (function), expressions (const fn = function), ou fléchées (const fn = () =>). Les closures capturent la portée lexicale, permettant la création de fonctions privées.
6.1 Fonctions fléchées et closures
// Fonction fléchée avec implicit return
const sum = (a, b) => a + b;
// Closure pour encapsulation
function createCounter(initial = 0) {
let count = initial;
return {
increment: () => ++count,
decrement: () => --count,
getCount: () => count
};
}
const counter = createCounter(5);
counter.increment(); // 6
// Higher-order functions
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);
6.2 Async/Await et Promises
// Gestion asynchrone avec async/await
async function fetchUserData(userId) {
try {
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
return data;
} catch (error) {
console.error('Fetch failed:', error);
throw error;
}
}
// Promise chaining
fetch('/api/data')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
7. Manipulation du DOM (Document Object Model)
Le DOM est une interface programmatique représentant la structure HTML/XML. Chaque élément est un nœud accessible via des méthodes: getElementById, querySelector, querySelectorAll. Les événements suivent la propagation en 3 phases: capture, target, bubbling.
7.1 Sélection et modification d'éléments
// Sélection d'éléments
const button = document.querySelector('#submit-btn');
const items = document.querySelectorAll('.list-item');
// Création et insertion
const newDiv = document.createElement('div');
newDiv.className = 'card';
newDiv.innerHTML = '<h3>New Card</h3>';
document.body.appendChild(newDiv);
// Gestion des événements
button.addEventListener('click', (event) => {
console.log('Clicked!', event.target);
event.preventDefault();
});
// Event delegation
document.addEventListener('click', (e) => {
if (e.target.matches('.delete-btn')) {
e.target.closest('.item').remove();
}
});
TypeScript & NodeJS: Développement Backend
8. Introduction à TypeScript
TypeScript (Microsoft) est un superset typé de JavaScript compilé en JS pur. Il ajoute: typage statique, interfaces, classes abstraites, génériques, enums, et modules. Le compilateur tsc utilise les fichiers tsconfig.json pour la configuration.
8.1 Configuration et compilation
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"outDir": "./dist",
"rootDir": "./src",
"declaration": true
}
}
// Compilation
// tsc # Compile tous les .ts
// tsc --watch # Mode watch
// tsc --noEmit # Vérification sans compilation
9. Types et Interfaces
TypeScript distingue les types primitifs (string, number, boolean) des types complexes (Array<T>, Tuple, Union, Intersection, Literal). Les interfaces définissent des contrats pour la forme des objets. Les types peuvent être étendus via des décorateurs.
9.1 Types avancés et exemples
// Interface et type
interface Student {
readonly id: number;
name: string;
grade: number;
optional?: boolean;
}
type Status = 'active' | 'inactive' | 'pending';
type StudentRecord = Record<number, Student>;
// Génériques
interface Repository<T> {
findById(id: number): T | undefined;
save(entity: T): void;
}
class StudentRepository implements Repository<Student> {
private students: Map<number, Student> = new Map();
findById(id: number): Student | undefined {
return this.students.get(id);
}
save(student: Student): void {
this.students.set(student.id, student);
}
}
10. Introduction à NodeJS
NodeJS (Runtime JavaScript côté serveur) utilise le moteur V8 et la bibliothèque libuv. Architecture single-threaded avec Event Loop pour la concurrence non bloquante. Modules Core: fs, http, path, events, stream, crypto. NPM est le gestionnaire de paquets.
10.1 Serveur HTTP basique
const http = require('http');
const fs = require('fs');
const path = require('path');
const server = http.createServer(async (req, res) => {
// Routing simple
if (req.url === '/' && req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Hello from NodeJS!</h1>');
} else if (req.url === '/api/data' && req.method === 'GET') {
res.writeHead(200, {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
});
res.end(JSON.stringify({ status: 'ok', data: [] }));
} else {
res.writeHead(404);
res.end('Not Found');
}
});
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
11. Système de fichiers et modules
Le module fs (File System) permet les opérations asynchrones et synchrones sur les fichiers. Les Streams gèrent efficacement les gros volumes de données en mode pipe. Modules CommonJS (require/module.exports) vs ES Modules (import/export).
11.1 Opérations FS et modules
// Lecture asynchrone avec Promise
const { readFile, writeFile, readdir } = require('fs').promises;
async function processFile(filepath: string) {
try {
const content = await readFile(filepath, 'utf-8');
const lines = content.split('\n').length;
return { filepath, lines };
} catch (error) {
console.error(`Error processing ${filepath}:`, error);
}
}
// Streaming pour gros fichiers
const { createReadStream, createWriteStream } = require('fs');
const readStream = createReadStream('large-file.txt', 'utf-8');
const writeStream = createWriteStream('output.txt');
readStream.pipe(writeStream);
// Module personnalisé
export function calculateGrade(scores: number[]): number {
return scores.reduce((sum, s) => sum + s, 0) / scores.length;
}