IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Dénormalisation de table. Quand ? [Débat]


Sujet :

Langage SQL

  1. #61
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    J'allais, moi aussi, parler de la modélisation par méta-données.

    Alors juste là-dessus :
    En informatique, il existe des notions d'héritage, de surcharge
    - Pourquoi ne pas appliquer ces principes au modèle des données
    Il est tout à fait possible et courant de modéliser un héritage de données en BDD.

    Quant à la surcharge, je ne connais pas bien mais je subodore que l'utilisation des vues doit pouvoir y répondre.

    Il y a quelques années, alors que j'envisageais une activité professionnelle indépendante, j'avais commencé à réfléchir à la structuration des données d'une entreprise, quelle qu'elle soit. J'étais arrivé au fait qu'une entreprise (ou toute autre entité juridique) a à gérer :
    - des personnes physiques ;
    - des personnes morales (entreprises, associations, administrations...) ;
    - des objets physiques ;
    - des "choses" immatérielles (brevets, marques, projets...) ;
    - des documents ;
    - des comptes ;
    - des événements datés ou périodiques (rendez-vous, réunions...) ;
    - des lieux.

    Venant de refaire cette réflexion tout en rédigeant, j'en ai peut-être oublié mais je ne pense pas qu'il en manque beaucoup.

    Alors effectivement, avec cette petite dizaine d'entités de base + une modélisation par méta-données et/ou quelques héritages communs à toute entreprise, on doit pouvoir construire une architecture de données qui pourra répondre à tous les besoins des entreprises.

    Mais au vu de vos messages et de la description des données que vous faites, j'ai l'impression que le modèle de données de votre ERP magique est bien loin d'avoir une structure de données optimisée, notamment par l'usage abusif de clés alphanumériques mais ça je l'ai déjà critiqué dans un précédent message.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  2. #62
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 761
    Points : 52 547
    Points
    52 547
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    Intention louable, mais simplifier un algorithme dans un programme n’entraîne pas a priori la réduction de la consommation de ressources, mais a un coût en termes de maintenance. En revanche, un SGBD comme DB2 utilise sous le capot des algorithmes de plus en plus astucieux et sophistiqués, dont l’objet est bien de réduire la consommation des ressources, sans que l’on ait en contrepartie à modifier une ligne de code dans les programmes.
    On peut citer en exemple parfait le théorème (dont je ne me souviens jamais l'auteur) qui veut que tout algorithme récursif peut s'écrire de manière itérative à l'aide d'une pile. Le code en sera probablement plus complexe, mais les performances sans communes mesure !


    Non. Il y a aussi ceux dont je fais partie et qui ont passé leur vie dans la soute et à la dunette, à modéliser, prototyper et garantir les performances de la production informatique dans les entreprises. Comme je l’ai déjà mentionné, j’ai passé le plus clair de mon temps sur le terrain, notamment suite à des appels au secours, pour rattraper en catastrophe les bourdes des autres mettant à mal la production. Cela fait un bon moment que j’ai conclu que, même si elle n’est pas la panacée, la normalisation des bases de données est déterminante et singulièrement bénéfique. Par ailleurs, je rappelle que normaliser et optimiser sont deux choses différentes mais qui sont complémentaires.
    Il arrive même que l'hyper normalisation soit un moyen de réduire les coûts de stockage et de restitution de l'information, donc d'améliorer les performances. Par exemple envisager une table des prénoms permet de réduire singulièrement les ressources de toute nature, lorsque l'on a une base contenant 130 millions d'individus comme c'est le cas de la base de données de l'INSEE située à Nantes et qui recense toute la population française (y compris de nombreuses personnes aujourd'hui décédées...)...
    Pardon ? Des centaines (des milliers) de requêtes pour un seul écran ?! Il y a de l’optimisation à prévoir en ce qui concerne la manipulation des données, les requêtes SQL il ne faut pas « s’en cogner », même si celui qui les génère est un ERP...
    Visiblement notre quidam est passé à côte de la notion de procédure stockées et de concepts tels que le MARS qui permettent d'envoyer et recevoir plusieurs lots de requêtes et procédures dans une seule et même connexion au serveur avec entrelacement des lectures ...
    J’inverse le propos : la jointure (l’opérateur relationnel par excellence) permet de ne pas avoir à ajouter inutilement des colonnes dans l’en-tête d’une table. Ajouter une colonne est une opération lourde s’il en est quand il faut s’y résoudre, alors qu’ajouter une ligne dans une table est transparent, et comme on l’a vu, sans que la performance soit impactée.
    Dans le même esprit, en modélisation (ou plutôt devrais-je dire en "non modélisation") on voit souvent des gens au cours de l'exploitation d'une base dire, "il faut rajouter telle information... Vas-y met là dans cette table là..." C'est qui est une parfaite imbécilité et conduit à des matrices creuses (que vont contenir, comme données, toutes les lignes d'avant qui n'ont pas cette info ?) et des tables obèses (des dizaines, voire des centaines de colonnes... rarement requêtées toutes systématiquement !)

    Le défi de la modélisation est — entre autres — de ne jamais avoir d’attribut qui puisse être marqué NULL.
    C'est d'ailleurs quelque part le but caché de la 6e forme normale... Rermarquons que certaines bases de données (Sybase IQ en particulier) font cela de manière naturelle en décomposant toute table relationnelle en n relation pure à raison d'une relation par couple clef/colonne hors clef. C'est même devnu très mode ces derniers temps avec le stockage vertical... (exemple vertipaq / columnstore... plus adapté à la BI, on est bien d'accord !)


    Êtes-vous conscient de l’énormité que vous proférez ? Grâce au langage qu’il propose, le SGBD vous permet de structurer les données (le typage sert par exemple à éviter de comparer des choux et des carottes, les vues vous permettent de présenter les données de différentes façons, etc.), les manipuler en tant qu’ensembles (grâce aux opérateurs de l’algèbre relationnelle), en garantir l’intégrité (intégrité d’entité, intégrité référentielle, contraintes de base de données (instruction CONSTRAINT de Tutorial D ou assertions et triggers SQL)). Et je ne parle même pas des propriétés ACID que le SGBD doit assurer outre d’autres fonctions. Si vous vous limitez au stockage, autant en passer par des fichiers.
    Mais la plupart des développeur ignore totalement ce qu'est une gestion ensembliste des données... Ils pensent naïvement que les lignes sont traitées itérativement. Déjà ils ont du mal à concevoir qu'une table n'a pas d'ordre des lignes et qu'une demande tel que "je voudrais retrouver la dernière ligne que j'ai mis dans ma table ?" n'a aucun sens dans le monde relationnel si l'on a pas prévu d'information pour ce faire !

    Effectivement, il faut changer d’outil, ou envoyer celui qui en est l’auteur apprendre à modéliser correctement (5NF, voire 6NF pour les données temporelles), apprendre l’algèbre relationnelle, apprendre à faire des vues. La modélisation des bases de données ne se fait pas en plaquant dans des tables ce qu’on voit à l’écran, la vue qu’on a de l’écran est indépendante (orthogonale comme dirait Chris Date) de la structure de la base de données.
    Le malheur est que plus personne ne parle du MED (Modèle Externe de Données) c'est à dire les vues, les procédures... alors que c'est fondamental, et qu'on tente de le remplacer par ces horribles merdouilles d'ORM dont chacun sait que c'est le Viêtnam de l'informatique !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #63
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par SQLPro
    Le malheur est que plus personne ne parle du MED (Modèle Externe de Données) c'est à dire les vues, les procédures... alors que c'est fondamental, et qu'on tente de le remplacer par ces horribles merdouilles d'ORM dont chacun sait que c'est le Viêtnam de l'informatique !
    Il m'arrive de parler, dans mes interventions sur les forums de DVP, du "Modèle Organisationnel des Données" et de dire que ce sont les vues qu'utilisera le logiciel et qui correspondra grosso modo aux classes métiers de l'application.

    Et j'appelle les ORM des "Objets Réellement Merdiques" !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  4. #64
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 149
    Points : 7 392
    Points
    7 392
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Visiblement notre quidam est passé à côte de la notion de procédure stockées et de concepts tels que le MARS qui permettent d'envoyer et recevoir plusieurs lots de requêtes et procédures dans une seule et même connexion au serveur avec entrelacement des lectures...
    A priori, vu qu'il est question d'une réponse à une de mes interventions, le quidam c'est moi, et à ce titre, je me permet de me défendre.

    Quand on travaille avec un ERP qui utilise à la fois une base de données hyper mal goupillée (très maléable, très générique, mais aussi parfaitement dénormalisée) et un framework écrit par des stagiaires bulgares, on fait ce qu'on peut avec ce qu'on a.

    Ce framework propose des objets métiers écrits en Java, dont on ne maîtrise ni le code, ni le fonctionnement, ni quoi que ce soit, qui sont appelés entre eux grace à un fichier XML de configuration qui décrit les flux pour une page donnée.

    On se retrouve alors avec ce genre de choses (voir capture d'écran "xdme1.png")

    Modification des informations d'un fournisseur :
    On a en point de départ l'utilisateur courant (le compte utilisateur connecté).
    Derrière (donc si on a retrouvé les données de l'utilisateur connecté et qu'elles sont valides), on a :
    - une API qui lui permet de supprimer le fournisseur (si on a passé des paramètres particuliers en paramètre)
    - un objet métier qui va récupérer des informations sur le type de tiers "fournisseur"
    - un objet métier qui va récupérer les informations du fournisseur
    Derrière l'objet métier fournisseur, on a de nouveaux objets métiers :
    - un objet adresse qui récupère l'identifiant de l'adresse commerciale du fournisseur
    - une requête dynamique (un objet métier qui ne sait faire que du CRUD à l'unique condition que le SELECT ne porte que sur une seule table et retourne la clé de cette dernière)
    - et un objet métier dans lequel on va récupérer... j'ai pas bien compris pourquoi, mais encore le type du tiers
    Derrière l'objet métier qui récupère l'identidfiant de l'adresse commerciale du tiers, on a :
    - un objet métier qui récupère l'adresse en question

    Pour chaque objet métier, c'est N requêtes : "utilisateur courant société" s'assure que l'utilisateur existe, que son mot de passe est valide, etc. mais aussi qu'il est habilité à voir l'écran demandé, etc. Je n'ai pas la main sur ce que fait cet objet, donc je ne sais pas s'il fait tout en une requête ou en 25 requêtes.
    Ici, on voit un (1) pour chaque objet métier, cela indique que même si par mésaventure plusieurs lignes étaient retournées, seule la première lue serait chargée. On on va avoir en tout guère plus de requête qu'il n'y a d'objet métier.

    Mais si on prend l'exemple "xdme2.png", ça se complique.
    Ici, on va charger 10 lignes d'un événement (commande, livraison, facture, etc.)
    Et pour chaque ligne, on va récupérer des informations :
    - sur le produit, le fournisseur, l'objet de stock, le lot, etc.
    Donc toutes les requêtes effectuées après "EvenementPoste" sont exécutée 10 fois, une fois pour chaque ligne retournée par "EvenementPoste". La fèche verte sur ces objets le confirme d'ailleurs, puisqu'elle force le programme à charger l'objet métier non pas pour la première ligne de l'objet père, mais pour toutes les lignes de l'objet père.
    Et ça, c'est comme ça que c'est fait.
    Et accessoirement, un ORM fonctionne exactement pareil.

    Et enfin, on arrive sur des pages plus complèxes, qui ne tiennent pas dans l'écran, "xdme3.png" :

    Il s'agit ici de modifier l'entête d'un événement. Un nombre considérable d'objet métiers sont appelés, puisqu'un nombre considérable de données sont présentes sur l'entête d'un événement, et qu'il faut contrôler énormément de choses afin de savoir s'il faut afficher tel ou tel champ, autoriser ou non telle modification, etc.
    Et là, on arrive rapidement à des centaines de requêtes juste pour afficher cette page.

    Alors oui, on pourrait faire une mega-vue, et faire du CRUD dessus.
    Sauf que :
    1/ L'application n'est absolument pas prévue pour fonctionner de la sorte
    2/ Qu'on soit client, éditeur ou intégrateur, on n'est pas là pour réécrire l'ERP à chaque projet
    3/ La complexité des règles de gestion, en partie à cause de la généricité du modèle des données, fait qu'il faudrait passer plusieurs semaines de travail sur chaque écran, ce qui n'est juste pas possible en termes de budget
    4/ Que le modèle des données derrière étant de toute façon ce qu'il est, il n'y a absolument aucune garantie qu'une hausse des performances significative soit constatée, au risque d'immenses régressions

    Bref, je veux bien me faire allumer pour un produit que j'ai écrit, mais pas pour quelque chose que je subit quotidiennement. C'est déjà assez chiant de travailler avec cette merde, sans pour autant devoir subir des remarques désobligeantes.

    En revanche, malgré tout le mal je pense et que je peux dire de l'outil et de sa conception, force est de constater qu'à la fois le modèle des données et cette façon de fonctionner lui permettent d'être personnalisable à moindre coût, et notamment permet de couvrir de nouveaux besoins fonctionnels sans devoir développer quoi que ce soit.
    C'est d'ailleurs le principe d'un ERP, et pour le coup, celui-ci est du genre "jusquauboutiste", puisqu'il n'a pour ainsi dire comme limitations que la connaissance qu'on en a, et l'imagination de celui qui le paramètre.

    Il me semble que je vous ai déjà parlé de Générale de Santé qui utilise cet ERP dans ses hôpitaux pour gérer des greffes à partir du moteur de livraison, et de Petites Annonces qui modélise le journal officiel sous forme de commandes.
    Images attachées Images attachées    
    On ne jouit bien que de ce qu’on partage.

  5. #65
    Membre éclairé

    Développeur Web
    Inscrit en
    Mars 2002
    Messages
    412
    Détails du profil
    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2002
    Messages : 412
    Points : 657
    Points
    657
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Et j'appelle les ORM des "Objets Réellement Merdiques" !
    C'est aussi mon sentiment. Les bases de données relationnelles sont un monde propre et il appartient au développeur de s'y adapter plutôt que l'inverse. De même qu'on ne devrait pas programmer en PHP comme en Java sous peine de performances déplorables, et que JavaScript demande une manière encore différente de "penser objets" si l'on veut éviter de programmer de manière malpropre.

    Citation Envoyé par SQLpro Voir le message
    ces horribles merdouilles d'ORM dont chacun sait que c'est le Viêtnam de l'informatique !
    J'ai parcouru. C'est une bonne ressource, merci.
    Elle est toutefois trop diluée et le topo sur la guerre du Vietnam est en trop, une simple allusion aurait suffit. Y aurait-il un autre article plus concis quelque part ? Ça peut être utile, pour convaincre…

  6. #66
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 761
    Points : 52 547
    Points
    52 547
    Billets dans le blog
    5
    Par défaut
    Personnellement j'ai développée un ERP dans le domaine de la santé et nous avons été à la fois très souple (paramétrage oblige) et totalement normalisé et même hypernormalisé sur la partie patient du fait de l'identitovigilance....

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  7. #67
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    06/09/2011
    Citation Envoyé par StringBuilder
    Bonjour,

    Je viens ajouter un petit grain de sable à l'édifice.

    Je travaille sur un ERP, qui s'appelle Generix.

    Et cet outils m'a ouvert les yeux sur une nouvelle façon de modéliser les bases de données.
    À l'époque, le ton de tes messages laissait à penser que tu trouvais Generix très bien. Tes messages étaient à la limite de la publicité pour ce logiciel.

    Et tu t'es fait allumé, non pas sur cette défense aveugle mais sur le fonds de ce que tu exprimais en rapport avec la manière dont ce logiciel est fait, et surtout sur son modèle de données que tu semblais défendre, alors que de bien plus grands experts que moi, notamment fsmrel, contraient tes arguments de façon nette.

    Depuis, j'ai remarqué que tes interventions dans différents forums étaient beaucoup plus raisonnables et, disons plus conforme à ce qui est préconisé par les experts.

    Aujourd'hui, nous ne pouvons que constater l'évolution de ton opinion pour Générix qui donne finalement raison à tes détracteurs.

    26/10/2012 :
    Citation Envoyé par StringBuilder
    Quand on travaille avec un ERP qui utilise à la fois une base de données hyper mal goupillée (très maléable, très générique, mais aussi parfaitement dénormalisée) et un framework écrit par des stagiaires bulgares, on fait ce qu'on peut avec ce qu'on a.
    ...
    Bref, je veux bien me faire allumer pour un produit que j'ai écrit, mais pas pour quelque chose que je subit quotidiennement. C'est déjà assez chiant de travailler avec cette merde, sans pour autant devoir subir des remarques désobligeantes.
    SQLPro n'a fait que souffler sur les braises de cette ancienne discussion, sans peut-être remarquer qu'elle était interrompue depuis déjà un temps certain.

    Si j'étais ton supérieur hiérarchique et que je tombais sur ton dernier message, je te convoquerais rapidement pour te passer un savon !
    J'espère que ce message ne va pas se retourner contre toi professionnellement... ou que tu as déjà prévu la suite de ta carrière !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  8. #68
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 149
    Points : 7 392
    Points
    7 392
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Personnellement j'ai développée un ERP dans le domaine de la santé et nous avons été à la fois très souple (paramétrage oblige) et totalement normalisé et même hypernormalisé sur la partie patient du fait de l'identitovigilance....

    A +
    Au détail près qu'ici je parle d'un ERP qui a été conçu à la base pour le retail, mais qui couvre aussi bien les domaines du négoce, de l'import, de la logistique, ou même de la santé, sans besoin de vertical.
    Chaque entité a donc été conçu pour pouvoir stocker "tout et n'importe quoi".

    Ça donne donc un arrière gout de "n'importe comment" au niveau modélisation, mais au final ça permet de faire à peu près tout.

    Quand on normalise "trop", on perd cette souplesse, c'est à dire que dans ton entité "patient", je ne pourrai pas y faire rentrer un camion si demain au lieu d'être dans un hôpital ton ERP est installé chez un transporteur.

    Citation Envoyé par CinePhil Voir le message
    06/09/2011

    À l'époque, le ton de tes messages laissait à penser que tu trouvais Generix très bien. Tes messages étaient à la limite de la publicité pour ce logiciel.

    Et tu t'es fait allumé, non pas sur cette défense aveugle mais sur le fonds de ce que tu exprimais en rapport avec la manière dont ce logiciel est fait, et surtout sur son modèle de données que tu semblais défendre, alors que de bien plus grands experts que moi, notamment fsmrel, contraient tes arguments de façon nette.

    Depuis, j'ai remarqué que tes interventions dans différents forums étaient beaucoup plus raisonnables et, disons plus conforme à ce qui est préconisé par les experts.

    Aujourd'hui, nous ne pouvons que constater l'évolution de ton opinion pour Générix qui donne finalement raison à tes détracteurs.

    26/10/2012 :

    SQLPro n'a fait que souffler sur les braises de cette ancienne discussion, sans peut-être remarquer qu'elle était interrompue depuis déjà un temps certain.

    Si j'étais ton supérieur hiérarchique et que je tombais sur ton dernier message, je te convoquerais rapidement pour te passer un savon !
    J'espère que ce message ne va pas se retourner contre toi professionnellement... ou que tu as déjà prévu la suite de ta carrière !
    Je ne renie en rien ce que j'ai pu dire à l'origine.
    N'étant clairement pas expert en modélisation, et faisant une confiance aveugle à l'époque envers ce que pouvait représenter à mes yeux un éditeur d'ERP, j'ai eu la faiblesse de prendre pour argent comptant les solutions parfois malheureuses mises en place sur cet outil.

    Aujourd'hui, j'ai un oeil plus critique envers cet ERP, sa philosophie et son modèle des données. Et je le dit clairement, "c'est modélisé comme de la merde" (j'assume mes propos).

    Cependant, je ne lui enlève pas sa fabuleuse souplesse, car autant d'un côté il est modélisé n'importe comment, autant je suis convaincu que ce n'est pas le concept de l'outils qui n'est pas adapté aux SGBDR, mais les SGBDR qui ne sont pas adaptés à sa conception.

    Car normaliser le modèle de cet outil, c'est aussi le brider complètement sur bien des aspects.

    Un exemple simple.

    Actuellement 3 tables avec (entre autres) les champs suivants :

    MEV (codsoc, codent, segment, codsoc_phy)
    EVE (codsoc, typeve, numeve, typtie, sigtie)
    TIE (codsoc, typtie, sigtie, nomtie)

    La table "EVE" sert à stocker des événement, qui peuvent aussi bien être :
    - des devis
    - des commandes
    - des livraisons
    - des factures
    - des inventaires
    - des poses de prothèses
    - des ordonnances
    - des publications de journal officiel
    - le planning des cours d'un étudiant
    - j'en passe des meilleures

    La clé est "codsoc, typeve, numeve".
    CODSOC indique la société à laquelle appartient l'événement (centrale d'achat, dépôt, magasin, hôpital, etc.)
    TYPEVE indique le type d'événement (devis, commande, etc.)
    NUMEVE indique le numéro d'événement

    TYPTIE indique le type de tiers rattaché à mon événement (un utilisateur, un client, un fournisseur, un dépôt, un médecin, un patient, un magasinier,un vendeur, etc.)
    SIGTIE indique le sigle du tiers en question.

    Et dans la table TIE, on retrouve CODSOC, TYPTIE et SIGTIE.

    Grace à ça, on peut savoir quel tiers est rattaché à tel événement.

    MEV, quant à elle, permet de dire "bon, quand je suis dans la société 'X', pour la table 'Y' et le type d'élément 'Z', je dois aller lire en réalité dans la société 'A'".

    Par exemple, je suis dans la société (10) "Dépôt de Paris", et je veux consulter les livraisons que je dois honorer.
    Les livraisons ne sont pas créés au dépôt, mais au service commercial qui est dans une autre société (5).
    Accessoirement, afin de pouvoir faire des négiciations au niveau national avec mes clients, ces derniers sont tous gérés dans la société hodling (1).

    Alors y'a moyen de faire ça de façon normalisée.
    Mais accrochez-vous pour les requêtes ensuite, surtout si elles doivent marcher chez un client qui a une organisation parfairement différente.

    Ici, ça coule de source, pour chaque table lue, on va rechercher dans MEV la valeur du CODSOC à interroger : c'est "automatique", simple et parfaitement fonctionnel.
    Par contre, en effet, y'a pas une seule clé étrangère,car on ne sais pas faire une clé étrangère qui pointe sur plusieurs tables à la fois.

    Jeu de données :
    MEV (10, 'TIE', 'CLI', 1)
    MEV (10, 'EVE', 'LIV', 5)
    TIE (1, 'CLI', 'TOTO', 'Monsieur Toto')
    EVE (5, 'LIV', 1, 'CLI', 'TOTO')

    Et là, la magie du modèle des données pourri opère :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    select eve.numeve, tie.nomtie
    from mev meveve
    inner join mev mevtie on mevtie.codsoc = meveve.codsoc and mevtie.codent = 'TIE' and mevtie.segment = eve.typtie
    inner join eve on eve.codsoc = meveve.codsoc_phy and eve.typeve = meveve.segment
    inner join tie on tie.codsoc = mevtie.codsoc_phy and tie.typtie = mevtie.segment and tie.sigtie = eve.sigtie
    where meveve.codsoc = 10 and meveve.codent = 'EVE' and meveve.segment = 'LIV'

    Quel que soit le client chez qui cette requête sera utilisée, on n'aura que le paramètre "codsoc = 10" à remplacer par la société dans laquelle est connecté l'utilisateur, et "meveve.segment = 'LIV'" par le type d'événement qu'on essaie de consulter.

    Dans la logique d'un ERP, ça peut justifier l'abandon de la puissance du SGBDR au profit d'une maintenabilité accrue.

    Ça n'en reste pas moins pourrissime d'un point de vue modélisation dans l'optique d'une mise en place dans un SGBDR.
    On ne jouit bien que de ce qu’on partage.

  9. #69
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 761
    Points : 52 547
    Points
    52 547
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    ...
    Chaque entité a donc été conçu pour pouvoir stocker "tout et n'importe quoi".
    Ça donne donc un arrière gout de "n'importe comment" au niveau modélisation, mais au final ça permet de faire à peu près tout.
    Quand on normalise "trop", on perd cette souplesse, c'est à dire que dans ton entité "patient", je ne pourrai pas y faire rentrer un camion si demain au lieu d'être dans un hôpital ton ERP est installé chez un transporteur.
    Visiblement la notion d'héritage n'est pas connue... Elle permet de passer d'un type générique à un type spécialisé. C'est comme cela que l'on fait pour partir d'un objet global aux détails, sans perdre rien de la normalisation ni de la finesse des données. N'oubliez pas que le SQL permet de créer de nouvelles tables dynamiquement et prévoir des IHM génériques ainsi que des système d'interrogation générique est un jeu d'enfant !
    ....
    Aujourd'hui, j'ai un oeil plus critique envers cet ERP, sa philosophie et son modèle des données. Et je le dit clairement, "c'est modélisé comme de la merde" (j'assume mes propos).
    C'est le cas hélas de bien des ERP car les chef de projet de c genre d'engins sont plus à l'aise dans le code client que dans la base...

    Cependant, je ne lui enlève pas sa fabuleuse souplesse, car autant d'un côté il est modélisé n'importe comment, autant je suis convaincu que ce n'est pas le concept de l'outils qui n'est pas adapté aux SGBDR, mais les SGBDR qui ne sont pas adaptés à sa conception.
    Car normaliser le modèle de cet outil, c'est aussi le brider complètement sur bien des aspects.
    Non, je ne peut pas être d'accord.
    En imaginant que l'on ait par exemple prévu 36 colonnes VARCHAR dans une table "ressource" dont on ne sait pas si c'est un homme une machine ou un contrat, que pensez vous de la difficulté par exemple :
    1) de faire des requêtes avec des critères > ou < quand c'est données numérique ou des dates ?
    2) d'extraire un mois ou le n° de semaine ISO d'une date
    3) du coût des requêtes qui doivent se farcir un transtypage à chaque ligne ?
    4) que dire d'indexer une colonne VARCHAR contenant des nombre ou des dates ? Cela servira t-il à grand chose ?
    Il est beaucoup plus simple de rajouter une table fille en héritage de cette table ressource et la doter du nombre exact des critères exigés et de les typer correctement...
    En sus vos requêtes ne seront pas plus difficile à écrire, surtout si lors de la création de cette table en héritage est créée simultanément une vue de "mise à plat". En revanche, les performances seront très nettement meilleure sur les extractions, le volume des données stockées moindre et surtout la concurrence transactionnelle sera améliorée (des tables obèses posent toujours des problèmes de contention pour les transactions. À me lire : http://blog.developpez.com/sqlpro/p1...mances_petites).




    Un exemple simple.

    Actuellement 3 tables avec (entre autres) les champs suivants :

    MEV (codsoc, codent, segment, codsoc_phy)
    EVE (codsoc, typeve, numeve, typtie, sigtie)
    TIE (codsoc, typtie, sigtie, nomtie)

    La table "EVE" sert à stocker des événement, qui peuvent aussi bien être :
    - des devis
    - des commandes
    - des livraisons
    - des factures
    - des inventaires
    - des poses de prothèses
    - des ordonnances
    - des publications de journal officiel
    - le planning des cours d'un étudiant
    - j'en passe des meilleures

    La clé est "codsoc, typeve, numeve".
    CODSOC indique la société à laquelle appartient l'événement (centrale d'achat, dépôt, magasin, hôpital, etc.)
    TYPEVE indique le type d'événement (devis, commande, etc.)
    NUMEVE indique le numéro d'événement

    TYPTIE indique le type de tiers rattaché à mon événement (un utilisateur, un client, un fournisseur, un dépôt, un médecin, un patient, un magasinier,un vendeur, etc.)
    SIGTIE indique le sigle du tiers en question.

    Et dans la table TIE, on retrouve CODSOC, TYPTIE et SIGTIE.

    Grace à ça, on peut savoir quel tiers est rattaché à tel événement.

    MEV, quant à elle, permet de dire "bon, quand je suis dans la société 'X', pour la table 'Y' et le type d'élément 'Z', je dois aller lire en réalité dans la société 'A'".

    Par exemple, je suis dans la société (10) "Dépôt de Paris", et je veux consulter les livraisons que je dois honorer.
    Les livraisons ne sont pas créés au dépôt, mais au service commercial qui est dans une autre société (5).
    Accessoirement, afin de pouvoir faire des négiciations au niveau national avec mes clients, ces derniers sont tous gérés dans la société hodling (1).

    Alors y'a moyen de faire ça de façon normalisée.
    Mais accrochez-vous pour les requêtes ensuite, surtout si elles doivent marcher chez un client qui a une organisation parfairement différente.

    Ici, ça coule de source, pour chaque table lue, on va rechercher dans MEV la valeur du CODSOC à interroger : c'est "automatique", simple et parfaitement fonctionnel.
    Par contre, en effet, y'a pas une seule clé étrangère,car on ne sais pas faire une clé étrangère qui pointe sur plusieurs tables à la fois.
    Vous venez de prouver ce que je dis : comme on ne sait pas faire d'héritage, alors on bricole. Et donc pas de contraintes Foreign Key... mais savez-vous au moins que les FK dans les bons SGBDR (je parle pas de MerdeSQL...) permettant d'optimiser les requêtes notamment en abandonnant des jointures inutiles ?
    Jeu de données :
    MEV (10, 'TIE', 'CLI', 1)
    MEV (10, 'EVE', 'LIV', 5)
    TIE (1, 'CLI', 'TOTO', 'Monsieur Toto')
    EVE (5, 'LIV', 1, 'CLI', 'TOTO')

    Et là, la magie du modèle des données pourri opère :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    select eve.numeve, tie.nomtie
    from mev meveve
    inner join mev mevtie on mevtie.codsoc = meveve.codsoc and mevtie.codent = 'TIE' and mevtie.segment = eve.typtie
    inner join eve on eve.codsoc = meveve.codsoc_phy and eve.typeve = meveve.segment
    inner join tie on tie.codsoc = mevtie.codsoc_phy and tie.typtie = mevtie.segment and tie.sigtie = eve.sigtie
    where meveve.codsoc = 10 and meveve.codent = 'EVE' and meveve.segment = 'LIV'

    Quel que soit le client chez qui cette requête sera utilisée, on n'aura que le paramètre "codsoc = 10" à remplacer par la société dans laquelle est connecté l'utilisateur, et "meveve.segment = 'LIV'" par le type d'événement qu'on essaie de consulter.

    Dans la logique d'un ERP, ça peut justifier l'abandon de la puissance du SGBDR au profit d'une maintenabilité accrue.

    Ça n'en reste pas moins pourrissime d'un point de vue modélisation dans l'optique d'une mise en place dans un SGBDR.
    Et surtout des performances en volume...

    Mon collègue Stéphane Faroult a fait une série de vidéo sur le problème des perf, et montre très bien comment ce genre de modèle conduit à des milliers de lectures et relecture des mêmes pages en mémoire faisant écrouler le serveur...


    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  10. #70
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 149
    Points : 7 392
    Points
    7 392
    Billets dans le blog
    1
    Par défaut
    L'héritage, oui, mais la création dynamique de table, non : comment voulez-vous ensuite garantir les performances sur un modèle des données mutant, où le programme passe son temps à recréer des tables, ajouter des colonnes au moindre changement de définition d'une entité ?

    Ensuite, je suis parfaitement d'accord qu'une table avec 30 champs VARCHAR ne résoud pas tout.

    C'est d'ailleurs pour ça que cet ERP prévoit à la place 10 champs VARCHAR, 10 DECIMAL, 10 INTEGER et 10 DATE ( pas taper )

    Ensuite, cet ERP repose surtout sur des tables fourre tout, qui permettent d'étendre les entités via paramétrage, sans devoir régénérer de requête.

    Cependant, les limites que vous donnez (types non adaptés, tables obèses etc.) restent, et c'est pour cette raison que mon sophisme s'arrête là.

    Mais en terme de mise en place, les solutions retenues sont clairement plus aisées à mettre en place qu'un modèle aux petits oignons.

    Et peut-être est-ce parce que j'ai jamais eu de bonnes expériences avec, mais les modèles de données construits dynamiquement via paramétrage, je suis très sceptique, autant en ce qui concerne les performances que la fiabilité et la pérennité des développements connexes (interfaces, univers BO, etc.)
    On ne jouit bien que de ce qu’on partage.

  11. #71
    Membre éclairé

    Développeur Web
    Inscrit en
    Mars 2002
    Messages
    412
    Détails du profil
    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2002
    Messages : 412
    Points : 657
    Points
    657
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    mais savez-vous au moins que les FK dans les bons SGBDR (je parle pas de MerdeSQL...) permettant d'optimiser les requêtes notamment en abandonnant des jointures inutiles ?
    Je serais intéressé par plus d'explications.

  12. #72
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Débat intéressant. Pauvre StringBuilder obligé de barouder dans des marécages plein d’ennemis et de crocodiles, fichue épreuve, je compatis.


    Mais permettez-moi de regrimper dans les hauteurs éthérées, je souhaiterais préciser un point :

    Citation Envoyé par SQLpro Voir le message

    Citation Envoyé par fsmrel Voir le message
    Le défi de la modélisation est — entre autres — de ne jamais avoir d’attribut qui puisse être marqué NULL.
    C'est d'ailleurs quelque part le but caché de la 6e forme normale...
    Hum... La sixième forme normale n’a aucun but caché. En l’énonçant, le but de Chris Date était de montrer dans quelles conditions on modélise correctement dans un contexte temporel.

    Quand il présente la structure de la table des fournisseurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Fournisseur {FourId, FourNom, FourStatut, FourVille}
                KEY {FourId} ;
    Il se trouve que cette structure est seulement en cinquième forme normale, mais dans un contexte non temporel c’est parfait, inutile de chercher à la décomposer contrairement à ce que réclament les tenants du modèle binaire (Binary Relation Approach), et comme dit Date (An Introduction to Database Systems, eighth edition, page 762) : « The argument in favor of “decomposing all the way” is not very strong » (euphémisme...) Pour sa part, Codd renvoie les tenants en question à leurs chères études (The Relational Model for Database Systems: Version 2, 1990, page 474, « Normalization Cannot be Forgotten »). En l’occurrence, il cite Leo Mark chaud partisan du modèle binaire :
    The model seems to be easy for non-technical people because it avoids normalization [...]
    Et il montre pourquoi l’affirmation « it avoids normalization » est fausse.

    Maintenant, quand les valeurs prises par les attributs FourNom, FourStatut et FourVille de la table Fournisseur varient de façon indépendante dans le temps, si l'on veut historiser les changements alors la normalisation en 6NF prend tout son intérêt.

    La prise en compte du temps pourrait par exemple faire évoluer ainsi — mais de façon maladroite — la structure de la table Fournisseur (noter la composition de la clé) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Fournisseur {FourId, FourNom, FourStatut, FourVille, DateDebut}
                KEY {FourId, DateDebut} ;
    Mais ça n’est pas bien fameux (euphémisme à nouveau...), la modélisation correcte est la suivante (noter la composition de chaque clé) :

    1) En premier lieu, une table seulement en 5NF (mais non redondante) qui permet de représenter les données actives (par exemple, le fournisseur F1 réside à Toulouse depuis le 24 juillet 2012) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Fournisseur {FourId, FourIdDateDebut, 
                 FourNom, FourNomDateDebut, 
                 FourStatut, FourStatutDateDebut,
                 FourVille, FourVilleDateDebut}
                KEY {FourId} ;
    2) En deuxième lieu, une table par attribut FourId, FourNom, FourStatut, FourVille, chacune en 6NF, permettant de représenter le passé en termes d’intervalles de dates propres à chaque donnée (l’attribut Durant est du type intervalle de dates, {DateDebut:DateFin}), sans redondance (c'est l'objet non caché de la 6NF) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Fournisseur_Histo {FourId, Durant}
                KEY {FourId, Durant} ;
    
    Fournisseur_Nom_Histo {FourId, FourNom, Durant}
                KEY {FourId, Durant} ;
    
    Fournisseur_Statut_Histo {FourId, FourStatut, Durant}
                KEY {FourId, Durant} ;
    
    Fournisseur_Ville_Histo {FourId, FourVille, Durant}
                KEY {FourId, Durant} ;
    Tout cela est développé dans la partie « Sixième forme normale » de l’article Bases de données relationnelles et normalisation : de la première à la sixième forme normale, plus particulièrement dans le paragraphe « Données actives et données historisées ».


    Quant au bonhomme NULL :

    Le sort du bonhomme NULL est tout de suite réglé puisqu’il est banni du modèle relationnel. Ainsi Chris Date écrit (cf. Date on Database, Writings 2000-2006, pages 127 et suivantes, je traduis) :

    Une table est normalisée — de façon équivalente, est en première forme normale, 1NF — si elle est la représentation directe et fidèle d’une relation.

    Date précise : « représentation directe et fidèle » veut dire « isomorphe ». Plus précisément, pour mériter le label « normalisée 1NF », la table en question doit préalablement être en conformité avec les cinq obligations suivantes (automatiquement respectées par les relations du modèle relationnel) :
    1. Les lignes n’ont pas à être ordonnées.

    2. Les colonnes n’ont pas à être ordonnées.

    3. Les doublons de lignes sont interdits.

    4. Chaque intersection d’une ligne et d’une colonne contient exactement une valeur du domaine de référence de celle-ci (et rien d’autre).

    5. Toutes les colonnes sont régulières.
    C’est bien sûr le quatrième point qui nous intéresse ici : chaque ligne doit contenir exactement une valeur du domaine (type) approprié pour chaque colonne, en conséquence de quoi l’absence de valeur est en contradiction avec le modèle relationnel et NULL est donc de facto hors-la-loi. Par exemple, en SQL chaque colonne de chaque table doit être définie avec l’option NOT NULL (cf. instruction CREATE TABLE) : si tel n’est pas le cas pour telle table, celle-ci n’est pas la représentation directe et fidèle d’une relation, en conséquence de quoi elle ne peut pas mériter le label « normalisée 1NF ». Autant dire que la 6NF n'a rien à voir dans cette histoire...

    Pour information, concernant le cinquième point, une table ne doit pas avoir de colonnes cachées (sous forme par exemple de « Row ID », d’« Object ID », de Timestamp, etc.)


    Sur ce, je rappelle que la théorie de la normalisation (disons de la 2NF à la 6NF) est orthogonale au modèle relationnel, c'est-à-dire qu’elle n’en fait pas partie, elle relève de la modélisation des données, sujet sur lequel Chris Date a beaucoup écrit.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  13. #73
    Membre éclairé

    Développeur Web
    Inscrit en
    Mars 2002
    Messages
    412
    Détails du profil
    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2002
    Messages : 412
    Points : 657
    Points
    657
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    l’absence de valeur est en contradiction avec le modèle relationnel et NULL est donc de facto hors-la-loi.
    J'ai une question. Prenons les deux tables suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    create table element (
    	element_id integer not null primary key,
    	parent_element_id integer references element(element_id),
    	label varchar(255) not null
    );
     
    create table hierarchy (
    	hierarchy_id integer not null primary key,
    	root_element_id integer not null references element(element_id)
    );
    Le but est de construire des hiérarchies. On a une dizaine de hiérarchies et pour chacune on peut avoir des dizaines de milliers d'éléments.

    Et le problème, c'est l'élément racine d'une hiérarchie dont le champ "parent_element_id" prend la valeur NULL.

    Si l'on voulait éviter cette valeur NULL, on pourrait s'en sortir par héritage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    create table element (
    	element_id integer not null primary key,
    	label varchar(255) not null
    );
     
    create table element_descendant (
    	element_id integer not null primary key references element(element_id),
    	parent_element_id integer not null references element(element_id)
    );
     
    create table hierarchy (
    	hierarchy_id integer not null primary key,
    	root_element_id integer not null references element(element_id)
    );
    Mais est-ce souhaitable ? Car dans notre situation (une poignée d'éléments racines, une foule d'éléments descendants) cela revient à stocker les éléments les plus nombreux dans deux tables, ce qui prend plus de place et est plus lourd à manipuler. On complique le cas général (l'élément en tant que descendant) à cause du cas particulier (l'élément en tant que racine). Quels sont les arguments en faveur de cette solution ?

  14. #74
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Citation Envoyé par laffreuxthomas Voir le message
    le problème, c'est l'élément racine d'une hiérarchie dont le champ "parent_element_id" prend la valeur NULL.
    Vous pouvez remplacer NULL par NOT NULL :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE TABLE element (
        element_id         integer NOT NULL PRIMARY KEY,
        parent_element_id  integer REFERENCES element(element_id) NOT NULL,
        label              varchar(255) NOT NULL
    );

    Un jeu d’essai :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    INSERT INTO element VALUES (1, 1, 'xxx') ;
    INSERT INTO element VALUES (2, 1, 'xxx') ;
    INSERT INTO element VALUES (3, 1, 'xxx') ;
    INSERT INTO element VALUES (4, 2, 'xxx') ;
    INSERT INTO element VALUES (5, 3, 'xxx') ;
    INSERT INTO element VALUES (6, 3, 'xxx') ;
    INSERT INTO element VALUES (7, 5, 'xxx') ;

    Récupération des enfants de element_id = 1 (en prenant soin de ne pas déclencher une boucle infinie ) :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    WITH Recurs (element_id, parent_element_id) AS
    (
      SELECT element_id, parent_element_id
      FROM   element 
      WHERE  parent_element_id = 1    -- point de départ
        AND  parent_element_id <> element_id
      UNION ALL
     (SELECT n.element_id, n.parent_element_id
      FROM   element AS n JOIN Recurs AS r ON n.parent_element_id = r.element_id  
      WHERE  n.parent_element_id <> n.element_id)
     ) 
    -- Au résultat --
    SELECT element_id, parent_element_id
    FROM   Recurs
    ;

    =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    element_id    parent_element_id
    ----------    -----------------
             2                    1
             3                    1
             4                    2
             5                    3
             6                    3
             7                    5

    Voyez aussi la discussion avec Greg221.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  15. #75
    Membre éclairé

    Développeur Web
    Inscrit en
    Mars 2002
    Messages
    412
    Détails du profil
    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2002
    Messages : 412
    Points : 657
    Points
    657
    Par défaut
    Bonsoir et merci pour la réponse. Donc en déclarant l'élément racine comme son propre parent. Bien que la valeur NULL (n/a) soit plus exacte : en réalité la racine n'est pas son propre parent, elle n'a pas de parent.

    Citation Envoyé par fsmrel Voir le message
    Voyez aussi la discussion avec Greg221.
    OK (mais je dois rester compatible MySQL, hééé oui). Je viens aussi de trouver cet exposé en anglais qui propose quatre façons de représenter des arbres en base (diapositives 39 à 69).

  16. #76
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Citation Envoyé par laffreuxthomas Voir le message
    Donc en déclarant l'élément racine comme son propre parent. Bien que la valeur NULL (n/a) soit plus exacte
    Allez expliquer ça à Chris Date ! (j’espère que vous courez vite... )

    A cette occasion, je rappelle que NULL n'est pas une valeur, sinon on resterait dans une logique bivalente.

    Citation Envoyé par laffreuxthomas Voir le message
    En réalité la racine n'est pas son propre parent, elle n'a pas de parent.
    Sémantiquement parlant, c’est exact. J’avais expliqué cela il y a 20 ans aux militaires (plus précisément au colonel H*) à l’occasion de leur modélisation de la hiérarchie au moyen d’une table s’auto-référençant, à la manière de celle que j’ai utilisée :
    Si on procède ainsi, Le général X a sous ses ordres directs les colonels Y et Z et ... lui-même, donc les colonels Y et Z sont au même niveau hiérarchique que le général X, ce qu’après tout les militaires trouvaient intéressant...

    Mais ils ont revu leur modèle, et utilisé une structure parfaitement classique, dans le style de celle que j’ai proposée à Greg221.

    Je vous propose en passant de parcourir la discussion où l’on parle (mais pas avec MySQL, désolé...) d’arbres entremêlés, de forêts (notamment le post #9).
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  17. #77
    Membre éclairé

    Développeur Web
    Inscrit en
    Mars 2002
    Messages
    412
    Détails du profil
    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2002
    Messages : 412
    Points : 657
    Points
    657
    Par défaut
    Encore merci pour les liens, j'ai parcouru.

    J'en suis resté à SQL 92, c'est comme la nouvelle orthographe : d'abord j'attends ses vingt ans, ensuite j'adopte. Non je plaisante, ce n'est pas moi, ce sont les "SGBD" SQLite et MySQL avec lesquels je travaille. Alors, par curiosité, que fait exactement la syntaxe "WITH RECURSIVE" ? Elle crée une sorte de vue temporaire ?

    La journée d'hier a été éclairante. Pour le moment, après avoir réécrit plusieurs fois mon schéma, je suis revenu à la solution de l'adjacence : une simple clé étrangère vers le parent. J'ai plus peur des effets de bord d'une sémantique faussée que de ceux d'une dénormalisation, aussi je garde nullable la clé étrangère vers le parent. J'y ai en outre ajouté la colonne "path" de la méthode du chemin (une colonne textuelle avec une suite d'ID), c'est une redondance qui me permettra de sélectionner tous les descendants en SQL 92.

    Votre exemple de table "ACTIONNAIRE" est proche de la deuxième option sur laquelle j'hésite toujours, à savoir l'héritage, cf plus haut ma table "element_descendant". D'autant plus que j'ai en vérité trois colonnes dans la table "element" qui sont mises à NULL pour l'élément racine et toujours renseignées pour les enfants. Mais ces colonnes nullable ne seront jamais concernées par des opérations ensemblistes, donc j'imagine que la dénormalisation n'engendrera pas de problème ?

  18. #78
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    laffreuxthomas, tu devrais proposer ton MCD dans le forum Schéma mais en tout cas, ça, c'est vraiment affreux, Thomas !
    J'y ai en outre ajouté la colonne "path" de la méthode du chemin (une colonne textuelle avec une suite d'ID), c'est une redondance qui me permettra de sélectionner tous les descendants en SQL 92.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  19. #79
    Membre éprouvé Avatar de redoran
    Homme Profil pro
    Développeur-Amateur
    Inscrit en
    Juin 2010
    Messages
    1 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur-Amateur
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 346
    Points : 1 031
    Points
    1 031
    Par défaut
    salut ; une année après l'intervention de CinePhil , le débat est relancé en poussant la barre plus haut.
    Utilisation d'une solution prête à utiliser et la conception d'une dédiée, l'approche diffère.
    partant de la conception : vous êtes bien placé pour savoir les différentes étapes de la conception à partir de l'étude de l'existant jusqu’à la livraison , je crois si le cadre logique est bien défini et avec utilisation d'une méthode d'analyse du système d’information telle que Merise la modélisation serait en faveur d'optimisation tout en sachant que la méthode est basée sur les mathématiques, aussi que l'information est structurée....
    donc ce qui facilite le passage au modèle logique des données.
    de ce côté je ne vois pas l’intérêt de dénormaliser
    maintenant du côté des SGBDR:
    je crois que le SGBDR est conçu de sorte de prendre en charge les différentes requêtes émises par le client.
    Est-ce que le fait de dénormaliser est lié à la compétence du concepteur de la BDD ou aux limites du SGBDR ?

  20. #80
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Citation Envoyé par laffreuxthomas Voir le message
    Alors, par curiosité, que fait exactement la syntaxe "WITH RECURSIVE" ? Elle crée une sorte de vue temporaire ?
    C’est une vue temporaire. Je fais référence à l’article « Recursion in SQL: Tips and Techniques » paru en 1996 dans DBPD (Database Programming and Design). Son auteur est Donald Chamberlin (Centre de recherche d’IBM), co-inventeur de SQL, en binôme avec Raymond Boyce, mort trop tôt en 1974).

    J’ai extrait ce qui suit de l'article de Chamberlin (qui s’inspire de ce qu’il avait déjà écrit en 1994 avec trois de ses collègues chez IBM, « Extending relational database technology for new applications ») :



    Pour le reste, je vous engage à faire comme dit CinePhil.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

Discussions similaires

  1. [Débutant] Récupérer un élément de la table quand ID==ID
    Par solid_sneak06 dans le forum Silverlight
    Réponses: 11
    Dernier message: 18/05/2012, 19h57
  2. Réponses: 2
    Dernier message: 05/08/2009, 10h30
  3. [FN] Dénormaliser une table de cumuls mensuels
    Par doudou_rennes dans le forum Schéma
    Réponses: 3
    Dernier message: 27/02/2007, 16h18
  4. [DEBUTANT]requete de jointure avec identifiant quand ds une table
    Par tripper.dim dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 17/05/2006, 13h46
  5. Et quand tes tables gonflent trop...
    Par hphil dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 22/03/2005, 15h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo