Champs calculés dans une BDD

Cool, un peu de base de données aujourd’hui !

En effet tout n’est pas rose dans les monde des SGBD, et souvent des choix s’imposent pour faciliter la future phase de développement d’une application. Ici on va parler d’optimisation de tables. A savoir, faut-il stocker le résultat de sous requêtes dans un attribut de la table. On appelle ces champs, des champs calculés.

En effet, des effets de bords concernant la rapidité des requêtes peuvent poser problème, et les enjeux peuvent être plus important que la normalisation, optimisation de la base de données.

Le cas du forum

Rien de mieux qu’un exemple pour illustrer mes propos. Prenons un forum. Celui-ci est composé de sous-forums, et chacun de ces sous-forums contient une liste de topics. Enfin chaque topic concerne une liste de messages. Pour modéliser cela un petit schéma relationnel fait avec DBDesigner4.

 

mcd forum champs calculés

 

Se pose alors un problème de conception. En effet pour connaître et afficher le nombre de messages dans un topic, il me faut faire une sous requête avec un COUNT. De même si je veux l’auteur du topic, il me faut retrouver l’auteur du premier message du forum.

Typiquement quand je suis sur la page d’accueil de mon forum, je veux lister tous mes forums et en face de chacun d’eux, je veux afficher le nombre de messages et de topics ; ces 2 informations sont ce qu’on appelle des champs calculés.

Il se dessine alors plusieurs choix d’implantations, qu’ils soient au niveau de la structure ou de la requête.

  1. La requête complexe

    Une des premières approches et des plus justes, consiste à trouver nos champs calculés grâce à la requête, c’est donc le SGBD qui se charge de la phase de recherche/calcul. D’un point de vu normalisation et attribution des rôles on est optimum. Cependant il est clair que notre base de données va perdre du temps à calculer cette valeur. Cette perte de temps peut vite devenir handicapante pour note cas du forum.

    En effet, si j’appelle la liste des forums et que pour chaque forum je veux le nombre de message associé, il va me falloir une sous requêtes qui scanne chaque topic du forum et compte son nombre de message, donc un SUM(COUNT()).

    Avantages :

    • Les données calculés sont exactes car recalculées à chaque appel de la requête.
    • On n’a pas de redondance de données et la base est normalisée.

    Inconvénient :

    • Le temps de réponse de la requête est très ralenti.
  2. Le stockage des champs calculés

    Une autre approche consiste à stocker ces dits champs calculés en base de données pour pouvoir y accéder tout de suite. Pour cela, il suffit dans notre exemple de rajouter 2 champs à notre table Forum : ‘nombre_topic’ et ‘nombre_message’. Ainsi, à chaque ajout/suppression il suffira d’incrémenter ces champs.

    Heureusement pour nous, il existe un outils bien pratique commun à la plupart des SGDB : les triggers. On peut en effet programmer le fait, qu’à chaque ajout/modification/suppression d’un topic ou message, le SGBD se charge de mettre à jour les champs de la table Forum.

    Cependant, cela peut générer plusieurs désavantages. Lors de l’exécution du trigger, on place un verrou sur la table forum pour pouvoir la mette à jour. Ainsi toutes lectures au même moment est impossible. De plus on dé-normalise notre notre BDD, en stockant des valeurs calculés.

    Avantages :

    • Le temps d’accès est quasiment instantané.
    • Pas besoin de faire des requêtes complexes.

    Inconvénients

    • Lecture impossible pendant la mise à jour du trigger.
    • On dé-normalise la BDD.

Quelle méthode utiliser ?

Il n’y a malheureusement pas de réponse toute faite. Tout dépend de vos besoins. Cependant on peut distinguer deux besoins différents :

  1. Le stockage des champs calculés

    Ici on veut simplement stocker une informations, celle-ci ne doivent pas être critiques car elles ne sont pas recalculés à chaque appel même si un trigger et mis en place. De plus si vous avez très peu de requêtes de modification/insertion/création et beaucoup de requêtes de consultation, le trigger serra exécuter très rarement, et l’accès à vos données serra donc plus rapide.
    Dans le cas de notre forum, c’est cette solution qu’il faut utiliser. On créer/modifie/supprime rarement un forum, mais tout le monde va le consulter très souvent.

  2. L’appel à des sous requêtes

    Ici on recherche l’optimisation de la BDD. Quand on a des données sensibles et que l’on veut être sûr du total même avec plusieurs utilisateurs connectés à la BDD. Par exemple pour des valeurs comptables dans un logiciel de gestion. Notre base de données reste normalisée et reste maintenable pour le futur.

Conclusion

La partie conception d’une base de données est une partie importante d’un projet. Celle-ci est vouée à évoluer, il est donc primordial de bien la concevoir pour pouvoir la maintenir facilement. Si possible essayer de normaliser votre base de données au maximum, et ce n’est que dans certaines conditions et/ou circonstances qu’il faut la dé-normaliser.

 

Merci au site developpez.com sur lequel j’ai trouvé pas mal d’informations pour la rédaction de cet article.