Apprenez en lisant dans l'ordre

Contraintes de colonne — NOT NULL / UNIQUE / CHECK / PRIMARY KEY

Conçois des tables comme app_member avec PRIMARY KEY / NOT NULL / UNIQUE / CHECK, puis vis l'expérience d'INSERT en violation rejetés avec des erreurs constraint failed — en pratique dans le navigateur.

Ce que sont les contraintes de colonne — bloquer les données invalides côté base

Une contrainte de colonne (une règle d'entrée attachée à une colonne) est une « condition sur les valeurs qui peuvent entrer dans cette colonne », écrite dans CREATE TABLE.

Cet article couvre les quatre principales — PRIMARY KEY (identifie de façon unique une ligne),

NOT NULL (interdit NULL), UNIQUE (interdit les doublons) et CHECK (interdit les valeurs qui ne satisfont pas une condition).

Contrairement aux articles précédents, aucune donnée n'est préchargée — au lieu de ça, tu construis toi-même les tables dans les exercices et tu exécutes des INSERT en violation exprès pour vivre les erreurs.

Les rôles des quatre contraintes de colonne
PRIMARY KEYIdentifie de façon unique une lignePas de NULL, pas de doublonsNOT NULLInterdit NULLRend la saisie obligatoireUNIQUEInterdit les valeurs en doublon(NULL est autorisé)CHECKInterdit les valeurs oùl'expression n'est pas vraie
Chaque contrainte restreint « quelles valeurs peuvent entrer dans la colonne ». Les INSERT / UPDATE en violation sont rejetés avec une erreur, empêchant les données invalides d'entrer dans la table.

Déclarer une table avec des contraintes

Les contraintes viennent après le type dans une définition de colonne.

La forme est nom_colonne type contrainte contrainte ..., et tu peux empiler plusieurs contraintes sur une seule colonne.

Attacher PRIMARY KEY à une colonne INTEGER en fait la clé primaire qui identifie de façon unique une ligne.

NOT NULL interdit d'omettre la valeur, UNIQUE interdit la même valeur qu'une autre ligne, et CHECK (expression) interdit toute valeur qui ne rend pas l'expression vraie.

La table member ci-dessous fait de member_id la clé primaire, de handle (un nom d'utilisateur) NOT NULL plus UNIQUE, et attache un CHECK « non-négatif » à age.

-- Exemple d'une définition de table avec contraintes (à lire simplement)
CREATE TABLE IF NOT EXISTS member (
  member_id INTEGER PRIMARY KEY,        -- clé primaire : unique et non NULL
  handle    TEXT    NOT NULL UNIQUE,    -- obligatoire et sans doublons
  email     TEXT    UNIQUE,             -- sans doublons (NULL autorisé)
  age       INTEGER CHECK (age >= 0)    -- seulement des valeurs non-négatives
);

-- Une ligne qui satisfait chaque contrainte passe sans souci
INSERT INTO member (member_id, handle, email, age)
VALUES (1, 'alice', 'alice@example.com', 30);

Imagine le besoin : « concevoir une table member avec des contraintes pour que les données invalides ne puissent pas entrer. » (Exécute correctement et l'explication apparaît.)

① Commence par DROP TABLE IF EXISTS app_member; pour nettoyer toute version précédente, puis construis la table app_member. Colonnes : member_id (entier, clé primaire), handle (texte, obligatoire et sans doublons), email (texte, sans doublons mais NULL autorisé), age (entier, non-négatif uniquement).

② INSERT une ligne qui satisfait chaque contrainte (par ex. member_id 1 / handle chaîne ASCII / email chaîne ASCII / age entier ≥ 0).

③ Exécute SELECT * FROM app_member; pour confirmer qu'une ligne est entrée.

Éditeur SQL

Exécutez une requête pour voir les résultats

Les violations de contraintes lèvent des erreurs — NOT NULL et UNIQUE

Le rôle d'une contrainte est de rejeter les écritures en violation.

Tenter de mettre NULL (ou d'omettre la valeur) dans une colonne NOT NULL lève une erreur NOT NULL constraint failed, et insérer une valeur déjà existante dans une colonne UNIQUE / PRIMARY KEY lève une erreur UNIQUE constraint failed.

La ligne d'INSERT qui a erré n'entre pas dans la table.

Flux d'un INSERT en violation de contrainte
INSERT quisatisfait la contrainteLa base accepteLigne ajoutéeINSERT quiviole la contrainteerreurconstraint failedLigne non ajoutée(données invalides bloquées)
Les lignes qui satisfont les contraintes passent normalement ; celles qui les violent sont rejetées avec une erreur et ne sont jamais ajoutées. Une erreur est la preuve que « la contrainte fonctionne ».
-- Violation NOT NULL : tente de mettre NULL dans handle (à lire simplement)
INSERT INTO member (member_id, handle, age) VALUES (2, NULL, 20);
--> Erreur : NOT NULL constraint failed: member.handle

-- Violation UNIQUE : tente d'insérer le même handle qu'une ligne existante (à lire simplement)
INSERT INTO member (member_id, handle, age) VALUES (3, 'alice', 25);
--> Erreur : UNIQUE constraint failed: member.handle

Imagine le besoin : « vérifier l'effet de rendre handle obligatoire en déclenchant un INSERT en violation. » Cet exercice réussit si tu obtiens une erreur (preuve que la contrainte bloque correctement les données invalides).

① Le DELETE FROM app_member; initial vide app_member de l'exercice 1 (pour que relancer donne le même résultat).

② Écris un INSERT qui met NULL dans la colonne handle NOT NULL exprès (par ex. member_id 1 / handle NULL / email NULL / age 20).

③ Exécute et confirme que tu obtiens une erreur NOT NULL constraint failed: app_member.handle. Remarque que le message d'erreur indique quelle table et quelle colonne ont été violées.

Éditeur SQL

Exécutez une requête pour voir les résultats

Imagine le besoin : « vérifier l'effet d'interdire les doublons sur handle en déclenchant un INSERT en violation. » Cet exercice réussit aussi si tu obtiens une erreur.

① Le DELETE FROM app_member; initial vide app_member de l'exercice 1.

② Pour la ligne 1, écris ton propre INSERT avec handle à 'alice' (par ex. member_id 1 / handle 'alice' / email 'alice@example.com' / age 30).

③ Pour la ligne 2, écris un autre INSERT avec le même handle 'alice' (tu peux changer member_id et email).

④ Exécute et confirme que la ligne 1 passe bien, tandis que la ligne 2 lève UNIQUE constraint failed: app_member.handle.

Éditeur SQL

Exécutez une requête pour voir les résultats

Contraintes CHECK — exprimer les conditions de valeur comme expressions

CHECK (expression) est une contrainte qui utilise une expression pour décrire quelles valeurs peuvent entrer dans la colonne.

CHECK (age >= 0) rejette les âges négatifs, CHECK (price > 0) rejette les prix de 0 ou en dessous.

Un schéma fréquent est CHECK (status IN ('active','inactive')), qui limite l'ensemble des valeurs autorisées.

Si l'expression ne s'évalue pas à vrai, l'INSERT / UPDATE est rejeté avec une erreur CHECK constraint failed.

Les exercices finaux de cet article utilisent CHECK (age >= 0) et CHECK (status IN (...)) pour vivre comment CHECK rejette les violations.

Comment CHECK évalue vrai/faux
Valeur INSERTÉvaluer l'expressionRésultatage = 30age >= 0→ vraiAcceptéLigne ajoutéeage = -5age >= 0→ fauxCHECKconstraint failedstatus ='banned'status IN('active','inactive')→ fauxCHECKconstraint failed
L'expression CHECK est évaluée pour chaque ligne INSERT. Vrai → accepté, sinon → rejeté comme CHECK constraint failed.
-- Restreindre la plage ou l'ensemble de valeurs via CHECK (à lire simplement)
CREATE TABLE IF NOT EXISTS product (
  product_id INTEGER PRIMARY KEY,
  price      INTEGER CHECK (price > 0),
  status     TEXT    CHECK (status IN ('active','inactive'))
);

-- price <= 0 est rejeté avec CHECK constraint failed
INSERT INTO product (product_id, price, status) VALUES (1, -100, 'active');

Imagine le besoin : « vérifier l'effet d'attacher un CHECK non-négatif à age en déclenchant un INSERT en violation. » Une erreur est la condition de réussite.

① Le DELETE FROM app_member; initial vide app_member de l'exercice 1.

② Écris ton propre INSERT qui met une valeur négative (par ex. -5) dans age. Comme handle est NOT NULL, donne-lui une valeur non-NULL.

③ Exécute et confirme que tu obtiens une erreur CHECK constraint failed: app_member.age. Optionnel : essaie de changer age pour une valeur non-négative et vois que l'INSERT passe alors.

Éditeur SQL

Exécutez une requête pour voir les résultats

Imagine le besoin : « limiter la colonne status d'un membre aux deux valeurs 'active' / 'inactive' uniquement. » C'est l'exercice final de l'article — une erreur est la condition de réussite.

① Commence par DROP TABLE IF EXISTS app_member_status; pour nettoyer toute version précédente, puis construis toi-même la table app_member_status. Deux colonnes : member_id (entier, clé primaire) et status (texte, obligatoire et seulement 'active' ou 'inactive' autorisés).

② Comme ligne 1, INSERT une des valeurs autorisées ('active' ou 'inactive').

③ Comme ligne 2, INSERT 'banned', qui n'est pas dans la liste autorisée.

④ Exécute et confirme que la ligne 1 passe et que la ligne 2 lève CHECK constraint failed: app_member_status.status.

Éditeur SQL

Exécutez une requête pour voir les résultats
QUIZ

Vérification des connaissances

Répondez à chaque question une par une.

Question 1À propos d'une colonne déclarée handle TEXT NOT NULL UNIQUE, quelle affirmation est correcte ?

Question 2Que se passe-t-il quand tu tentes d'INSERT une valeur déjà existante dans une colonne UNIQUE ?

Question 3Quelle contrainte est la mieux adaptée pour exprimer la règle métier « seuls les prix strictement supérieurs à 0 sont autorisés » dans la définition de table ?