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

Requêtes MySQL Discussion :

Tinyint Int SmallInt Pour un index(unique, primary Key, index)


Sujet :

Requêtes MySQL

  1. #1
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 123
    Points : 77
    Points
    77
    Par défaut Tinyint Int SmallInt Pour un index(unique, primary Key, index)
    Bonjour à tous,
    je cherche à savoir si le type numérique utilisé permet de réduire la taille de l'index.

    Est-ce que l'utilisation d'un tinyInt par rapport à un int rend l'index moins gros.

    Dans un même registre, hormis les valeurs autorisé, est-ce que l'index est le même entre un int(3), un int(11) et un int ou on ne précise pas la taille?

    3 petites questions, j'ai plusieurs tables qui me permette de donner de droit sur des catégories, sous catégorie
    Le droit sur catégories implique le droit sur toute les sous catégories.
    Ce qui rend mes requêtes (effectué régulièrement) relativement lente car il y a beaucoup de jointure.
    J'avais pensé mettre en place une table de travail. A la connexion de mon user, je vide ses précédents droits, et remet à jour ses nouveaux droits avec uniquement sur les sous catégories. Ce qui permet de simplifier toutes les requêtes le temps de sa connexion. Qu'en pensez-vous?
    Y'a t-il une norme pour ca? A partir de combien de jointure mieux vaut utiliser une autre table pour y stocker des informations qui seront accessible plus rapidement.

    D'avance merci.

  2. #2
    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
    D'après la doc MySQL, un INT occupe 4 octets, un SMALLINT 2 octets et un TINYINT 1 octet.

    Mais bien sûr un TINYINT stockera moins de valeurs qu'un SMALLINT etc.
    Les plages de valeurs acceptées par ces types sont données sur cette autre page de la doc.

    A noter que la précision de la longueur de l'entier est un abus de phpMyAdmin et ne sert à rien : un entier fera toujours 4 octets !

    3 petites questions, j'ai plusieurs tables qui me permette de donner de droit sur des catégories, sous catégorie
    Le droit sur catégories implique le droit sur toute les sous catégories.
    Ce qui rend mes requêtes (effectué régulièrement) relativement lente car il y a beaucoup de jointure.
    J'avais pensé mettre en place une table de travail. A la connexion de mon user, je vide ses précédents droits, et remet à jour ses nouveaux droits avec uniquement sur les sous catégories. Ce qui permet de simplifier toutes les requêtes le temps de sa connexion. Qu'en pensez-vous?
    Euh... c'est peut-être l'effet "vendredi soir" mais je n'ai rien compris !
    Si tu as potentiellement des sous-sous-sous... sous catégories, tu tu retrouves avec une structure arborescente qui peut être modélisée d'une manière différente que ce que l'on a tendance à faire de prime abord, comme l'explique SQLPro dans son tutoriel sur la gestion d'arbres par représentation intervallaire.

    A partir de combien de jointure mieux vaut utiliser une autre table pour y stocker des informations qui seront accessible plus rapidement.
    Ca c'est plutôt une mauvaise question !
    Vouloir créer une autre table pour éviter des jointures revient à dénormaliser le modèle de données et donc à réduire sa fiabilité. Une dénormlisation n'est à faire qu'en dernière solution, après mesure des problèmes et évaluation des solutions sur une base de tests.
    Il y a bien d'autres choses à examiner avant d'en arriver là :
    - Le modèle de données est-il normalisé ?
    - A t-on envisagé les solutions d'héritage et d'identification référentielle ?
    - Les tables sont-elles correctement indexées ? A t-on essayé des index couvrants ?
    - Les requêtes sont-elles optimisées ?
    - Le serveur est-il correctement dimensionné et configuré par rapport au volume de données et à la charge qu'il doit supporter ?
    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 !

  3. #3
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 123
    Points : 77
    Points
    77
    Par défaut
    Donc, le fait que la capacité de stockage des types numériques a bien une influence sur la rapidité de l'index. Ok merci.


    Pour la deuxième partie. Je vais essayer d'expliquer plus en détail, j'ai un outil de demande. Une demande appartient à un workflow, et est classifié au sein d'une catégorie.

    On attribue des droits aux utilisateurs sur un workflow (dans ce cas, il peut voir toute les demandes quelques soit les catégories).
    Ou alors, on lui attribue des droits sur certaines catégories pour éviter qu'il voit tout les demandes du workflow.

    Dans ce cas, la requête serait relativement simple, si il a les droits sur le workflow, je prend tout les demandes, sinon, je regarde tout les demandes appartenant aux catégories où il a les droits.

    Le problème, c'est que les droits données sont en fait donnés pour certains profil particuliers.

    Du coup, je dois récupérer à la fois les demandes pour lesquels il a au minimum un profil attribué pour le workflow et celle où il a au minimum un profil pour les catégories des demandes.

    Pour vérifier les droits unitairement (c'est à dire pour une demande donné), c'est simple, je fais 2 requêtes, je regarde pour le workflow, et ensuite pour la catégorie. Et ensuite je récupère la demande.

    Mais pour récupérer la liste des demandes en cours, je n'ai pas trouvé de solution que de faire une jointure sur les 2 tables de gestion de droit. Ce qui rend la requête compliqué,et assez lente. Ou alors de faire 2 select (ou pour les droits workflow et l'autre pour les droits catégories) et ensuite un union, mais je crois que c'est plus lent.

    C'est pourquoi je me demandé si j'étais pas mieux de garder mes tables tels quels pour la gestion des droits. Mais d'avoir une sorte de cache des droits que je charge à la connexion de l'utilisateur. Et où pour chaque droit donné sur un workflow, je met les droits sur toutes les catégories. Du coup, je ne fais qu'une jointure dans une seule table.

    Je sais pas si j'ai été clair. Ou si ca n'a pas été trop long à lire. mais d'avance merci à ceux qui vont me répondre.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 133
    Points : 117
    Points
    117
    Par défaut
    Citation Envoyé par CinePhil Voir le message

    A noter que la précision de la longueur de l'entier est un abus de phpMyAdmin et ne sert à rien : un entier fera toujours 4 octets !

    Il me semble que cette précision sert quand même avec l'option ZEROFILL.

    Par exemple un entier qui vaut 13.
    On peut le déclarer int tout court ou alors int(5) (par exemple).
    Dans le cas d'int(5) et si on active ZEROFILL, l'affichage du nombre sera 00013 et non 13.

  5. #5
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 123
    Points : 77
    Points
    77
    Par défaut
    Oui, en effet, j'ai vu cette option que je ne connaissais pas . Et pourtant, elle aurait mettre utile bien des fois. Pour les codes postaux, les numéros de facture, etc.

  6. #6
    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 ttropardy Voir le message
    Oui, en effet, j'ai vu cette option que je ne connaissais pas . Et pourtant, elle aurait mettre utile bien des fois. Pour les codes postaux, les numéros de facture, etc.
    Ouh là !
    Un code postal n'est pas un entier ! Les codes postaux de la Corse commencent par 2A ou 2B.
    D'une manière générale, un code n'est pas un nombre mais... un code ! Potentiellement alphanumérique, même si dans l'état actuel des choses il est entièrement numérique. On ne fait jamais de calcul sur un code.

    Idem pour les numéros, qui sont une autre forme de code.
    Aujourd'hui, vous avez une seule société en un seul endroit et vous numérotez vos factures de 0 à n.
    Dans un an, les affaires marchent et vous ouvrez une autre agence ou une filiale et pour différencier les factures vous décidez de faire précéder les numéros d'une lettre ou d'un code encore plus compliqué. Et paf ! vous êtes obligé de changer le modèle de données !

    Revenons à ta "deuxième partie'...
    Une demande appartient à un workflow
    MCD :
    Demande -1,1----Apartenir----0,n- Workflow

    Une demande est classifiée au sein d'une catégorie
    Demande -1,1----Classifier----0,n- Catégorie

    On attribue des droits aux utilisateurs sur un workflow (dans ce cas, il peut voir toute les demandes quelques soit les catégories).
    Ou alors, on lui attribue des droits sur certaines catégories pour éviter qu'il voit tout les demandes du workflow.
    La phrase entre parenthèses étant mal formulée, j'ai du mal à comprendre !
    N'est-ce pas plutôt ceci ?
    (dans ce cas, il peut voir toutes les demandes, quelles que soient les catégories)

    On aurait donc d'une part :
    Utilisateur -0,n----Autoriser----0,n- Workflow

    Et d'autre part :
    Utilisateur -0,n----Autoriser----0,n- Categorie

    En assemblant les schémas précédents, ça donne ceci :
    Utilisateur -0,n----Autoriser----0,n- Workflow -0,n----Appartenir----1,1- Demande
    |----------------0,n----Autoriser----0,n- Categorie -0,n----Classifier----1,1----------|

    Il en découle les tables suivantes :
    Utilisateur (U_Id, U_Nom...)
    Workflow (W_Id, W_Libelle....)
    Categorie (C_Id, C_Nom...)
    Uti_Autoriser_Wkf (UAF_Id_Utilisateur, UAF_Id_Workflow...)
    Uti_Autoriser_Cat (UAC_Id_Utilisateur, UAC_Id_Categorie...)
    Demande (D_Id, D_Id_Workflow, D_Id_Categorie, D_Objet...)

    Quels demandes à le droit de consulter l'utilisateur n° 12 ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT d1.D_Id, d1.D_Objet
    FROM Demande AS d1
    INNER JOIN Workflow AS w ON d1.D_Id_WorkFlow = w.W_Id
      INNER JOIN Uti_Autoriser_Wkf AS uw ON w.W_Id = uw.UAF_Id_Workflow
    WHERE uw.UAF_Id_Utilisateur = 12
     
    UNION
     
    SELECT d2.D_Id, d2.D_Objet
    FROM Demande AS d2
    INNER JOIN Categorie AS c ON d.D_ID_Categorie = c.C_Id
      INNER JOIN Uti_Autoriser_Cat AS uc ON c.C_Id = uc.UAC_Id_Categorie
    WHERE uc.UAC_Id_Utilisateur = 12
    Même avec des dizaines de milliers de lignes, ça ne devrait pas prendre des secondes à donner le résultat.
    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 !

  7. #7
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 123
    Points : 77
    Points
    77
    Par défaut
    Moi actuellement, je faisais une jointure sur les 2 tables de Droit(workflow, catégorie),
    et ensuite dans ma clause WHERE, je récupère uniquement mes demandes où il y a une une ou l'autre des lignes de droits.

    Mais donc, la solution de l'union est plus propre et plus rapide en terme de performance?

    Sur chaque demande, je récupère des infos dans d'autres tables, si je comprend bien, avec la solution de l'union, je suis mieux de, dans un premier temps, récupère tous les Id avec un union, et ensuite de faire une requete pour récupérer les autres infos liés à ma demande

    Ou dans le premier select, je récupère toutes les demandes et infos liés avec les droits de workflow, et union toutes les demandes et infos liés avec les droits de catégorie?

  8. #8
    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
    Si tu nous donnais la structure de tes tables et les requêtes que tu fais ce serait plus facile parce que là tes explication sont un peu trop abstraites.
    Si tu as un MCD ou un MLD de ta BDD c'est encore mieux.
    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 !

  9. #9
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 123
    Points : 77
    Points
    77
    Par défaut
    Me re-voila, désolé pour le temps de réponse, j'avais pas le schéma sous la main.
    Ci-joint une version simplifiée de mon schéma.

    Et mes requêtes.

    Actuellement, j'utilise cette requête qui me plait pas, c'est d'ailleurs celle-ci que je veux modifier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT demandes.demandeId,demandes.info1,demandes.info2,TableLie.monInfo
    FROM demandes
    LEFT OUTER JOIN DroitsCategorie ON demandes.demandeId=DroitsCategorie.demandeId
    JOIN DroitsWorkflows ON demandes.demandeId=DroitsWorkflows.demandeId
    LEFT OUTER JOIN TableLie On TableLie.tableLieId=demandes.tableliee
    WHERE (DroitsCategorie.droitCategorieId IS NOT NULL OR DroitsWorkflows.droitWorkflowId IS NOT NULL)
    Si je reprend l'idée d'utiliser l'UNION, comment doit l'utiliser?

    Comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT demandes.demandeId,demandes.info1,demandes.info2,TableLie.monInfo
    FROM demandes
    JOIN DroitsCategorie ON demandes.demandeId=DroitsCategorie.demandeId
    LEFT OUTER JOIN TableLie On TableLie.tableLieId=demandes.tableliee
     
    UNION
    SELECT demandes.demandeId,demandes.info1,demandes.info2,TableLie.monInfo
    FROM demandes
    JOIN DroitsWorkflows ON demandes.demandeId=DroitsWorkflows.demandeId
    LEFT OUTER JOIN TableLie On TableLie.tableLieId=demandes.tableliee
    Ou comme ceci, ce qui me permet si j'ai beaucoup de tables liés d'éviter d'avoir à les mettre de chaque coté de l'unions.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT demandes.demandeId,demandes.info1,demandes.info2,TableLie.monInfo
    FROM (
        SELECT demandes.demandeId,demandes.info1,demandes.info2
          FROM demandes
        JOIN DroitsCategorie ON demandes.demandeId=DroitsCategorie.demandeId
        UNION
        SELECT demandes.demandeId,demandes.info1,demandes.info2
        FROM demandes
        JOIN DroitsWorkflows ON demandes.demandeId=DroitsWorkflows.demandeId
      ) as demandes
    LEFT OUTER JOIN TableLie On TableLie.tableLieId=demandes.tableliee
    En espérant avoir été plus clair avec ces requêtes et mon schéma.
    Images attachées Images attachées  

Discussions similaires

  1. Différence entre un index Unique et un index primary
    Par hukiro dans le forum Langage SQL
    Réponses: 5
    Dernier message: 12/02/2013, 15h06
  2. Réponses: 2
    Dernier message: 25/11/2010, 11h52
  3. Réponses: 3
    Dernier message: 02/05/2006, 21h36
  4. Réponses: 7
    Dernier message: 27/04/2006, 10h21
  5. PRIMARY KEY - UNIQUE - INDEX
    Par Thierry8 dans le forum Requêtes
    Réponses: 4
    Dernier message: 16/12/2005, 23h28

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