Partage
  • Partager sur Facebook
  • Partager sur Twitter

Structure des tables de base des donnée

    17 janvier 2023 à 23:15:16

    Bonjour,

    Je dois créer une très grosse application, donc les performances de ma base de données doivent être très bonnes.

    J'ai donc lu un cours SQL dans le cours il y a un passage qui dit qu'il faut éviter d'avoir trop de colonne dans ces tables.

    Il donne un exemple de ce qu'on pouvait faire avant et ce qu'on devrait faire maintenant :

    avant :

    table "PERSONNE" : ID, nom, prenom, date_de_naissance, numero_voie, BIS, adresse, suite_adresse, ID_VILLE, numero_telphone1, numero_telephone2
    
    table "VILLE" : ID, code_postal, nom

    après :

    table "PERSONNE" : ID, nom, prenom, date_de_naissance, ID_ADRESSE, ID_VILLE
    
    table "ADRESSE" : ID, numero_voie, BIS, adresse, suite_adresse, ID_VILLE
    
    table "VILLE" : ID, code_postal, nom
    
    table "PERSONNE_TELEPHONE" : ID, ID_TELEHONE
    
    table "TELEPHONE": ID_TELEPHONE, prefix, num1, num2, num3, num4, num5

    Il dise dans le cours que chaque entité devienne indépendante et que ça permet de réutiliser la table "ADRESSE" pour une autre table (ex : "ETABLISSEMENT : ID, nom, ID_ADRESSE").

    J’avoue que cela me plait beaucoup, mais dans le cours il ne dise pas comment résoudre un de mes problèmes, dans mon appli j'ai beaucoup de listing des tableaux de données sauf que dans mon appli j'ai beaucoup de donnée non obligatoire (ex : adresse, téléphone).

    avant j'avais juste à faire ça :

    select p.ID, p.nom, p.prenom, p.date_de_naissance, p.numero_voie, p.BIS, p.adresse, p.suite_adresse, p.numero_telphone1, p.numero_telephone2, p.ID_VILLE, v.code_postal, v.nom from personne p
    inner join ville v on v.ID=p.ID_VILLE;

    maintenant il va falloir faire ça :

    select p.ID, p.nom, p.prenom, p.date_de_naissance, a.numero_voie, a.BIS, a.adresse, a.suite_adresse, a.ID_VILLE, v.code_postal, v.nom from personne p
    left join adresse a on a.id=p.ID_ADRESSE
    left join ville v on v.ID=a.ID_VILLE
    left join ...
    left join ...
    left join ...
    left join ...
    left join ...
    left join ...;


    Vu que je vais avoir beaucoup de donnée non obligatoire je vais me retrouver avec 2 tonnes de "left join" pour chaque donnée non obligatoire.

    sauf que les "left join" ralentisse énormément les requête SQL.

    j'ai trouvé quelque solution sur internet dite moi celle que vous me conseillé, mais si vous avez d'autre je suis preneur.

    1er solution : faire des vues avec des "union all" prenant tous les cas en compte (personne sans adresse, personne avec adresse, ...)

    sauf que les vues vont être gigantesque

    2ième solution :

    Quand je crée la table "ADRESSE" je rajoute un champ "renseigner" et donc même si la personne n'a pas d'adresse elle aura une entrée dans "adresse" mais à vide :

    table "ADRESSE" : ID, renseigner, numero_voie, BIS, adresse, suite_adresse, ID_VILLE


    3ième solution :

    les sous requêtes, mais le problème ces les "order by" qu'il faudra que je fasse en PHP ce qui est vraiment mauvais.

    select * from personne order by nom, prenom;
    ------> select * from adresse where ID=:ID_ADRESSE;
    


    Cordialement wandapanel.

    -
    Edité par wandapanel 17 janvier 2023 à 23:17:23

    • Partager sur Facebook
    • Partager sur Twitter
      17 janvier 2023 à 23:55:05

      Comme ça, je te dirais de faire des procédures. Tu prépares toutes celles que tu comptes faire. Et tu les appelles en fonction des conditions que tu auras données. Tu feras le bon nombre de left join.

      Je ne sais pas si c'est possible, mais, si tu peux mettre 1 paramètre d'entrée sous forme de tableau dynamique (ne contient pas toujours x éléments), tu pourrais ne faire qu'une seule procédure et c'est dans son contenu que tu géreras les différents cas.

      Il faut parfois faire des concessions sur les optimisations. Pense d'abord à ce qui est humainement acceptable. Mieux vaut une base de données bien compartimentée quitte à ce que l'insertion d'une nouvelle personne prenne du temps ? Et dans ce cas, tu permets en parallèle la visite de ton app par exemple. Ou une insertion rapide car tout dans une seule table, mais avoir des opérations de lecture très lente à cause des doublons ou de la multitude d'index ? Logiquement on fait peu d'opérations d'écriture et beaucoup d'opération de lecture. Et concernant les mises à jour, on fait au préalable une opération de lecture pour bien indiquer où se font les changements.

      • Partager sur Facebook
      • Partager sur Twitter
        17 février 2023 à 15:41:55

        Hello,

        C'est vrai qu'on préconise souvent d'éviter les tables avec des trop grand nombres de colonnes, mais il faut voir ce qu'on appelle "trop grand nombre".

        Dans ton cas, tu en as 13, et 13 c'est clairement pas trop. Trop c'est quand on passe les plusieurs dizaines, voir les centaines.

        Dans tous les cas, le but est surtout d'éviter d'avoir à dupliquer les données. Si tu as une adresse qui est utilisé par 50 personnes, alors oui il faut une table juste pour ca (disons dans le cas d'une adresse d'un établissement scolaire par exemple). Mais dans le cas où chaque personne aurait une adresse différente ... Alors non il faut éviter d'avoir une table dédiée à ça.

        Il y a plusieurs avantages et risques aux 2.

         1/ 2 tables : Dans le cas d'un lycée par exemple, si le numéro de la rue change parce que la numérotation de la ville a changé, tu ne dois update qu'une seule ligne. Pratique. Et vu que c'est une adresse utilisée par beaucoup de monde, c'est rentable.

        2/ 1 table : Pour des adresses personnelles, il faut éviter je pense d'avoir 1 table dédiée. Imaginons même le cas d'une famille, si une personne de la famille vient à déménager, c'est + simple d'avoir à traiter que sa ligne dans la table personne pour l'adresse, plutot que de devoir créer une nouvelle ligne dans la table adresse puis changer l'id. 

        D'autant + que si tu as une seule personne à une adresse, et qu'elle déménage, tu vas préférer update la ligne de Adresse ? ou en créer une nouvelle puis changer la clef 2daire ? Si tu changes l'adresse, il faut bien vérifier qu'elle est utilisé par personne => pas pratique. Si tu en crées une nouvelle, ca veut dire que l'ancienne existera en base, mais ne sera plus utilisé => pas ouf non plus.

        En gros ca demanderait de devoir faire des SELECT de vérification pour adopter le bon comportement pour ne pas faire de bêtise, ou bien commencer à polluer avec des adresses historiques non utilisés, et donc potentiellement mettre en place un batch de purge.

        Bilan : Y'a pas de solution parfaite, ca va dépendre de tes besoins, et il faut trouver le juste milieu.

        Typiquement, la table Ville, ca se fait. C'est quelque chose de redondant en terme de donner, et tu as moyen de trouver des données brutes sur le site du gouvernement pour peupler ta table avec toutes les infos nécessaires.

        La table Adresse, ca va dépendre de ton utilisation, si c'est du 1 pour 1 en nombre de ligne avec Personne, alors c'est non, si c'est un vrai 1 ou n, alors oui pourquoi pas. Mais garder en tête les limites d'avoir une adresse partagée si on veut la changer pour une personne.

        La table Telephone : c'est non. Avec tous les numéro de portable, tu auras un numéro par personne, alors met directement le numéro. Et dans les rares cas ou ca peut être partagé ... on s'en fout presque.

        Et du coup la table de correspondance Personne_Telephone, encore pire. Ca ca ne sert que quand tu as des gens qui ont plusieurs numéros, et quand un numéro peut être partagé. y'a un monde ou ca existe avec les numéros fixe, mais en vrai ca vaut pas le coup de se prendre la tête à gérer 3 tables alors que tu as juste à mettre 2 colonnes de numéro dans la table Personne (tel_portable et tel_fixe).

        Ensuite pour le requêtage, il faut prendre en compte la volumétrie. Suivant ton projet, le nombre de personne peut monter, mais est-ce que ca va passer les milliers ? les millions ?

        Si on parle de milliers, alors on s'en fout complètement en vrai, dans tous les cas ca va pendre 0.1s si correctement indéxé.

        Si on parle de millions, ca reste pas un truc de fou non plus si elle est bien rangé, avec de bons indexes, et que tu mets des clause where comme il faut.

        A ta place, j'aurais 2 tables : Personne et Ville

        • Partager sur Facebook
        • Partager sur Twitter

        Structure des tables de base des donnée

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown