Redondance dans une base de données ?

a marqué ce sujet comme résolu.

Bonjour,

Pour des besoins semi-professionnel, j’ai besoin de créer une petite base de données (quelques milliers d’entrées tout au plus). Je n’ai jamais fait ça, et je n’ai pas trop envie de devoir y revenir dans quelques mois, donc je me demandais comment le faire au mieux, et en écrivant sur un papier mes tables, je me suis retrouvé avec un certains nombre de cas de redondances. Je veux dire :

Projets

  • nom
  • personnes
  • date

Personnes

  • nom
  • compagnie
  • projets

compagnie

  • nom
  • personnes
  • projets

Vous voyez où je veux en venir. Si je procède de cette manière, ça me semble plus naturel. Mes requêtes seront sûrement aussi plus facile. Mais les informations sont dupliquées et pourraient être retrouvées.

Comment fait-on quand on fait les choses bien ?

Merci !

Je dois passer à côté d’un truc, mais le but d’une base de donnée n’est pas justement de ne pas avoir à faire ça ? Tu fais

  • nom
  • personnes
  • projets
  • compagnie

et c’est fini. L’efficacité est la même (et n’est pas importante avec quelques milliers d’entrée), et il n’y a plus de duplication.

Ensuite, selon ce que tu cherches, tu fais un classement par nom, personne… à l’utilisation (avec les requêtes qui vont bien). Mais tes données restent classées comme ça.

+1 -0

Merci pour les réponses !

@A-312

Je ne comprends pas, ça ne va pas encore rajouter de La redondance ?

@Gabbro

Tu ne passes sûrement à côté de rien, ce n’est clairement pas mon domaine. Il ne faut pas supposer que ma solution est même à moitié intelligente…

Par contre, tout mettre dans une table va générer une structure très complexe non ? Avec des listes de dictionnaires, ce genre de chose. Et encore de la redondance. Par exemple, si j’ai un pdf lié à un projet, mais plus de table "projets", il va falloir que je mette les info du pdf à chaque fois que le projet est mentionné dans l’entrée d’une personne, non ? Pareil pour les informations d’une compagnie qui sont identiques pour toutes les personnes y travaillant. Ou raté-je quelque chose ?

Mais si je comprends le sens général de ton commentaire, c’est d’éviter la duplication d’informations autant que possible et de laisser la logique du programme faire les liens. Correct ?

Moi ce qu’on m’a appris, c’est de respecter au moins la 2FN et si possible (généralement oui) la 3FN (ainsi qu’une autre 3FNBC).

+1 -0

La redondance c’est le fait dans une même table d’avoir 5 fois les mêmes groupes de données.

Si tu fais une unique table comme @Gabbro le propose, je vois quelques problèmes, si je prends personnes, la liste des problèmes seront :

  • personnes sera un champ TEXT, les noms des personnes seront séparés par des virgules ?
  • Si je veux mettre l’age, l’adresse et autres choses relié à la personne membre du projet ça sera compliqué ;
  • Si je veux chercher une personne précise le WHERE personne LIKE %machin% sera moins performant qu’avec une deuxième table.

Dans un premier temps c’est bien. Cependant, si je souhaite éviter la redondance dans une grosse structure, je dois créer des tables intelligemment et rajouter des liens entre elles.

+1 -0

Le fait de dénormaliser les infos sur la compagnie (i.e. les mettre dans la même table que les personnes) duplique l’information. Ça a de nombreux désavantages (si on veut renommer une compagnie, on doit modifier les lignes de chaque membre vs. une seule ligne, on risque d’avoir plusieurs versions désynchronisées de la même compagnie, etc.), et ça tue complètement l’intérêt d’utiliser un SGBD relationnel (i.e. "avec des tables") : si c’est pour faire ça, autant tout stocker en JSON dans une bête base key/value.

Pour le coup je rejoins @A-312 : quitte à utiliser un SGBDR, alors autant donner un ID à chaque compagnie, personne et projet, et créer des tables pour modéliser les relations entre elles, a fortiori s’il y a des relations "1 to N" entre compagnies et personnes, personnes et projets, compagnie et projets, et encore plus si ces relations peuvent du jour au lendemain devenir "N to N" (une personne peut bosser sur plusieurs projets et un projet est généralement mené par plusieurs personnes, etc.).

Après, ce qui devrait vraiment guider ce choix, ce sont les opérations que l’on compte faire sur cette base de données: que va faire l’application concrètement? Quel genre de requêtes ?

Pour résumer mon point de vue: il existe des cas où ce type de redondance est acceptable, mais à première vue ceci n’en est pas un.

+4 -0

Je pense que j’ai ma réponse, et que j’ai à peu près compris. Sauf le premier message de A-312, puisque si j’ai déjà la liste de personnes dans les tables projets et compagnie, je ne vois pas l’interêt de rajouter encore une table de correspondance.

Je me rends aussi compte, en demandant de l’aide quelque part où je suis totalement novice, que beaucoup de réponses demandent des recherches complémentaires pour être comprises, ne serait-ce que dû aux acronymes (2NF, 3NF, SGDBR, etc.). Je ne m’en plains pas, je demande de l’aide et c’est la moindre des choses que je soie disposé à utiliser un peu google, mais j’ai trouvé ça assez marquant.

Merci à tous, je vais donc retravailler ma structure avant de commencer pour éviter la duplication d’information autant que possible, et essayer de faire des tables 3NF.

SGBDR: Système de Gestion de Base de Données Relationnelle.

Sauf le premier message de A-312, puisque si j’ai déjà la liste de personnes dans les tables projets et compagnie, je ne vois pas l’interêt de rajouter encore une table de correspondance.

En fait, c’est discutable de lister les personnes telles quelles dans les tables projets etc. Il vaut mieux raisonner sur des IDs. Typiquement :

Personnes:

  • ID unique (ou person_id)
  • Nom
  • Prénom
  • [autres infos que tu peux vouloir stocker sur la personne elle-même]

Projet:

  • ID unique (ou project_id)
  • Nom du projet
  • [autres infos relatives au projet lui-même]

Compagnie:

  • ID unique (ou company_id)
  • Nom de la compagnie
  • [autres infos relatives à la compagnie]

Employés:

  • company_id
  • person_id
  • [autres infos, comme le poste occupé, l’ancienneté…]

Membres:

  • project_id
  • person_id
  • [autres infos, comme le rôle de la personne sur ce projet…]

Avec cette modélisation:

  • Un projet peut être mené par plusieurs personnes, de compagnies différentes.
  • Une personne peut travailler pour plusieurs compagnies à la fois.
  • Une personne peut travailler sur plusieurs projets à la fois.

Maintenant:

  • Si tu es sûr et certain qu’une personne ne peut appartenir qu’à une seule compagnie à la fois et que ça ne changera jamais, tu peux supprimer la table Employés et rajouter un company_id directement dans la table Personnes.

Le fait de travailler avec des ID, ça permet notamment:

  • que deux personnes puissent avoir le même nom,
  • d’avoir des relations robustes qui ne reposent pas, par exemple, sur la casse d’une chaîne de caractères ("Michel DUBOIS" vs. "Michel Dubois"…)
  • s’il y a une typo ou autre dans le nom de la personne, tu n’as qu’une seule ligne dans la table Personnes à modifier pour la corriger, ce qui est largement préférable à un UPDATE sur toutes les lignes de toutes les tables avec le nom de la personne.

D’une façon générale, il vaut mieux avoir une très, très bonne raison pour dénormaliser (dupliquer) une information dans une base de données. En général c’est pour répondre à des soucis de performances et/ou de grosse volumétrie (vulgairement, des problématiques de Big Data). Un exemple typique de mauvaise raison serait par exemple « ça rend les requêtes SQL plus faciles à écrire ».

+2 -0

Bonjour,

Pour des besoins semi-professionnel, j’ai besoin de créer une petite base de données (quelques milliers d’entrées tout au plus). Je n’ai jamais fait ça, et je n’ai pas trop envie de devoir y revenir dans quelques mois, donc je me demandais comment le faire au mieux, […]> Comment fait-on quand on fait les choses bien ?

Merci !

Rockaround

Attention : si ta base de données, et les applis qui s’en servent, fait le boulot bien, on te félicitera et on te demandera de rajouter un petit truc, puis un autre, puis un autre, etc.

Donc, tu vas y revenir, de toutes façons.

Je pensais que tu avais les bases théoriques ou l'expérience du terrain pour comprendre mon premier message vu que ta réponse était assez complète et respecter les attentes d’une base de donnée relationnelle, je vais donc illustrer mes propos :

Je suis A-312, je participe à plusieurs projets zds-site, avion-electrique et zmd. Sur le zds-site, on compte notamment artragis en membre du projet. On identifie aussi deux compagnies zestedesavoir (pour zds-site et zmd) et airbus (pour avion-electrique et zmd ils aiment bien écrire en zmd leur fiche technique).

Donc on a :

IdProjet Nom
1 zds-site
2 avion-electrique
3 zmd
Projet
IdMembre Nom
1 A-312
2 artragis
Personne
IdEntreprise Nom
1 zestedesavoir
2 airbus
Entreprise

