Enregistrer plutot l'id d'un champ ou le libellé ?

Eléphanteau du PHP | 40 Messages

18 juin 2006, 09:15

Bonjour à tous,

Je m'explique : je souhaite intégrer la notion de 'commercial' dans mon application. L'utilisateur de l'application a la possibilité de créer, de modifier et de supprimer des commerciaux dans une table et de les affecter finalement à certains clients.

Stocker l'id du commercial dans la table client parait le plus évident (gain de place, de rapidité d'exécution de requete, etc...) mais est-ce pertinent si l'utilisateur effectue des modifications dans la table 'commercial', il risque de ne plus y avoir de correspondance. Est-ce qu'il est plus judicieux dans ce cas là de stocker directement le nom complet du commercial, même si cela alourdit la base et, je suppose, les requetes ?

Merci de vos contributions éclairées :P

Bon dimanche à tous,

JM

Eléphant du PHP | 140 Messages

18 juin 2006, 09:55

De maniere generale il faut toujours stocker la clef primaire d'un champ. :D Ton intuition est donc la bonne.

Eléphant du PHP | 332 Messages

18 juin 2006, 20:02

Attention : pas forcément.

Les commerciaux sont des gens qui ont un turn-over important. Que se passe t'il quand ils quittent la boîte ? si tu supprimes l'enregistrement, tu risques de perdre tout l'historique ... Mais on ne peut pas non plus laisser un commercial accéder à une application d'une boîte qu'il a quitté.

Un risque en ne stockant que l'id, c'est que les utilisateurs se servent du même compte pour ne rien perdre. Par exemple, quand le commercial id n°5 Jean Dupont quitte la boîte, on réaffecte son id n°5 à son remplaçant Jacques Durand (cas vécu : ça évite de refaire toute la réaffectation du portefeuille client).
Si le but, c'est de garder l'historique de la fonction "commercial service X" ou "commercial service Y", alors sers-toi de l'ID
Si le but, c'est de garder un historique nominatif, alors sers-toi du nom.

Bref, avant de répondre dans un sens ou dans l'autre, il faut surtout prendre en compte les contraintes fonctionnelles liées au métier et au but de l'application. A quoi sert le lien commercial-client ? Comment il évolue ? Que se passe t'il si un commercial s'en va ou change de portefeuille client ? Qu'est-ce qu'on veut garder ? Qu'est-ce qu'on peut oublier ? ...
Et ça, c'est aux commerciaux de répondre (ou du moins au directeur commercial) à partir des scénarios possibles que tu leur présenteras.

Après, tu pourras envisager une réponse.

Eléphant du PHP | 82 Messages

18 juin 2006, 23:00

Salut,

A mon avis la clé primaire est le mieux... Si le problème est la réaffectation d'un ancien ID, l'utilisation du auto_increment resoudra le problème.

Si tu souhaites que certains n'accèdent plus, tu créé un booléen dans ta table de commerciaux pour savoir si ils sont actifs...

Eléphanteau du PHP | 40 Messages

18 juin 2006, 23:30

merci à tous pour vos avis très interessants, c'est très sympa. En fait, l'application est relativement simple puisque l'utilisateur est en principe une seule et même personne (il s'agit d'un petit module de gestion commerciale). En fait, j'étais plutot focalisé sur l'intégrité de la base. Par exemple, je valide 3 devis au nom d'un commercial (id(2) - Emile Dupond) . 2 mois après, on modifie le libellé du commercial en 'Jean Durand'. 6 mois plus tard, je fais une recherche sur le nombre de devis validés par Jean Durand. Si je fais une requete d'après l'Id(2), mon résultat sera faussé.

Voilà où en est ma réflexion. J'ai eu la même interrogation lorsque j'ai créé mes tables de devis. Un exemple tout bete : j'ai une table avec les taux de TVA. Quand je créé un devis, j'enregistre 'en dur' dans la table 'devis' le taux de tva (et pas l'id correspondant) car si l'utilisateur modifie le taux de TVA de 19,6 à 20,6 ou bien tout simplement le supprime, tout est faussé :?

Encore merci à vous et bonne soirée,

Jean-Marc

Eléphant du PHP | 82 Messages

19 juin 2006, 00:26

Salut,


tes résultats ne seont pas faussés puisque les enregistrements suivants n'auront pas la même clé primaire.

Si Tu as 2 enregistrements dans ta base et que tu supprimes le N°2 le prochain enregistrement aura le n°3... Donc les données ne se mélangeront pas ....


++(bonne nuit)

Eléphanteau du PHP | 40 Messages

19 juin 2006, 08:55

hmm, je ne suis pas forcément d'accord. Imagines, pour reprendre le cas de la TVA (mais ça marche aussi avec les commerciaux), que l'utilisateur ait à sa disposition un formulaire pour ajouter/modifier les taux. Il choisi de modifier un taux. Celui-ci garde le même id mais sa valeur change (passe de 19.6 à 20.6).


@++

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

19 juin 2006, 10:18

D'une manière générale, une base bien concue limite au maximum la redondance des données. De part ce fait, il vaut mieux stocker les commerciaux dans une table et les les clients dans une autre et que le lien entre les clients et les commerciaux soit juste l'id.

En ce qui concerne la mise à jour de l'id, il y a plusieurs cas de figures qui se présentent :
si il ne peut y avoir qu'un seul commercial par client : tu stocke l'id du commercial dans le client
si il peut y avoir plusieurs commerciaux par client : une table intermediaire qui associe un id_client et un id_commercial
tu doit garder un historique des commerciaux associés aux client : une table temporaire comme ci dessus mais avec une notion de lien actif ou non pour connaitre le commercial actuel du client
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 332 Messages

19 juin 2006, 10:40

Attention à bien distinguer ce que tu penses que l'utilisateur va faire et ce qu'il va faire réellement.

Le taux de TVA est un exemple parfait. Tu crées une page où tu permets que l'utilisateur crée de nouveaux taux ou les modifie ... Mais s'il s'amuse à modifier le taux n°4 de 19.6 à 20.6, eh bien, c'est le souk dans ta comptabilité.

Le taux de TVA est le cas par excellence où il faut stocker la valeur avec la facture et surtout pas l'id. Si jamais le taux change (ce sont des taux imposés par la loi) et qu'il y a des avoirs à faire, des calculs de TVA à reverser ou à recevoir, ... il est IMPERATIF d'avoir le taux au moment où la facture a été établie. Il est inimaginable qu'il puisse y avoir le moindre soupçon que l'utilisateur ait pu modifier le taux. Donc laisser la possibilité à l'utilisateur de pouvoir modifier le taux (même s'il te jure qu'il ne le fera jamais) est une faille majeure de l'application (sauf si tu emploies la solution décrite un peu plus bas).

Je dirais même que nul administrateur de base n'est à l'abri d'une mauvaise manipulation : un moment d'inattention et hop ! effacée la table des taux de TVA. A priori, elle n'est pas difficile à reconstituer, et puis il y a des sauvegardes, ... Oui, mais c'est TOUJOURS dans ces cas là que la bande est illisible, qu'il faut sortir les comptes pour dans 2 heures et qu'on se pose des questions si le taux n°4, c'est 19.6 ou 20.6 qui a été modifié en 2012 ? et le taux n°3, ce n'était pas un taux transitoire qui n'a existé que pendant 3 mois en 2007 ? ... Bref, l'horreur !

Truc employé par beaucoup de personnes qui font des applis de gestion commerciale, de facturation, ... On crée une table de taux de TVA (id, taux), mais avec un id saisi à la main par l'utilisateur (pas de champ autoincrément) ou, encore mieux, calculé par le programme : l'id est la valeur rendue entière du taux décimal ! exemple : id=196 pour taux 19.6 ; id 55 pour taux 5.5 ... Il n'y a pas de modification ni de suppression de cette table, il n'y a que des ajouts. Si l'utilisateur veut modifier le 19.6 en 20.6, cela ajoute un taux id 206. Et on résoud tout les problèmes évoqués plus haut puisqu'on stocke l'id, mais que cet id indique la valeur. Il reste bien le cas où tu aurais un taux à 1.96% et un taux à 19.6%, mais je te laisse trouver une solution :)

Concernant l'historique des devis, si tu veux savoir 3 mois après que c'est jacques durand qui a établi le devis, tu n'as pas d'autre choix que de stocker le nom+prénom (ou à la rigueur des initiales). De la même manière que ci-dessus, il y a ce que tu penses que les utilisateurs feront (un nouveau commercial arrive, on crée un nouveau compte) et il y a ce qu'ils feront (l'ancien commercial file ses codes d'accès au nouveau et celui-ci fait juste la modif de ses noms et prénoms). Question : et pourquoi pas stocker les deux ?
- l'id permettra au commercial de retrouver ses devis (et d'ignorer ceux du voisin)
- le nom+prénom permettra de savoir qui a signé le devis ?

Restent les contraintes techniques : problème de place, d'indexation, ... sans vouloir être "dépensier" en ressources, est-ce que c'est un VRAI problème ou est-ce que c'est juste pour la satisfaction intellectuelle ?
Est-ce qu'il y a des centaines de milliers de devis ? des milliers de commerciaux ? Est-ce que tu as disque dur si petit que ça ?

Tu parles d'intégrité de la base : c'est vrai que c'est un des principes de base de SQL : l'intégrité de la base, la non-redondance de l'information, ... Mais il y a des moments où il faut savoir ne pas suivre les règles théoriques à condition de savoir qu'on fait un truc "interdit" et à condition de savoir pourquoi on le fait. Si ton appli est codée, testée et documentée correctement, il n'y aura pas de problème.

Encore une fois, oui, en théorie, il faut stocker l'id du commercial et gérer une table des commerciaux avec des valeurs actifs/inactifs et compter sur la discipline des gens pour gérer proprement ces comptes d'accès. Mais ça, c'est la théorie et en matière de gestion de sécurité (code, mots de passe, comptes d'accès) l'expérience montre malheureusement que les gens vont au plus court. Donc, il ne faut absolument pas compter sur une auto-discipline qui fera que le compte Dupont sera désactivé, puis le compte Durant créé. Avec beaucoup de bol, le nouveau commercial changera le mot de passe que lui a filé l'ancien ; dans la plupart des cas, il ne le fera pas et l'ancien commercial pourra encore pendant des mois accéder aux devis via Internet (là aussi, je parle hélas d'expérience).

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

19 juin 2006, 11:02

:shock: il y a des choses qui me surprennent beacoup dans ce que tu dit :
- un id devrait être entièrement transparent et donc en aucun cas ce devrait être à l'utilisateur de le saisir, même pour que cet id soit parlant vis-a-vis de sa valeur.
- une application basée sur une base de données correctement modélisée permet un développement plus rapide, une maintenance aisée et un transfert de compétence facilité donc, pour aller au plus court, il vaut mieux prendre le temps de correctement modéliser une base afin de réduire les temps de développement et de maintenance
- le contenu d'un id ne devrait pas être modifié de cette manière. Exemple : pour la sécurité sociale, il est possible de modifier un adhérent pour changer son adresse ou son nom marital, mais il n'est pas possible de changer la personne ayant ce numéro. Et quand cette personne laisse vacant ce numéro, il n'est pas réattribué.
- on ne parle pas que le place utilisée en parlant de redondance. On parle également de facilité d'utilisation. Pour un SGBD, il est plus facile d'executer une recherche sur un id numérique que sur une chaine de caractères.

Donc, pour créer une appli stable et ayant un avenir, je te conseille de faire une table commercial dans laquelle tout nouveau commercial sera ajouté et si un client change de commercial, tu n'as qu'a modifier l'id du commercial de ce client.

Si tu veux concerver un historiques des commerciaux d'un client, il te suffit de suivre ce que je t'ai dit dans le message plus haut
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 332 Messages

19 juin 2006, 11:53

- un id devrait être entièrement transparent et donc en aucun cas ce devrait être à l'utilisateur de le saisir, même pour que cet id soit parlant vis-a-vis de sa valeur.
J'ai indiqué qu'il vallait mieux que ce soit le programme qui calcule l'id plutôt que l'utilisateur qui le fasse. Maintenant, s'agissant des taux de TVA qui sont modifiés une fois tous les 5 ou 10 ans, il faut se poser la question de savoir si c'est rentable de développer du code qui calcule l'id en fonction du taux ou s'il ne vaut pas mieux que ce soit "l'informaticien" qui se charge de créer le taux et son id à la main. C'est juste une question de rentabilité : de toute façon, même si tu crées cette fonction de calcul automatique, le jour où il faudra créer un taux, comme aucun utilisateur ne connaîtra cette fonction parce qu'elle n'est jamais utilisée, ils te téléphoneront pour que tu le fasses. Ne pas oublier qu'un utilisateur ne lit jamais un mode d'emploi, qu'il ne connaît que les 3 fonctions qu'il utilise tous les jours et que pour le reste, il ne cherche même pas à savoir si ça existe : il téléphone. :)
- une application basée sur une base de données correctement modélisée permet un développement plus rapide, une maintenance aisée et un transfert de compétence facilité donc, pour aller au plus court, il vaut mieux prendre le temps de correctement modéliser une base afin de réduire les temps de développement et de maintenance
Je suis complètement d'accord avec toi. C'est exactement ce que j'ai dit hier. Mais tu as beau avoir modélisé comme un dieu, il faut maintenant ajouter le facteur humain : qu'est-ce que va faire l'utilisateur de ton application ? Je parle juste d'expérience (j'ai souvent travaillé sur des applis pour des commerciaux) : tu modélises tout comme il faut, mais quand Dupont quitte la boîte, il file ses codes à Durand qui continue avec les mêmes qui à son tour les refilera à Dubois et tu es dans la merdouille car le directeur commercial va vouloir sortir l'historique de qu'a fait Dupont il y a 5 ans.
- le contenu d'un id ne devrait pas être modifié de cette manière. Exemple : pour la sécurité sociale, il est possible de modifier un adhérent pour changer son adresse ou son nom marital, mais il n'est pas possible de changer la personne ayant ce numéro. Et quand cette personne laisse vacant ce numéro, il n'est pas réattribué.
Le numéro de sécu : cas typique d'un identifiant qui N'EST PAS indépendant de sa valeur puisqu'il ne comporte que des éléments liés à la personne. Mais encore une fois, oui, je suis d'accord : la théorie veut qu'on crée un nouveau commercial (avec son n° de badge par exemple). Mais ceci ne peut fonctionner dans la réalité que si c'est par exemple le directeur du personnel qui crée ou désactive le compte parce que c'est marqué dans la procédure d'arrivée ou départ d'un employé. Si tu laisses les utilisateurs lambda (y compris le directeur commercial) s'occuper de ça, cela sera obligatoirement mal géré. Il faut que ce soit un administratif qui gère cela avec rigueur, parce que si tu laisses ça à un opérationnel, il aura toujours une tâche plus urgente à accomplir (j'ai l'air de passer pour un vieux con cynique, mais c'est comme ça que cela s'est passé dans les dizaines de boîtes où j'ai eu à intervenir).
- on ne parle pas que le place utilisée en parlant de redondance. On parle également de facilité d'utilisation. Pour un SGBD, il est plus facile d'executer une recherche sur un id numérique que sur une chaine de caractères.
Mouais ... il reste à prouver que c'est sensible pour l'utilisateur : on est en train de parler de devis et de facture ici donc de quelques milliers, voire dizaines de milliers d'enregistrements. Une recherche sur un index à clé alphanumérique va prendre quelques millisecondes de plus qu'une recherche sur un index à clé numérique. En tout cas, pour le SGBD, ce n'est pas plus "facile" ou plus "difficile".
Donc, pour créer une appli stable et ayant un avenir, je te conseille de faire une table commercial dans laquelle tout nouveau commercial sera ajouté et si un client change de commercial, tu n'as qu'a modifier l'id du commercial de ce client.
C'est justement là la question : est-ce qu'il "sera" ajouté ? Tu bases la stabilité de ton application sur une procédure qui DOIT être appliquée. C'est un pari risqué !

Quand aux modifications de portefeuille client (et pas uniquement d'un seul client), à ce moment-là, comme je l'ai expliqué hier, il faut faire un lien avec l'id d'un poste fonctionnel, pas avec un nom et un prénom. Tu lis le client à la fonction "commercial du secteur automobile", pas avec Gérard Dupont.

Mais je me répète une dernière fois sur ce sujet et après basta : je suis d'accord avec tout ce qui a été dit sur les identifiants, la non-redondance, la modélisation, l'hérérésie de stocker une valeur, ... Oui, mille fois oui, je suis d'accord. Mais ... pensez au facteur humain : ce ne sont pas des robots qui vont utiliser le logiciel, ce sont des hommes et des femmes, en général pas du tout intéressés par les problèmes de création, d'historique et tout le pataquès : la population "commerciale" est une population de gens stressés, pressés et complètement insensibles à toute autre problématique que "faire du chiffre". Et si tu ne prend pas ce facteur en compte, ton appli ne sera pas stable du tout. Si tu comptes sur une auto-discipline pour suivre les procédures normales, tu vas droit dans le mur.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

19 juin 2006, 11:58

Pour le facteur humain, d'une manière personnelle, j'essaye de toujours les prendre pour des débiles mentales et les guider au maximum vers les actions à faire.

Et il faut dire que jusqu'a maintenant, quand j'impose une réunion de 1h pour la populace plus un approfondissement pour les personnes ayant des droits de modification et j'estime que c'est suffisant. Les suites de cette action sont la responsabilité de la gestion de personnel.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
ViPHP | 2144 Messages

19 juin 2006, 12:16

Henri; je ne comprends pas en quoi c'est à l'informaticien de calculer l'id en fonction du taux de TVa, on laisse au contraire le sgbd s'occuper de l'affecter lors de l'insertion dans la table et on ne s'en occupe pas.

Excuse moi, mais j'ai du mal à saisir ce que viennent faire dans la question actuelle, des dissertations sur la discipline et la capacité d'autonomie des utilisateurs finaux.

On parle de modélisation de base de donnée là....
:wink: :wink:

Une recherche sur un index numérique sera toujours plus rapide que sur une chaine de caractère et donc même si pour l'utilisateur ça ne change rien, ça aura un impact sur la charge de travail du serveur, et donc ce n'est pas négligable

Eléphant du PHP | 332 Messages

19 juin 2006, 12:49

iclo

On ne parle pas de "modélisation" ex abrupto. La modélisation n'est pas un but en soi. Le but, c'est une application informatique. Ce que j'essaye d'expliquer, c'est que d'un côté, tu as la modélisation parfaite, idéale, celle qu'on apprend dans les manuels et qu'il faudrait toujours appliquer. Et que de l'autre côté, tu as le monde réel, celui des utilisateurs, celui du travail, celui de gens pressés. Et si ta modélisation ne tient pas compte de ces contraintes imposées par les utilisateurs et la manière qu'ils auront de se servir de ton outil, tu vas à la catastrophe.

La question initiale du post est "faut-il mettre le nom du commercial avec le devis ou simplement son id". J'essaye d'expliquer que la réponse n'est pas aussi simple :
- si tu restes sur les schémas théoriques des SGBD, c'est sans aucun doute l'id qu'il faut stocker
- si tu commences à regarder comment les gens utilisent une application, (ou risquent de l'utiliser) cela mérite de se poser la question.

De la même manière, oui, dans un monde parfait, tu as un id de TVA indépendant du taux de TVA. Mais dans un monde parfait, tu n'auras pas un utilisateur qui s'amusera à modifier le taux sans se poser la question des conséquences. Dans un monde parfait, tu n'auras pas de table de données qui se scratche exactement quand il ne le faut pas.

Ce coup de mettre un id qui reprend la valeur de la TVA, ce n'est pas moi qui l'ai inventé. J'ai pas mal fréquenté le milieu des comptables et des contrôleurs de gestion pour savoir que c'est ça qu'ils font : ils donnent au code TVA la valeur de la TVA, c'est un "truc" de professionnels. Pourquoi ? Parce que ça n'est pas plus compliqué que de donner une valeur auto-incrémentale arbitraire. Et que du coup tu mets une sécurité en plus, tu diminues les risques.
Alors, non, sur ce point-là, je ne suis pas d'accord avec toi : on ne laisse pas le SGBD se débrouiller tout seul. Je ne sais pas si tu as beaucoup fréquenté ces milieux professionnels de la gestion et de la compta, mais la TVA c'est leur bête noire : tu ne laisses pas un SGBD se débrouiller tout seul. Ce n'est pas uniquement un code sur une ligne de facture, c'est beaucoup, beaucoup d'autres choses et très ennuyeuses pour eux s'il y a le moindre souci. Donc, sur ce point-là, tu ne prends strictelement aucun risque.

Je n'en dirais pas autant sur d'autres points et dans mes modélisations de base de données, je me base bien sûr à 99% sur un id auto-incrémental. Mais il y a ce 1% (dont la TVA fait partie) qui mérite réflexion.

Quant a l'impact d'un recherche sur un index alphanumérique, oui, bien sûr cela influe, personne ne le nie. Mais si tu trouves que ce n'est pas négligeable pour la charge du serveur, c'est qu'il a un problème de configuration. Ou que tu as un souci dans les index. Ou un problème de dimensionnement : c'est sûr que si tu as dix millions d'enregistrements dans ton MySQL et que les index commencent à ramer, il est peut-être temps de se poser des questions sur la configuration matérielle et logicielle. Ce n'est pas parce qu'on est dans le sujet "modélisation" que l'on doit complètement oublier le monde réel.

Je te signale par exemple qu'une application toute simple comme les pages blanches de l'annuaire téléphonique sont basés uniquement sur des index alphanumériques. Et les volumes sont un peu plus importants qu'une base de devis d'une entreprise.

Eléphant du PHP | 332 Messages

19 juin 2006, 13:03

@zeus

je ne les prends pas pour des débiles profonds, juste pour des êtres surprenants et imprévisibles :). D'où la nécessité de blinder au maximum.

Ensuite, dans toute modélisation, il faut tenir compte de l'utilisation du logiciel : C'est le passage de la modélisation de l'espace du problème à la modélisation de l'espace des solutions.

Espace du problème : Dans le devis on stocke l'id du commercial

Espace de la solution : à quoi ça sert ? en gros, une fois par an, le directeur commercial voudra faire le point sur les devis des commerciaux qui se seront barrés dans l'année ou l'année précédente.
Si tu es dans un cadre industriel (donc avec des notions de rendement et de rentabilité) : quelle est la solution la plus simple pour aboutir au même résultat ?
- gérer des autorisations/interdictions de compte, des clés primaires/étrangères pour un truc qui servira une fois par an ?
- stocker tout bêtement le nom et le prénom dans le devis ? et même si une fois par an, la charge du serveur est un peu plus importante, quelle importance ?

Alors quelle solution choisir ?
- si je suis prof de modélisation, sans aucun doute la solution avec les id.
- si je suis patron de SSI, sans aucun doute la solution avec le nom stocké.

Je dis juste : prenez toutes les contraintes en compte. Et pas uniquement la modélisation théorique qu'on trouve dans les manuels.