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 :

Schéma SQL et nouvelle constuction par type


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2021
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Novembre 2021
    Messages : 7
    Points : 18
    Points
    18
    Par défaut Schéma SQL et nouvelle constuction par type
    Bonjour,

    Je vais bientôt devoir développer une grosse application.

    J'ai lu un tutoriel qui explique une nouvelle manière de concevoir un schéma de base de données, il disait de créer des tables par types de donnée exemple :
    table "adresse" : ID, voie, suite, code_postal, ville
    table "telephone": ID, indicatif, n1, n2, n3, n4, n5
    table "email": ID, nom, domain
    table "personne" : ID, nom, prenom, ID_ADRESSE, ID_TELEPHONE, ID_EMAIL

    Et plus par le métier exemple :
    table "personne" : ID, nom, prenom, voie, suite, code_postal, ville, telephone, email

    Il disait que ça permettait d'éviter d'avoir trop d'index, pour faire des statistiques plus facile, et pour faire évoluer un type de donnée plus facilement, exemple :
    On rajoute BIS aux adresses d'un coup, la totalité de mes adresses dans mon application aura la gestion du BIS.
    Si je veux avoir tous les numéros commençant par 06.
    etc...

    J'avoue que je trouve ça génial, mais mon application va avoir des listings qui vont dépasse le million de lignes.
    Bien sûr, je vais faire une pagination de 100 lignes par page.

    Mon problème vient du tri, ils doivent pouvoir faire le tri par téléphone, adresse ou email, ....
    Sauf que l'adresse, le téléphone et l’e-mail ne sont pas obligatoire.

    Donc je vois certaines solutions, mais j'aimerais que vous me disiez laquel serais la meilleure :
    1re solution : les left join, je n'aime pas cette méthode, car les left join font ralentir considérablement les requêtes sql.
    2e solution : mettre des données à vide dans les tables telephone, email, adresse, peut être rajouter un champ tel que :
    table "adresse" : ID, renseigner, voie, suite, code_postal, ville
    table "telephone": ID, renseigner, indicatif, n1, n2, n3, n4, n5
    table "email": ID, renseigner, nom, domain
    3e solution : récupérer en PHP et faire le tri en PHP, mais je ne pourrais pas utiliser LIMIT
    4e solution : faire des vues avec des unions avec toutes les alternatives (personne s'en rien, personne avec telephone, personnel avec email, personne avec telephone et email, ...)
    Mais ça risque d'être compliqué à force.

    pour moi la meilleur solution est la 2ième, aujourd'hui on a des disque dur énorme.

    Si vous avez d'autres solutions, je suis preneur.

    Cordialement Jérémy.

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 311
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 311
    Points : 39 677
    Points
    39 677
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Citation Envoyé par wandapanel Voir le message
    Je vais bientôt devoir développer une grosse application.
    J'ai lu un tutoriel qui explique une nouvelle manière de concevoir un schéma de base de données, il disait de créer des tables par types de donnée
    La bonne démarche est de ne pas réfléchir aux tables.
    Pour modéliser correctement, il est préférable et bien plus simple de commencer par le modèle conceptuel, le MCD.
    Le préalable au MCD c'est l'établissement du dictionnaire de données et des règles de gestion.

    Quand le MCD est validé, on obtient en un clic un modèle tabulaire (MLD ou MPD au choix).

    Par analogie, avec la construction d'une maison, le MCD c'est le plan, et les tables ce sont les sacs de ciment, les parpaings et autres matériaux constitutifs. Or, on valide bel et bien le plan avant de décider des matériaux.


    Citation Envoyé par wandapanel Voir le message
    exemple :
    table "adresse" : ID, voie, suite, code_postal, ville
    table "telephone": ID, indicatif, n1, n2, n3, n4, n5
    table "email": ID, nom, domain
    table "personne" : ID, nom, prenom, ID_ADRESSE, ID_TELEPHONE, ID_EMAIL
    Positionner la ville et le code postal dans la table des adresse implique de répéter autant de fois ces informations qu'on a d'adresses dans cette ville.
    C'est donc une redondance. Le jour où la ville change de nom (des petites communes sont concernées à peu près à chaque élection municipale où certaines sont contraintes de fusionner faute de candidats), il faut mettre à jour en masse toutes les adresses !
    Le bon modèle est donc d'avoir au niveau conceptuel une entité-type [ADRESSE] associée à une entité-type [VILLE], ainsi, chaque ville n'est enregistrée qu'une seule fois.
    Pour les personnes, si les identifiants du téléphone, du mail et de l'adresse sont dans la table des personnes, ça implique que chaque personne ne peut avoir qu'un seul téléphone, qu'un seul mail, qu'une seule adresse.
    C'est peut-être satisfaisant dans votre contexte, peut-être pas. Le rôle des règles de gestion validées par la MOA est justement de préciser tout ça.
    Selon le cas, il faudra peut-être prévoir de procéder autrement.


    Citation Envoyé par wandapanel Voir le message
    Et plus par le métier exemple :
    table "personne" : ID, nom, prenom, voie, suite, code_postal, ville, telephone, email
    Ca c'est un modèle à plat type tableur, si une personne a plusieurs téléphones, email ou adresses, il faut répéter les lignes.
    Ce type de modèles est simple conceptuellement, mais comporte les risques d'erreurs liés aux redondances et pénalise les performances.
    C'est ce qu'on appelle des "tables obèses" où pléthore de colonnes cohabitent, ce qui implique une pléthore d'index et une pléthore de verrous concurrents.


    Citation Envoyé par wandapanel Voir le message
    Il disait que ça permettait d'éviter d'avoir trop d'index, pour faire des statistiques plus facile, et pour faire évoluer un type de donnée plus facilement,
    C'est tout le contraire, mettre à la fois le nom, le prénom, l'adresse, le numéro de téléphone... dans une même table, fait que les applications qui utilisent les informations sur la personne et celles qui utilisent les informations sur les adresses accèdent à la même table. Elle sont donc concurrentes bien que les données utilisées soient différentes. À l'inverse, un découpage pertinent des tables facilite les accès concurrents.
    Mais si on modélise en commençant par le MCD, on n'a même pas à se poser ces questions, les tables n'étant qu'une conséquence du MCD.



    Citation Envoyé par wandapanel Voir le message
    exemple :
    On rajoute BIS aux adresses d'un coup, la totalité de mes adresses dans mon application aura la gestion du BIS.
    Si je veux avoir tous les numéros commençant par 06.
    Pas compris, désolé


    Citation Envoyé par wandapanel Voir le message
    J'avoue que je trouve ça génial, mais mon application va avoir des listings qui vont dépasse le million de lignes.
    Bien sûr, je vais faire une pagination de 100 lignes par page.
    D'une part, il ne faut pas confondre la structuration de la base de données et le volume de données à traiter
    D'autre part, un listing d'un tel volume n'a aucun autre intérêt que de participer à la déforestation et enrichir le papetier du coin.
    Qui ira lire un pavé pareil ? Personne !


    Citation Envoyé par wandapanel Voir le message
    Mon problème vient du tri, ils doivent pouvoir faire le tri par téléphone, adresse ou email, ....
    Sauf que l'adresse, le téléphone et l’e-mail ne sont pas obligatoire.
    Ces considérations relatives aux traitements sont à voir dans un deuxième temps, elles sont sans rapport avec la modélisation des données


    Citation Envoyé par wandapanel Voir le message
    Donc je vois certaines solutions, mais j'aimerais que vous me disiez laquel serais la meilleure :
    1re solution : les left join, je n'aime pas cette méthode, car les left join font ralentir considérablement les requêtes sql.
    2e solution : mettre des données à vide dans les tables telephone, email, adresse, peut être rajouter un champ tel que :
    [...]
    3e solution : récupérer en PHP et faire le tri en PHP, mais je ne pourrais pas utiliser LIMIT
    4e solution : faire des vues avec des unions avec toutes les alternatives (personne s'en rien, personne avec telephone, personnel avec email, personne avec telephone et email, ...)
    Idem, ces considérations sont prématurées tant que le modèle de données n'est pas stabilisé.
    Toutefois quelques remarques
    • une jointure OUTER ne ralentit pas les requêtes SQL si le prédicat de jointure est "Sargable" (indexable), elle ramène seulement potentiellement plus de lignes qu'une jointure INNER, ce qui n'est pas la même chose ;
    • les "données à vide" sont le symptôme d'une modélisation mal faite, à plat. Avec un MCD bien construit, on dérive un modèle tabulaire propre, dans lequel ce genre d'artifice est inutile ;
    • faire un tri des données coté application sera le plus souvent bien moins rapide que coté BDD ;
    • l'utilisation de vues est recommandé quoiqu'il arrive pour garantir l'indépendance des données et des traitements. Les traitements ne devraient jamais directement accéder aux tables. Mais les vues n'ont pas vocation à masquer une modélisation bancale, on en revient au même point : il faut commencer par le MCD pour éviter tous ces travers.


    Il y a un forum consacré à la modélisation des données, je vous recommande chaudement de commencer par là.
    Il se trouve ICI

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 874
    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 874
    Points : 53 037
    Points
    53 037
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par wandapanel Voir le message
    ...
    Donc je vois certaines solutions, mais j'aimerais que vous me disiez laquel serais la meilleure :
    1re solution : les left join, je n'aime pas cette méthode, car les left join font ralentir considérablement les requêtes sql.
    C'est une affirmation parfaitement stupide car dénuée de tout fondement. Un LEFT OUTER JOIN n'est ni plus ni moins rapide qu'un INNER JOIN. C'est comme si vous compariez un lave linge a un lave vaisselle. C'est pas la même fonction ! De plus, je peux vous montrer quantité de LEFT OUTER JOIN qui vont plus vite que des INNER JOIN... !
    2e solution : mettre des données à vide dans les tables telephone, email, adresse, peut être rajouter un champ tel que :
    table "adresse" : ID, renseigner, voie, suite, code_postal, ville
    table "telephone": ID, renseigner, indicatif, n1, n2, n3, n4, n5
    table "email": ID, renseigner, nom, domain
    Une base c'est du stockage, surcharger la base avec des données inutiles, c'est perdre en performances de manière systématique aussi bien en production qu'en maintenance...
    3e solution : récupérer en PHP et faire le tri en PHP, mais je ne pourrais pas utiliser LIMIT
    Un SQGDR utilise des index qui sont déjà trié pour présenter des données triées. Impossible de faire cela en PHP. De plus les grand SGBDR (SQL Server en particulier) font du parallélisme sur les grosses requêtes... Serez vous capable de faire un tri multithreadé en PHP ???
    4e solution : faire des vues avec des unions avec toutes les alternatives (personne s'en rien, personne avec telephone, personnel avec email, personne avec telephone et email, ...)
    Une une vue est une requête auquel on a donné un nom... Autrement dit à chaque fois que vous appelez la vue dans une commande SQL SELECT, vous forcez le moteur à relire toutes les données. utiliser les vues comme cela n'a aucun sens !

    Mais ça risque d'être compliqué à force.

    pour moi la meilleur solution est la 2ième, aujourd'hui on a des disque dur énorme.

    Si vous avez d'autres solutions, je suis preneur.

    Cordialement Jérémy.
    Vous vous posez les mauvaises questions.... La réponse est de faire un modèle réellement relationnel. Si l'est réellement (et rares sont les bases respectueuses des principes du relationnel) alors vous aurez de la performance, même avec des centaines de millions de lignes, car l'indexation sera simple et facile. Tout autre conception est vouée à l'échec tôt ou tard...

    En fait un SGBD Relationnel est fait pour gérer des relations... C'est stupide de le redire, mais la plupart des développeurs sont convaincu du contraires et font tout ce qu'il ne faudrait pas faire.

    Pour information, une relation est un objet mathématique dont la définition est la suivante :
    collection d'attributs typés par un domaine scalaire permettant de représenter les informations à stocker sans redondance et sans absence, et doté d'une clé.
    L'art de la modélisation consiste à :
    • créer des relations contenant uniquement les données propres (par opposition aux données relatives)
    • ne pas avoir de NULL
    • ne pas avoir de redondance
    • faire en sorte que la modification d'une valeur ne conduise pas à modifier plus d'une ligne d'une table.


    A +

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 17/08/2007, 15h51
  2. charger nouvelle page par clic sur bouton (pas pop-up)
    Par michaelbob dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 12/09/2005, 16h04
  3. Réponses: 4
    Dernier message: 29/06/2005, 11h40
  4. SQL Server / Fonction définie par l'utilisateur
    Par borgfabr dans le forum Langage SQL
    Réponses: 3
    Dernier message: 08/03/2005, 15h14
  5. [SQL Server] Error converting data type varchar...
    Par Sir Tengu dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 13/06/2003, 10h46

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