Comment arrives-tu à savoir qu’un membre participe à un projet ou qu’une entreprise est lié à un projet ?

Grâce à des tables qui relient chacune d’elles ! ;)

IdProjet IdMembre
1 1
1 2
2 1
3 1

Merci pour les réponses ! J’ai essayé de les prendre en compte pour refaire (assez fortement) mes tables, et au lieu de vous donner des bribes d’informations, je vous copie la nouvelle version (purgée de ce que je ne peux pas montrer, et de ce que j’ai pu oublier, mais ça ne change pas le concept). J’ai donc enlevé les liens entre tables, et à la place, j’en ai rajouté qui ne s’occuperont que de la correspondance (en gris). (FOA=Funding opportunity announcement)

image.png
image.png

Est-ce mieux ? Le champ "winner" peut être une personne ou une comapgnie, donc je ne l’ai pas sorti, vu que je ne voyais pas directement comment faire une table de correspondance.

Certains champs seront des listes (location pour les entreprises) voire des listes de listes/tuples (timelines=[date,event]). Faut-il que je le prenne en compte quand je crée mes tables ?

Merci encore !

Donne des noms de variables plus explicites : IDCompany, IDPeople … NameCompany, NameProject …

Si demain le projet 'Zeste de Savoir' est rebaptisé 'Zeste-de-Savoir’, pas de problème, il y a uniquement un enregistrement à modifier dans une seule table.

Si tu veux gérer des dates (telle personne participe à tel projet sur telle période), tu as juste à ajouter 2 colonnes date_début et date_fin dans la table people_project…

C’est robuste, et évolutif.

Je te conseille de mettre le nom de l’élément après Id c’est très pratique pour éviter de se tromper dans une jointure ou quand tu fais les liens entre clés primaires et clés secondaires. C’est quoi en gris ?

Mettre l’id du winner est peut être plus adapté.

Est-ce que tu pourrais nous en dire plus sur ce que doit faire ton application ?

Par exemple, tu parles de champs multivalués (avec des listes de tuples), ok, pourquoi pas, mais en vrai ça dépend très fortement de ton appli : si tu as des évènements datés, et qu’à un moment donné ton appli a besoin de pouvoir filtrer les évènements sur une période, tu vas vouloir pouvoir l’exprimer dans une requête SQL et donc simplifier ça en ayant une table pour les évènements qui différentie une date de début et une date de fin. En généralisant un peu, j’aurais envie de dire qu’il ne faut pas avoir peur d’avoir "trop" de tables parce que c’est moins chiant à gérer que de se rendre compte que tu n’en as pas assez.

Au final, c’est vraiment ce que l’application doit faire qui va dicter la meilleure façon de représenter les données.

+0 -0

L’idée c’est de structurer un peu un programme de recherche industriel ainsi que de faciliter le partage d’information. On finance actuellement peu ou prou 25 élèves/programmes, et plus ou moins personne ne connait, pas seulement les détails, mais même les grandes lignes de tous ces programmes. Il y avait quelqu’un, qui a pris sa retraite.

Additionnellement, il y a des centaines de programmes pour lesquels, sans financer, on est impliqués et on voudrait bien suivre d’un peu plus près. Quelque chose qui se fait beaucoup c’est les "one-slide summary", mais ça reste très superficiel.

L’idée de la base de données, c’est de créer un moyen de facilement savoir ce qu’il se passe et où. "Tiens, j’aimerais bien voir tout ce qu’il se passe à LANL." Projet Y? Je clique et je vois qui travaille dessus, un résumé, les productions, les financements, les dates clés, etc. Je vois que Docteur Y y travaille, et je clique dessus. Et je peux voir une liste de ses affiliations actuelles et passées, de ses projets, de ses intêrets, ses publciations, etc. Si je veux faire des "one-slide summaries" pour un projet entier, j’ai juste à écrire une ligne de commande, etc.

C’est pour ça que je l’avais présenté comme "semi-professionnel". Mon boulot, c’est plutôt les programmes, mais je pense que si j’arrive à avoir une POC sur mon temps libre, je pourrais intéresser les gens ici que ça peut être utile. Surtout quand on dépense des millions sur ces projets, si on peut gagner un peu en efficacité, ça vaut surement le coup.

J’ai déjà changé toutes les timelines par une nouvelle table:

Events

  • IDevent
  • reftable <- pour dire si c’est entreprise, projet, personne, etc
  • refID
  • dates
  • summary

J’ai aussi créé une table similaire pour winners.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte