Bonjour Knoxville,
Au niveau conceptuel, à chaque entité-type on affecte un identifiant, dont l’objet est de distinguer des jumeaux parfaits. Pour leur part, les associations-types n’ont pas d’identifiant en propre, mais héritent de l’union des identifiants des entités-types qu’elles mettent en relation.
Supposons que vous soyez dans une entreprise recevant des commandes de la part de ses clients. Considérons maintenant l’entité-type Commande. Elle a notamment pour propriétés : L’identifiant (disons CommandeId), affecté a priori par le concepteur (acte réflexe).
Le numéro de commande connu des utilisateurs (et qui peut être utilisé comme identifiant s’il est fourni par le système, s’il est invariant et s’il garantit la règle d’unicité).
La référence du client.
La date de la commande.
L’ensemble des lignes de commande.
Etc.
En Merise, la règle est que les attributs d’une entité-type ne puissent prendre qu’une seule valeur. Or, les lignes de commande correspondent à un attribut multivalué, en infraction avec la règle. En conséquence, ces lignes de commande vont faire l’objet d’une entité-type LigneCommande. Pour autant, cette entité-type pèse bien moins lourd que celle qui lui a donné naissance, elle est qualifiée de "faible" (weak entity). On peut encore considérer les lignes de commande comme constituant un composant de la commande. Au nom d’un principe érigé en règle, LigneCommande est techniquement une entité-type mais ontologiquement et sémantiquement, viscéralement devrais-je dire, elle n’est toujours qu’une propriété de Commande : par exemple, la suppression d’une commande entraîne automatiquement la suppression de toutes ses lignes de commande, qui n’ont aucune raison de rester en vie et de s’opposer à la destruction de l'objet qu'elles composent.
Quoi qu’il en soit, l’entité-type LigneCommande doit être affectée d’un identifiant, appelons-le LigneCdeId. Il y a deux écoles :
La première d’entre elles préconise que cet identifiant soit représenté par un attribut unique, comme ce fut systématiquement le cas jusque dans les années quatre-vingts.
La deuxième, moins simpliste, reconnaît que LigneCommande — à l’instar des associations — hérite de l’identifiant de Commande. Mais, pour distinguer chaque ligne de commande au sein d’une commande, on complète l’identifiant de LigneCommande par un attribut supplémentaire, en l’occurrence LigneCdeId qui perd son caractère absolu et devient relatif à CommandeId.
Pour résumer, selon la deuxième école : L’entité-type Commande a pour identifiant {CommandeId}
L’entité-type LigneCommande a pour identifiant {CommandeId, LigneCdeId} :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
Commande (CommandeId, CommandeDate, ClientId, ...)
1 d1 c1
2 d2 c2
... ... ...
LigneCommande (CommandeId, LigneCdeId, ProduitId, Quantité, ...)
1 1 p1 q1
1 2 p2 q2
1 3 p3 q3
2 1 p4 q4
2 2 p5 q5
2 3 p6 q6
... ... ... ... |
Personnellement, je suis un adepte de l’identification relative : Pour les raisons sémantiques que j’ai mentionnées.
Ensuite, parce que cela a une incidence déterminante à l’autre bout de la chaîne, c’est-à-dire au stade de la Production informatique.
J’ai quand même plus de quarante ans d’expérience concernant les très grands volumes de données, je me suis engagé auprès de nombreuses grandes entreprises quant à la performance de leurs applications et j’ai pu apprécier l’efficacité décisive de l’identification relative à ce sujet.
En effet, au niveau physique, pour faire simple et pour reprendre l’exemple des lignes de commande, en fonction de l’attribut CommandeId, celles-ci pourront être regroupées dans une même page (clustering) et faire l’objet d’une seule entrée/sortie. Sinon, au pire, chaque ligne sera dispersée dans une page distincte, ce qui fait qu’au lieu d’obtenir les lignes en une seule entrée/sortie, il faudra donc compter autant d’entrées/sorties que de lignes. Ainsi malgré toute la puissance CPU dont vous disposerez, vous serez bloqué par les attentes de fin d’entrée/sortie, phénomène connu sous le nom d’I/O bound (ou I/O wait), qui énerve singulièrement celui qui le subit. Sur des volumes faibles ou pour des transactions légères, cela est quasiment transparent, mais peut devenir dramatique quand vous manipulez simultanément dix tables de dix à cent millions de lignes et au delà. Plus d’une fois j’ai effectué des missions en catastrophe, diagnostiqué que l’I/O bound était le coupable et fait en sorte que les temps de traitement des batch de nuit tiennent dans la fenêtre imposée et ne retardent plus le démarrage du télétraitement diurne.
On pourra vous rétorquer que le regroupement (clustering) des lignes de commande sur CommandeId ne nécessite pas le mécanisme de l’identification relative. Mais, changement de chanson si vous voulez propager cet attribut au-delà des lignes de commande et continuer à éviter l’I/O bound. Considérez que l’entité-type LigneCommande comporte un attribut multivalué donnant lieu à une entité-type Engagement (on s’engage à livrer en fonction de ce que l’on a en stock, en cours d’arrivage, en fabrication, etc.) : le regroupement des engagements sur CommandeId s’impose là encore. Même chose si chaque engagement fait à son tour l’objet de plus d’une livraison (par exemple, on ne peut pas tout mettre sur le même camion).
Je joins un schéma que j’ai déjà proposé à Snoopo et consorts. Vous noterez que même l’entité-type Commande est identifiée relativement à Client. Exercice : à vous de justifier ce choix.
En revanche, l’entité-type Client est considérée comme "indépendante". Paradoxalement, le regroupement des clients pourrait poser des problèmes de contention dans un contexte transactionnel, mais je suppose que vous avez étudié le problème de la concurrence d’accès des transactions en mise-à-jour et comprendrez cela (supposez qu’au même moment plusieurs utilisateurs créent des clients). Le phénomène de contention joue moins avec les commandes et lignes de commande, car une commande donnée est traitée (en principe) par un utilisateur unique.
Sur ce schéma (Power AMC), vous noterez que, par exemple, l’attribut CommandeId ne figure pas comme attribut de l’entité-type LigneCommande, mais au niveau tabulaire il sera bien présent. Vous noterez aussi que LigneCommande n’est pas identifiée relativement à Produit : une ligne de commande n’est pas un composant d’un produit.
Il est encore possible que la recherche des données Produit engendrent de l’I/O bound, c’est pourquoi ces données devront être accédées au plus une fois, le plus tard possible, lors du traitement chargé de fournir ces données. Mais là, on en arrive au prototypage des traitements et il s’agit d’une autre histoire...
Pour conclure, au niveau conceptuel, l’identification relative se justifie pour des raisons ontologiques et sémantiques. Ses conséquences au niveau physique sont déterminantes pour la réduction des temps des traitements lourds manipulant de grands volumes de données.
A vous de jouer.
Partager