Mauvaises pratiques dans la conception de bases de données : faites-vous ces erreurs ?
Publié: 2022-03-11Chaque fois que vous, en tant que développeur, êtes chargé d'une tâche basée sur du code existant, vous devez faire face à de nombreux défis. L'un de ces défis, le plus souvent le plus exigeant, consiste à comprendre le modèle de données d'une application.
Vous êtes normalement confronté à des tables, des vues, des colonnes, des valeurs, des procédures stockées, des fonctions, des contraintes et des déclencheurs déroutants qui mettent beaucoup de temps à vous comprendre. Et, une fois qu'ils le font, vous commencez à remarquer de nombreuses façons d'améliorer et de tirer parti des informations stockées.
Si vous êtes un développeur expérimenté, il y a de fortes chances que vous remarquiez également des choses qui auraient pu être mieux faites au début, c'est-à-dire des défauts de conception.
Dans cet article, vous découvrirez certaines des mauvaises pratiques courantes de conception de bases de données, pourquoi elles sont mauvaises et comment vous pouvez les éviter.
Mauvaise pratique n°1 : ignorer la finalité des données
Les données sont stockées pour être consommées plus tard, et l'objectif est toujours de les stocker et de les récupérer de la manière la plus efficace. Pour y parvenir, le concepteur de base de données doit savoir à l'avance ce que les données vont représenter, comment vont-elles être acquises et à quel rythme, quel sera son volume opérationnel (c'est-à-dire quelle quantité de données est attendue), et enfin , comment il va être utilisé.
Par exemple, un système d'information industriel où les données sont collectées manuellement chaque jour n'aura pas le même modèle de données qu'un système industriel où les informations sont générées en temps réel. Pourquoi? Parce qu'il est très différent de gérer quelques centaines ou milliers d'enregistrements par mois par rapport à la gestion de millions d'entre eux au cours de la même période. Des considérations particulières doivent être prises par les concepteurs afin de maintenir l'efficacité et la convivialité de la base de données, si les volumes de données doivent être importants.
Mais, bien sûr, le volume de données n'est pas le seul aspect à prendre en compte, car l'objectif des données affecte également le niveau de normalisation, la structure des données, la taille des enregistrements et la mise en œuvre générale de l'ensemble du système.
Par conséquent, bien connaître l'objectif du système de données que vous allez créer conduit à des considérations dans le choix du moteur de base de données, des entités à concevoir, de la taille et du format des enregistrements et des politiques de gestion du moteur de base de données.
Ignorer ces objectifs conduira à des conceptions erronées dans leurs bases, bien que structurellement et mathématiquement correctes.
Mauvaise pratique n°2 : Mauvaise normalisation
La conception d'une base de données n'est pas une tâche déterministe ; deux concepteurs de bases de données peuvent suivre toutes les règles et principes de normalisation pour un problème donné et, dans la plupart des cas, ils généreront des mises en page de données différentes. Ceci est inhérent à la nature créative du génie logiciel. Cependant, il existe certaines techniques d'analyse qui ont du sens dans chaque cas, et les suivre est le meilleur moyen d'obtenir une base de données qui fonctionne au mieux.
Malgré cela, nous sommes souvent confrontés à des bases de données qui ont été conçues à la volée sans suivre les règles les plus élémentaires de normalisation. Nous devons être clairs là-dessus : chaque base de données doit, au moins, être normalisée à la troisième forme normale, car c'est la mise en page qui représentera le mieux vos entités, et dont les performances seront le mieux équilibrées entre l'interrogation et l'insertion-mise à jour-suppression d'enregistrements. .
Si vous tombez sur des tables qui ne sont pas conformes à 3NF, 2NF ou même 1NF, envisagez de reconcevoir ces tables. L'effort que vous y investissez sera payant à très court terme.
Mauvaise pratique n°3 : la redondance
Très lié au point précédent, puisque l'un des objectifs de la normalisation est de le réduire, la redondance est une autre mauvaise pratique qui apparaît assez souvent.
Les champs et les tables redondants sont un cauchemar pour les développeurs, car ils nécessitent une logique métier pour maintenir à jour de nombreuses versions des mêmes informations. Il s'agit d'une surcharge qui peut être évitée si les règles de normalisation sont suivies à la lettre. Même si parfois la redondance peut sembler nécessaire, elle ne doit être utilisée que dans des cas bien précis et être clairement documentée pour être prise en compte dans les développements futurs.
Les effets néfastes typiques de la redondance sont une augmentation inutile de la taille de la base de données, des données sujettes à des incohérences et une diminution de l'efficacité de la base de données, mais, plus important encore, cela peut entraîner une corruption des données.
Mauvaise pratique n°4 : mauvaise intégrité référentielle (contraintes)
L'intégrité référentielle est l'un des outils les plus précieux que les moteurs de base de données fournissent pour maintenir la qualité des données à son meilleur. Si aucune contrainte ou très peu de contraintes sont mises en œuvre dès la phase de conception, l'intégrité des données devra reposer entièrement sur la logique métier, ce qui la rendra vulnérable à l'erreur humaine.
Mauvaise pratique n° 5 : ne pas profiter des fonctionnalités du moteur de base de données
Lorsque vous utilisez un moteur de base de données (DBE), vous disposez d'un logiciel puissant pour vos tâches de traitement des données qui simplifiera le développement logiciel et garantira que les informations sont toujours correctes, sûres et utilisables. Un DBE fournit des services tels que :
- Vues qui offrent un moyen rapide et efficace d'examiner vos données, en les dénormalisant généralement à des fins de requête sans perdre l'exactitude des données.
- Des index qui permettent d'accélérer les requêtes sur les tables.
- Fonctions agrégées qui aident à analyser les informations sans programmation.
- Transactions ou blocs de phrases modifiant les données qui sont toutes exécutées et validées ou annulées (annulées) si quelque chose d'inattendu se produit, gardant ainsi les informations dans un état perpétuellement correct.
- Des verrous qui gardent les données sûres et correctes pendant l'exécution des transactions.
- Procédures stockées qui fournissent des fonctionnalités de programmation pour permettre des tâches de gestion de données complexes.
- Des fonctions qui permettent des calculs sophistiqués et des transformations de données.
- Des contraintes qui permettent de garantir l'exactitude des données et d'éviter les erreurs.
- Déclencheurs qui aident à automatiser les actions lorsque des événements se produisent sur les données.
- Optimiseur de commande (planificateur d'exécution) qui s'exécute sous le capot, garantissant que chaque phrase est exécutée au mieux et conservant les plans d'exécution pour les occasions futures. C'est l'une des meilleures raisons d'utiliser des vues, des procédures stockées et des fonctions, puisque leurs plans d'exécution sont conservés en permanence dans le DBE.
Ne pas connaître ou ignorer ces capacités entraînera le développement sur une voie extrêmement incertaine et sûrement vers des bogues et des problèmes futurs.

Mauvaise pratique n°6 : clés primaires composites
C'est en quelque sorte un point controversé, car de nombreux concepteurs de bases de données parlent aujourd'hui d'utiliser un champ généré automatiquement par un ID entier comme clé primaire au lieu d'un champ composite défini par la combinaison de deux champs ou plus. Ceci est actuellement défini comme la «meilleure pratique» et, personnellement, j'ai tendance à être d'accord avec cela.
Cependant, ce n'est qu'une convention et, bien sûr, les DBE permettent la définition de clés primaires composites, ce que de nombreux concepteurs pensent être inévitable. Par conséquent, comme pour la redondance, les clés primaires composites sont une décision de conception.
Attention, cependant, si votre table avec une clé primaire composite devrait contenir des millions de lignes, l'index contrôlant la clé composite peut croître jusqu'à un point où les performances de l'opération CRUD sont très dégradées. Dans ce cas, il est préférable d'utiliser une simple clé primaire d'ID entier dont l'index sera suffisamment compact et d'établir les contraintes DBE nécessaires pour maintenir l'unicité.
Mauvaise pratique n°7 : Mauvaise indexation
Parfois, vous aurez une table que vous devrez interroger sur plusieurs colonnes. Au fur et à mesure que la table grandit, vous remarquerez que les SELECT sur ces colonnes ralentissent. Si la table est assez grande, vous penserez, logiquement, à créer un index sur chaque colonne que vous utilisez pour accéder à cette table pour constater presque immédiatement que les performances des SELECT s'améliorent mais que les INSERT, UPDATE et DELETE chutent. Ceci, bien sûr, est dû au fait que les index doivent être maintenus synchronisés avec la table, ce qui signifie une surcharge massive pour le DBE. Il s'agit d'un cas typique de surindexation que vous pouvez résoudre de plusieurs manières ; par exemple, avoir un seul index sur toutes les colonnes différentes de la clé primaire que vous utilisez pour interroger la table, classer ces colonnes de la plus utilisée à la moins utilisée peut offrir de meilleures performances dans toutes les opérations CRUD qu'un index par colonne.
D'autre part, avoir une table sans index sur les colonnes utilisées pour l'interroger entraînera, comme nous le savons tous, de mauvaises performances sur les SELECT.
De plus, l'efficacité de l'index dépend parfois du type de colonne ; les index sur les colonnes INT affichent les meilleures performances possibles, mais les index sur VARCHAR, DATE ou DECIMAL (si cela a du sens) ne sont pas aussi efficaces. Cette considération peut même conduire à reconcevoir des tables auxquelles il faut accéder avec la meilleure efficacité possible.
Par conséquent, l'indexation est toujours une décision délicate, car trop d'indexation peut être aussi mauvaise que trop peu et parce que le type de données des colonnes à indexer a une grande influence sur le résultat final.
Mauvaise pratique n° 8 : Mauvaises conventions de nommage
C'est quelque chose avec lequel les programmeurs ont toujours du mal lorsqu'ils sont confrontés à une base de données existante : comprendre quelles informations y sont stockées par les noms de tables et de colonnes car, souvent, il n'y a pas d'autre moyen.
Le nom de la table doit décrire l'entité qu'elle contient et chaque nom de colonne doit décrire l'élément d'information qu'il représente. C'est facile, mais cela commence à être compliqué lorsque les tables doivent être liées les unes aux autres. Les noms commencent à devenir désordonnés et, pire, s'il existe des conventions de dénomination confuses avec des normes illogiques (comme, par exemple, "le nom de la colonne doit comporter 8 caractères ou moins"). La conséquence finale est que la base de données devient illisible.
Par conséquent, une convention de nommage est toujours nécessaire si la base de données doit durer et évoluer avec l'application qu'elle supporte, et voici quelques lignes directrices pour en établir une succincte, simple et lisible :
- Aucune limitation sur la taille du nom de table ou de colonne. Il est préférable d'avoir un nom descriptif plutôt qu'un acronyme dont personne ne se souvient ou ne comprend.
- Les noms qui sont égaux ont la même signification. Évitez d'avoir des champs qui ont le même nom mais avec des types ou des significations différents ; ce sera déroutant tôt ou tard.
- Sauf si nécessaire, ne soyez pas redondant. Par exemple, dans le tableau "Item", il n'est pas nécessaire d'avoir des colonnes telles que "ItemName", "PriceOfItem" ou des noms similaires ; "Nom" et "Prix" suffisent.
- Méfiez-vous des mots réservés DBE. Si une colonne doit s'appeler "Index", qui est un mot réservé SQL, essayez d'en utiliser un autre comme "IndexNumber".
- Si vous vous en tenez à la règle de la clé primaire simple (seul entier généré automatiquement), nommez-le "Id" dans chaque table.
- En cas de jointure à une autre table, définissez la clé étrangère nécessaire sous la forme d'un entier, nommé "Id" suivi du nom de la table jointe (par exemple, IdItem).
- Si vous nommez des contraintes, utilisez un préfixe décrivant la contrainte (par exemple, "PK" ou "FK"), suivi du nom de la table ou des tables impliquées. Bien sûr, l'utilisation de traits de soulignement ("_") avec parcimonie aide à rendre les choses plus lisibles.
- Pour nommer les index, utilisez le préfixe "IDX" suivi du nom de la table et de la colonne ou des colonnes de l'index. Utilisez également "UNIQUE" comme préfixe ou suffixe si l'index est unique et soulignez si nécessaire.
Il existe de nombreuses directives de dénomination de bases de données sur Internet qui éclaireront davantage cet aspect très important de la conception de bases de données, mais avec ces principes de base, vous pouvez au moins accéder à une base de données lisible. Ce qui est important ici, ce n'est pas la taille ou la complexité de vos directives de nommage, mais votre cohérence à les suivre !
Quelques remarques finales
La conception de bases de données est une combinaison de connaissances et d'expérience ; l'industrie du logiciel a beaucoup évolué depuis ses débuts. Heureusement, il existe suffisamment de connaissances disponibles pour aider les concepteurs de bases de données à obtenir les meilleurs résultats.
Il existe de bonnes directives de conception de bases de données partout sur Internet ainsi que de mauvaises pratiques et des choses à éviter dans la conception de bases de données. Faites votre choix et respectez-le.
Et, n'oubliez pas, ce n'est que par l'expérimentation, les erreurs et les succès que vous apprenez, alors allez-y et commencez maintenant.