bonjour,
je récupère une base de donnée qui m'interroge au niveau de certains aspect de sa conceptions. notamment la gestion des données de références.
Les données de références (civilité, pays, professions, ...) sont toutes gérés par une table "référence" unique de la forme suivante :
1 2 3 4 5 6 7 8 9 10 11 12 13
| table reference
- colonne : varchar 30, PK
- id : int, PK
- value : varchar 100.
cette table contient par exemple :
colonne id value
civilité 1 Mr
civilité 2 Mme
civilité 3 Mlle
pays 1 France
pays 2 Grande Bretagne
etc... |
L'application permet à l'utilisateur par un IHM très simple d'ajouter, supprimer, modifier les données de cette table. c'est assez pratique, la configuration de l'application est du coup très simple.
dans le reste du modèle les données de référence sont donc recherché dans cette table mais sans contraintes d'intégrité référentielle. par exemple
1 2 3 4 5
| table personne :
- nom : varchar 30
- civilité_id : id de la table référence ou colonne = "civilité"
- pays_id : id de la table référence ou colonne = "pays"
- etc... |
mon problème est le suivant (mis à part que je trouve ça très laid et in-maintenable) :
Comment garantir l'intégrité référentielle de ces relations "conditionnelles". en effet, tel que décris ci dessus, rien ne garantit que civilité_id référence effectivement une civilité et non un pays... et je me retrouve à devoir gérer ces problèmes d'intégrité dans la couche métier.
je vois plusieurs solutions mais qui ont toutes leurs problèmes :
1) re-normaliser le modèle : créer une table Pays et une table civilité, faire pointer toutes mes relations sur ces tables.
- c'est un gros boulot qui casse tous le modèle (et donc l'application)
- c'est finalement très pratique d'avoir toutes les données de références dans la même table. Cela permet d'avoir une IHM d'édition des données de références très simple. à l'inverse la renormalisation m'oblige à faire un code spécifique d'IHM pour Pays, civilité etc...
2) mettre les deux PK de la table relation en FK de la table relationnée... i.e. :
1 2 3 4 5 6
| table personne :
- nom : varchar 30
- civilité_colonne : colonne de la table de référence = "civilité"
- civilité_id : id de la table référence
- pays_colonne : colonne de la table de référence = "pays"
- pays_id : id de la table référence |
- c'est la solution que j'ai choisi jusque la, mais vu le nombre de type de données de référence auquel j'ai affaire, je me retrouve avec un nombre doublé de FK dans mes tables, de plus la colonne civilité_colonne (par exemple) contient toujours "civilité" (idem pour pays et les autres), ce qui me semble absurde.
ce problème me chagrine foncièrement à m'emmena à penser à une troisième solutions :
3) utilisations de vues et relation sur la vue. c'est à dire :
create vue PAYS AS select id, value from reference when colonne ="pays"
et rajouter une contrainte référentielle sur la table personne pointant sur l'id de la vue PAYS. du coup je bénéficierais du meilleurs des deux mondes : gestion unifiée des données de référence, lisibilité et maintenabilité de mon modèle, intégrité référentielle.
- mais est t'il seulement possible de créer des relations sur des vues (je suis sous postgres).
- est ce que je ne me retrouverais pas avec des problèmes de performance à la moindre jointure.
- est-ce que ce modèle est portable sur d'autre BD que la mienne ?
J'avoue que je suis perplexe, cette question m'a l'air presque classique et pourtant je ne vois pas de manière "élégante" de la résoudre. Peut être y à t'il une solution plus simple...
Quelqu'un aurais t'il un avis sur cette question?
je serais curieux d'avoir vos avis.
Merci
Patrice.
Partager