ProgrammationData Engineer

Comment mettre en œuvre la génération et la mise à jour automatiques des colonnes calculées (Computed Columns) dans SQL ? Quelle est la différence entre leur déclaration au niveau de la table et les calculs dans les requêtes, et quelles difficultés peuvent survenir ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Les colonnes calculées sont des colonnes dont les valeurs sont automatiquement générées à partir d'autres colonnes dans la table. Ce concept a été introduit pour faciliter l'accès aux résultats de calculs typiques, afin d'éviter de répéter des formules dans chaque requête. Elles peuvent être déclarées comme virtuelles (les valeurs sont calculées à chaque sélection) ou matérialisées (physiquement stockées lors de la mise à jour des données).

Le problème est que tous les types d'expressions ne peuvent pas être calculés au niveau de la table (limitations sur les types de fonctions), et le stockage physique des données dérivées occupe de l'espace et nécessite une mise à jour lors des opérations UPDATE.

Solution : déclarer les colonnes calculées au niveau DDL lorsque cela est possible, ou implémenter la logique de mise à jour via des triggers/procédures, si un stockage est requis ou utiliser des agrégats.

Example de code (MS SQL Server) :

ALTER TABLE orders ADD total_sum AS (quantity * price); -- virtuel ALTER TABLE orders ADD total_sum_persisted AS (quantity * price) PERSISTED; -- matérialisé

Caractéristiques clés :

  • Les colonnes virtuelles réduisent la redondance, mais diminuent la vitesse de sélection.
  • Les matérialisées se mettent à jour automatiquement, mais consomment de l'espace et des ressources.
  • Certaines expressions sont interdites : on ne peut pas utiliser des fonctions non réplicables ou des sous-requêtes dans les colonnes calculées.

Questions pièges.

Peut-on créer un index sur une colonne calculée ?

Si la colonne est déclarée comme PERSISTED (stockée physiquement), un index peut être créé. Pour les colonnes virtuelles — ce n'est pas toujours possible, cela dépend du SGBD.

CREATE INDEX ix_total_sum ON orders (total_sum_persisted);

Les colonnes calculées se mettent-elles à jour automatiquement lorsque les colonnes d'origine changent ?

Oui, lors de l'insertion/modification des données d'origine, une nouvelle valeur est calculée automatiquement si la colonne est déclarée au niveau de la table comme calculée.

Que se passe-t-il si une colonne calculée fait référence à NULL ?

La plupart des SGBD renvoient NULL si au moins un opérande est NULL — assurez-vous de traiter la valeur NULL potentielle via COALESCE/ISNULL.

ALTER TABLE orders ADD total_with_discount AS (COALESCE(quantity * price, 0));

Erreurs typiques et anti-patterns

  • Stocker des valeurs dérivées redondantes sans nécessité, ce qui conduit à une augmentation du volume.
  • Utilisation d'expressions complexes et non indexables, ralentissant les performances.
  • Mise à jour incohérente, si les calculs sont effectués au niveau de l'application et non de la base.

Exemple de la vie réelle

Cas négatif

La base stocke comme champs distincts le montant du produit et le prix, et séparément — total. Lors de la mise à jour du produit, le total n'est pas actualisé.

Avantages :

  • Lecture rapide

Inconvénients :

  • Incohérence des données, difficultés lors des recalculs.

Cas positif

Le montant total est déclaré comme colonne virtuelle. Toujours précis, il ne diverge pas des valeurs d'origine.

Avantages :

  • Pas de désynchronisation
  • Simplification du code d'interaction avec la base

Inconvénients :

  • Ralentissement insignifiant lors des formules complexes, si de nombreux calculs sont effectués.