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 :

Simplification de modèle relationnel et avis sur le type SET


Sujet :

Langage SQL

  1. #1
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 021
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    Par défaut Simplification de modèle relationnel et avis sur le type SET
    Bonjour,
    d'une manière générale, j'ai toujours essayé de respecter les formes normales et le principe de l'atomicité des données lors de la conception d'un modèle relationnel. Je me suis souvent retrouvé avec des modèles très complexes et les requêtes qui en découlent (et qui d'ailleurs au final peuvent poser de légers problèmes de consommation des ressources).

    Je me demandais s'il existait des moyens (propres ou non au SGBD) pour simplifier tout cela. Si je prends un cas d'étude simple pour lequel un 'document' peut être lié à plusieurs 'types', ex. : un 'document' peut être de type 'Roman' et 'Poésie'

    En général, j'ai tendance à procéder ainsi, avec 2 tables + 1 table de jointure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    document
    d_id | d_titre
     
    type
    t_id | t_intitule
     
    j_type
    d_id | t_id
    jeu de données qui donnerait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    document
    d_id | d_titre
    1 | Le Val de Rose
     
    type
    t_id | t_intitule
    1 | Roman
    2 | Poésie
     
    j_type
    d_id | t_id
    1 | 1
    1 | 2
    Tout d'abord, pensez-vous qu'il s'agit d'une bonne méthode dans le cas où la table 'type' n'est liée à aucune autre table et qu'en plus un enregistrement ne contient qu'un champ de donnée (i.e. ici l'intitulé) ? Y a-t-il une meilleure méthode ou plus communément utilisée ?

    Je suis en train de réfléchir à l'utilisation du type SET qui pourrait peut-être répondre à ce type de besoin.

    Auriez-vous des avis ou conseils sur l'utilisation du type SET ou sur d'autres techniques qui pourraient exister et simplifier les modèles et les requêtes dans ce même cas d'étude ? Sinon connaissez-vous des désavantages au type SET ? (ressources, recherches partielles/totales, souplesse, problèmes d'index ...)

    En vous remerciant d'avance.
    Vive les roues en pierre

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Je n'ai pas d'avis sur le type SET, mais ce que vous faites est bien la bonne méthode.

  3. #3
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,

    Tout d'abord, pensez-vous qu'il s'agit d'une bonne méthode dans le cas où la table 'type' n'est liée à aucune autre table et qu'en plus un enregistrement ne contient qu'un champ de donnée (i.e. ici l'intitulé) ? Y a-t-il une meilleure méthode ou plus communément utilisée ?
    Oui, non, non.

    Je suis en train de réfléchir à l'utilisation du type SET qui pourrait peut-être répondre à ce type de besoin.

    Auriez-vous des avis ou conseils sur l'utilisation du type SET ou sur d'autres techniques qui pourraient exister et simplifier les modèles et les requêtes dans ce même cas d'étude ? Sinon connaissez-vous des désavantages au type SET ? (ressources, recherches partielles/totales, souplesse, problèmes d'index ...)

    Oui, pour moi c'est une très mauvaise idée.

    Je ne comprend pas en quoi la requête est compliquée en fait ? Faire 1 ou 2 jointures de plus est si fatiguant que ca ?

    Pour les désavantages que je vois (vu qu'on ne connait pas votre SGBD...) :
    - Maintient horrible : obliger de faire un alter table pour ajouter / enlever une occurance du set
    - Requête pas vraiment simplifiée vu qu'il faudra utiliser des fonctions spécifique au sgbd pour arriver à travailler avec les set
    - Peut devenir source de contention / lock si forte activité autour de la table document ou affectation d'activité (plus qu'une table au lieu d'une table d'association)
    - Est-ce les update / delete, sur votre SGBD seront aussi performant ? (c'est facile à tester)

  4. #4
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 021
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    Par défaut
    Merci beaucoup pour vos réponses et conseils

    A la base, je pensais à la solution du SET (ou autres) dans le but d'optimiser les exécutions de requêtes mais aussi leurs écritures. Il me semble que cela simplifierait pas mal le code étant donné qu'on peut beaucoup réduire le nombre de tables.
    Comme dans certains modèles complexes, on peut parfois se retrouver avec plus d'une dizaine de jointures, je pense que ça pourrait réduire la complexité du code des requêtes mais aussi les ressources étant donné qu'on fait des SELECT sur moins de tables. (En fait, parfois ça n'est pas une ou deux jointures de moins que l'on aurait, il me semble que j'ai des modèles où cela en supprimerait bien 5 ou 6, mais peut-être que je suis trop gourmand sur ce que je veux récupérer en une seule fois)

    Il est vrai que les ALTER TABLE pour un SET/ENUM ne m'ont jamais inspiré ; sur ce coup-là j'étais plutôt dans une optique de sélection des données (sur un modèle statique, si je puis dire) plutôt que d'insert/update/delete, car c'est plutôt sur des SELECT que je peux parfois rencontrer quelques problèmes de performance mais ça semble mauvais de penser un modèle uniquement pour un type de traitement. (Et il y a sans doute d'autres optimisations que je puisse faire dans des modèles/scripts avant de "bousiller" des modèles de données )

    En fait, je croyais que SET et ENUM faisaient partie de la norme SQL et apparemment non, ce qui me dérange fortement. Je pense que je ferai des tests par curiosité mais je vais suivre les conseils et continuer dans la voie que j'ai suivie jusqu'ici. (Merci pour les désavantages proposés, 3 sur 4 auxquels je n'avais pas pensé)

    Je me posais encore 2 petites questions, si l'on respecte la norme SQL, le principe des formes normales, et que l'on veut stocker des "titres/qualificatifs" de personnes (Monsieur, Madame, Abbé, etc.), on aura également 3 tables dont une d'association ?

    Question un peu plus vague et sans doute un peu trop lié au SGBD mais cela vous arrive-t-il parfois de ne pas faire toutes les jointures nécessaires au jeu de données attendu en une seule requête mais, à partir de l'exemple extrêmement restreint présenté dans mon premier post, de récupérer tous les documents puis exécuter un nouveau SELECT pour chaque document afin de récupérer des données périphériques liées. Cela augmente considérablement le nombre de requêtes mais, dans mon souvenir, j'ai eu parfois de meilleurs performance dans certains cas. Auriez-vous des avis quelconques sur ce type de pratique ?
    Vive les roues en pierre

  5. #5
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Citation Envoyé par Djakisback Voir le message
    Je me posais encore 2 petites questions, si l'on respecte la norme SQL, le principe des formes normales, et que l'on veut stocker des "titres/qualificatifs" de personnes (Monsieur, Madame, Abbé, etc.), on aura également 3 tables dont une d'association ?
    Non, deux seulement, à moins que tu ne veuilles avoir des personnes pouvant avoir plusieurs titres.

    Question un peu plus vague et sans doute un peu trop lié au SGBD mais cela vous arrive-t-il parfois de ne pas faire toutes les jointures nécessaires au jeu de données attendu en une seule requête mais, à partir de l'exemple extrêmement restreint présenté dans mon premier post, de récupérer tous les documents puis exécuter un nouveau SELECT pour chaque document afin de récupérer des données périphériques liées. Cela augmente considérablement le nombre de requêtes mais, dans mon souvenir, j'ai eu parfois de meilleurs performance dans certains cas. Auriez-vous des avis quelconques sur ce type de pratique ?
    Si cela arrive, c'est que le SGBD ne raisonne pas bien Probablement par manque d'infos au niveau des stats. Cela dit, unitairement (ie quand je passe des requêtes à la main), ça m'arrive assez souvent de le faire, mais c'est plus par flemme d'écrire une requête complète et pour avoir accès à des informations intermédiaires si les résultats ne me vont pas. Pour les requêtes "applicatives", j'essaie de réduire au maximum le nombre de requêtes.

  6. #6
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 021
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    Par défaut
    Merci, il faudrait que je me forme un peu plus en administration de base de données pour mieux comprendre ces principes-là.

    Citation Envoyé par Rei Ichido Voir le message
    Non, deux seulement, à moins que tu ne veuilles avoir des personnes pouvant avoir plusieurs titres.
    merci, effectivement. (En général j'utilise majoritairement le ENUM pour ces cas-là).
    Vive les roues en pierre

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Citation Envoyé par Djakisback Voir le message
    Je suis en train de réfléchir à l'utilisation du type SET qui pourrait peut-être répondre à ce type de besoin.

    Auriez-vous des avis ou conseils sur l'utilisation du type SET ou sur d'autres techniques qui pourraient exister et simplifier les modèles et les requêtes dans ce même cas d'étude ?
    Tout d'abord SET n'est pas un type répandu dans les SGBDs. Supposons qu'on parle en fait ici de mysql, dont la doc présente le type SET comme assimilable à un champ de 64 bits.
    Ca, on peut toujours le faire dans tous les SGBDs avec un entier pour une taille fixe ou une chaine de caractères, ou même un champ binaire sans taille max.

    Dans certains cas spécifiques ça peut effectivement être très performant. Par exemple pour associer jusqu'à 32 tags à des documents dans un champ de 32 bits, on peut savoir si tel document a les tags A et B et n'a pas les tags D ou E en lisant uniquement un champ entier dans la table document sans aucune jointure. Cette lecture est beaucoup plus performante qu'une multi-jointure sur une table (doc_id,tag_id) et le gain de place est également considérable.

  8. #8
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 021
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    Par défaut
    Effectivement, pour ce type d'opération, dans le sens gestion de flags si je comprends bien, ça semble intéressant. Apparemment, on doit pouvoir travailler aussi directement en binaire dessus. Merci pour cette précision, j'avais zappé ça dans la doc MySql
    Vive les roues en pierre

  9. #9
    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
    Quelques bonnes pratiques...

    1) Construire un modèle de données normalisé au maximum.

    2) Utiliser des vues.
    Ce sont elles qui vont éventuellement contenir des jointures multiples mais ensuite les requêtes applicatives sur les vues sont beaucoup plus simples.

    3) Ne récupérer que les informations dont on a besoin.
    Si vous voulez afficher une liste de documents avec juste le titre et l'auteur, inutile de récupérer sa version, sa date de création, de révision, le texte du résumé...
    C'est ensuite lors du clic sur le titre du document qu'on aura besoin d'afficher d'autres informations.
    Il ne faut pas multiplier les requêtes inutiles mais il faut faire les requêtes nécessaires.

    4) Si vous avez un grand volume de données (à partir de plusieurs centaines de milliers de lignes dans certaines tables), prototypez la montée en charge sur les requêtes les plus gourmandes pour voir "si ça tient".
    Identifiez les points chauds et commencez par tester la modification et/ou la création d'index.
    Ensuite seulement, vous pourrez vous pencher sur la dénormalisation de certaines données, toujours en mesurant les résultats sur votre prototype.

    Voir au sujet des index l'article de SQLPro.
    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 !

  10. #10
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 021
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    Par défaut
    Merci pour ces conseils supplémentaires.
    Je pense être au point avec les points 1, 3 et la gestion des index mais n'ai jamais pratiquement utilisé les vues et ne connaît pas bien l'administration de BDD, il faudra que je m'y mette à l'occasion.
    Vive les roues en pierre

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2010] Modèle relationnel pour avis
    Par hugue dans le forum Modélisation
    Réponses: 4
    Dernier message: 02/03/2014, 13h52
  2. Avis sur modèle relationnel
    Par hugue dans le forum Modélisation
    Réponses: 8
    Dernier message: 14/04/2013, 21h45
  3. Hésite sur modèle relationnel
    Par amartik dans le forum Modélisation
    Réponses: 4
    Dernier message: 18/01/2010, 00h27
  4. Modèle relationnel sur SQL 2005 ?
    Par devdev dans le forum Développement
    Réponses: 2
    Dernier message: 22/04/2009, 08h42

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