B04 - SQL : créer la structure (DDL)
Objectif
Créer une base, des tables avec les bons types et les contraintes, les modifier, ajouter des index et des vues. Dialecte principal : T-SQL (SQL Server), avec les différences MariaDB/MySQL. Cours d’origine : Principe de base de la création de BDD.
1. Les familles de commandes SQL
| Famille | Rôle | Commandes |
|---|---|---|
| DDL (Data Definition) | Structure | CREATE, ALTER, DROP, TRUNCATE |
| DML (Data Manipulation) | Données | SELECT, INSERT, UPDATE, DELETE → B05 - SQL - interroger et modifier les données |
| DCL (Data Control) | Droits | GRANT, REVOKE, DENY |
| TCL (Transaction Control) | Transactions | BEGIN TRAN, COMMIT, ROLLBACK |
2. Base de données
CREATE DATABASE GestionParc;
GO -- (T-SQL) sépare les lots d'instructions dans SSMS / sqlcmd / VS Code
USE GestionParc;
GO
DROP DATABASE IF EXISTS GestionParc; -- supprimer (⚠ irréversible)3. Les types de données (SQL Server)
| Catégorie | Type | Usage / remarque |
|---|---|---|
| Entiers | TINYINT (0-255), SMALLINT, INT, BIGINT | Identifiants, quantités |
| Décimaux exacts | DECIMAL(p, s) / NUMERIC | Argent, mesures précises : DECIMAL(10,2) = 8 chiffres avant la virgule, 2 après |
| Décimaux approchés | FLOAT, REAL | Calcul scientifique (jamais pour l’argent) |
| Monétaire | MONEY | Préférer DECIMAL |
| Booléen | BIT | 0 / 1 |
| Texte Unicode (recommandé) | NCHAR(n), NVARCHAR(n), NVARCHAR(MAX) | Accents, toutes langues - préfixer les littéraux par N'…' |
| Texte non Unicode | CHAR(n), VARCHAR(n), VARCHAR(MAX) | Codes, références ASCII |
| Dates | DATE, TIME, DATETIME2, DATETIMEOFFSET | DATETIME2 remplace DATETIME ; DATETIMEOFFSET garde le fuseau |
| Binaire | VARBINARY(MAX) | Fichiers (mieux : stocker le chemin du fichier) |
| Identifiant global | UNIQUEIDENTIFIER + NEWID() | GUID |
| Obsolètes | TEXT, NTEXT, IMAGE | Remplacés par (N)VARCHAR(MAX), VARBINARY(MAX) |
| Piège | TIMESTAMP / ROWVERSION | Ce n’est pas une date : un compteur binaire de version de ligne |
| SQL Server | MariaDB / MySQL |
|---|---|
INT IDENTITY(1,1) | INT AUTO_INCREMENT |
NVARCHAR(100) | VARCHAR(100) (avec CHARSET utf8mb4) |
BIT | BOOLEAN (= TINYINT(1)) |
DATETIME2 | DATETIME |
NVARCHAR(MAX) | TEXT / LONGTEXT |
TOP 10 | LIMIT 10 |
GETDATE() | NOW() |
ISNULL(x, 0) | IFNULL(x, 0) (ou COALESCE, standard, dans les deux) |
4. CREATE TABLE avec toutes les contraintes
CREATE TABLE Salles (
id_salle INT IDENTITY(1,1) CONSTRAINT PK_Salles PRIMARY KEY,
nom_salle NVARCHAR(50) NOT NULL CONSTRAINT UQ_Salles_Nom UNIQUE,
etage TINYINT NOT NULL CONSTRAINT CK_Salles_Etage CHECK (etage BETWEEN 0 AND 5)
);
CREATE TABLE Postes (
id_poste INT IDENTITY(1,1) CONSTRAINT PK_Postes PRIMARY KEY,
nom_poste NVARCHAR(50) NOT NULL,
adresse_ip VARCHAR(15) NULL CONSTRAINT UQ_Postes_IP UNIQUE,
prix_achat DECIMAL(8,2) NULL CONSTRAINT CK_Postes_Prix CHECK (prix_achat > 0),
date_achat DATE NOT NULL CONSTRAINT DF_Postes_Date DEFAULT (CAST(GETDATE() AS DATE)),
est_portable BIT NOT NULL CONSTRAINT DF_Postes_Portable DEFAULT 0,
id_salle INT NOT NULL,
CONSTRAINT FK_Postes_Salles FOREIGN KEY (id_salle)
REFERENCES Salles(id_salle)
ON DELETE NO ACTION -- refuse de supprimer une salle qui contient des postes
ON UPDATE CASCADE
);Nomme tes contraintes (
PK_…,FK_…,CK_…,UQ_…,DF_…) : les messages d'erreur deviennent lisibles et tu pourras les supprimer facilement (ALTER TABLE … DROP CONSTRAINT CK_Postes_Prix).
Contraintes CHECK plus riches (exercice Zoo)
CONSTRAINT CK_Animal_Id CHECK (id_animal LIKE REPLICATE('[0-9]', 14)), -- exactement 14 chiffres
CONSTRAINT CK_Animal_Dates CHECK (date_naissance IS NULL OR date_naissance <= date_arrivee),
CONSTRAINT CK_Animal_Depart CHECK (date_depart IS NULL OR date_depart > date_arrivee),
CONSTRAINT CK_Animal_Steril CHECK (sterilise = 0 OR sexe IN ('M', 'F')) -- pas stérilisé si sexe inconnuActions sur les clés étrangères
| Action | Quand on supprime/modifie la ligne PARENTE… |
|---|---|
NO ACTION (défaut) | …c’est refusé s’il existe des lignes filles |
CASCADE | …les lignes filles sont supprimées / mises à jour aussi |
SET NULL | …la FK des filles passe à NULL (FK doit accepter NULL) |
SET DEFAULT | …la FK des filles prend sa valeur par défaut |
5. Modifier une table : ALTER
ALTER TABLE Postes ADD numero_serie NVARCHAR(50) NULL; -- ajouter une colonne
ALTER TABLE Postes ALTER COLUMN nom_poste NVARCHAR(100) NOT NULL; -- changer le type (T-SQL)
-- MariaDB : ALTER TABLE Postes MODIFY nom_poste VARCHAR(100) NOT NULL;
ALTER TABLE Postes DROP COLUMN numero_serie; -- supprimer
ALTER TABLE Postes ADD CONSTRAINT CK_Postes_Nom CHECK (LEN(nom_poste) >= 3);
ALTER TABLE Postes DROP CONSTRAINT CK_Postes_Nom;
EXEC sp_rename 'Postes.nom_poste', 'libelle_poste', 'COLUMN'; -- renommer (T-SQL)6. Supprimer
| Commande | Effet |
|---|---|
DROP TABLE IF EXISTS Postes; | Supprime la table et ses données |
TRUNCATE TABLE Postes; | Vide la table (rapide, remet l’IDENTITY à 1) - impossible si référencée par une FK |
DELETE FROM Postes; | Vide ligne par ligne (journalisé, respecte les FK) |
Ordre : supprimer d’abord les tables filles (qui ont les FK), puis les parentes.
7. Index et vues
-- Index : accélère les recherches et jointures sur une colonne
CREATE INDEX IX_Postes_Salle ON Postes(id_salle);
CREATE UNIQUE INDEX UX_Postes_Serie ON Postes(numero_serie) WHERE numero_serie IS NOT NULL; -- index filtré
-- Vue : une requête enregistrée, utilisable comme une table
CREATE OR ALTER VIEW v_PostesParSalle AS
SELECT s.nom_salle, COUNT(p.id_poste) AS nb_postes
FROM Salles s LEFT JOIN Postes p ON p.id_salle = s.id_salle
GROUP BY s.nom_salle;
GO
SELECT * FROM v_PostesParSalle;Les clés primaires et contraintes UNIQUE créent automatiquement un index. Les clés étrangères non : indexe-les toi-même.
8. Droits (DCL) - principe
-- SQL Server
CREATE LOGIN app_web WITH PASSWORD = 'MotDePasse#Fort1';
CREATE USER app_web FOR LOGIN app_web;
GRANT SELECT, INSERT, UPDATE ON dbo.Postes TO app_web;
DENY DELETE ON dbo.Postes TO app_web;MariaDB : B07 - MariaDB et MySQL.