Datawarehouse : bien gérer l'intégrité référentielle

Gérer proprement l'intégrité de sa base décisionnelle, c'est peut-être fastidieux mais c'est indispensable ! Quelques règles de base pour modéliser son datawarehouse et un plaidoyer pour les contraintes d'intégrité...

La modélisation d'une base de données décisionnelle nous impose très fréquemment un modèle de données en étoile (ou en flocon), indispensable à l'analyse multidimensionnelle :
  • la table de fait, au centre de l'étoile contient les mesures : ce sont les éléments que l'on va analyser et agréger comme les montants, les quantités, etc...
  • les branches de l'étoile sont les tables de dimension qui représentent les axes d'analyse : temps, clients, produits, etc...
Des jointures relationnelles entre les faits et les dimensions sont assurées par les clés des tables de dimension et celles des tables de fait.
Et dès lors qu'il existe une relation et qu'elle doit être vérifiée, nous devrions nous servir des mécanismes du SGBD qui servent à garantir l'intégrité référentielle : les contraintes de clé primaire, les contraintes de clé étrangère, les contraintes UNIQUE, les colonnes NOT NULL.

On voit beaucoup trop souvent des bases de données décisionnelles sans clés étrangères, des tables sans clés primaires ni contrainte d'unicité. Et je ne parle pas des NULL...

Certains concepteurs vont défendre leurs choix de modélisation avec divers arguments :
  • Lors du chargement, le coût des index en performances est élevé
  • Nécessité de maintenir les index qui peuvent se fragmenter avec les insertions et mises à jour
  • Les clés étrangères obligent à conserver un ordre lors du chargement du datawarehouse : tables de dimension d'abord puis tables de fait
  • Impossibilité de vider ses tables avec des instruction TRUNCATE lorsqu'il existe une contrainte de clé étrangère
  • Les chargements de données risquent d'échouer sur des violations de contraintes
  • Tous les contrôles sont fait dans l'ETL, dans ce cas pourquoi implémenter des contraintes ?
  • Tous ces mécanismes, c'est pour du transactionnel et c'est beaucoup trop lourd pour le décisionnel...
  • Une base décisionnelle est "dénormalisée"...
Cela reste certes ouvert au débat sur certains points. Il n'en n'est pas moins vrai que le développeur est humain et soumis à quelques défaillances. Les données elles-mêmes ont souvent des problèmes de qualité. Des contraintes dans la base de données garantiront l'intégrité au moment de l'alimentation et bloqueront toute possibilité d'erreur !
Il faut aussi prendre en compte les points suivants :
  • L'optimiseur de SQL Server tient aussi compte des contraintes (check, FK) dans le choix des plans de requête.Les contraintes FK ont un coût (relativement minime) lors des insertions, mise à jour et suppressions, mais elles peuvent cependant aider l’optimiseur lors des requêtes SELECT avec des jointures.
  • L’existence de contraintes FK lors du chargement des tables oblige aussi à conserver un ordre logique: tables de références chargées en premier, puis tables de faits. Un peu de rigueur ne fait pas de mal.
  • De même que pour les clés étrangères, les contraintes de clé primaire et les contraintes d'unicité permettent d’identifier plus facilement des problèmes de modèle, de doublon, de double chargement ou de contrôle d’unicité manquant dans le traitement. Quelles chiffres obtiendrez-vous si vous chargez des factures en double ?
  • Il est vrai qu'en présence de clés primaires, l’impact sur les performances de chargement peut être important et doit être géré, de même façon que pour tous les index pré-existants au moment d’un chargement. Différentes techniques sont possibles, dans le choix de l'index ou de la clé, dans l'ordre des données chargées, ou au pire une désactivation temporaire de l'index (et donc réindexation après).

Alors, soyons raisonnables : j'ai vu des projets entiers échouer avec des données incohérentes. Quelques contraintes d'intégrité auraient permis de s'en rendre compte !