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 :

Regroupement/Optimisation de tables identiques


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    228
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 228
    Points : 113
    Points
    113
    Par défaut Regroupement/Optimisation de tables identiques
    Bonjour,

    Pour mon premier projet SQL, je dois migrer une base de données DBF en base Firebird 3 sous Delphi. J'ai récupéré la modélisation faîtes sous DBF, certaines tables sont identiques (cf. image ci-dessous) et je pense qu'il doit exister une méthode pour regrouper et optimiser l'ensemble sous FB. Est-ce que je peux externaliser chaque champ code_table et commentaire de toutes les tables ? Si oui, comment représenter l'ensemble ? Comment optimiser les requêtes ?

    Merci pour vos conseils

    Nom : DB_Test.png
Affichages : 224
Taille : 40,3 Ko

  2. #2
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    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 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Sans plus de détails "fonctionnels", c'est un peu compliqué de répondre de manière ferme.

    Votre problématique ressemble grandement aux classiques tables "catalogue".

    C'est à dire par exemple des couleurs, des unités de mesure, des classifications non hiérachiques, etc.

    Souvent, dans les logiciels type "ERP" ou le nombre de ces catalogues n'est pas figé et peu évoluer dans le temps, on trouve des tables "poubelles" avec 3 colonnes : "code catalogue, id, nom".

    Ça se traduit par des lenteurs "inexpliquables" (mon cul, c'est tout à fait explicable, c'est juste modélisé comme de la merde) et des limitations (hiérarchie impossible ou uniquement limitée aux catalogues entre eux) ou des abominations (20 colonnes à NULL pour chaque ligne, car "au cas où on sait jamais si on a besoin d'un attribut pour un des catalogues"), etc.

    Donc non, 1 entité = 1 table. Même si elle a la même structure.

    Comme ça, le jour où une des entités évolue (hiérarchie, ajout d'attributs, de contraintes, etc.) il n'y a pas d'impact sur les autres.

    Comme le suggère SQLPro dans d'autres sujet, cela ne vous dispense pas d'une vue qui concatène toutes ces entités à grand coup de UNION ALL pour charger en mémoire (cache) la liste de toutes vos valeurs de catalogues en une seule requête.
    On ne jouit bien que de ce qu’on partage.

  3. #3
    Membre régulier
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    228
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 228
    Points : 113
    Points
    113
    Par défaut
    Bonjour StringBuilder,

    Merci pour votre message et vos conseils.

    Pour expliciter la partie fonctionnelle, chaque table correspond à un élément d'une voiture (roue, volant, porte...) et l'ensemble (table_source) correspond à la voiture complète.

    Pour résumer, il vaut mieux "exploser" le plus possible les tables pour une meilleure optimisation même si on prend plus de place sur le disque (à cause de la multiplication des champs type varChar(255)).

  4. #4
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    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 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lefju cabro Voir le message
    Bonjour StringBuilder,

    Merci pour votre message et vos conseils.
    De rien, on est là pour ça

    Citation Envoyé par lefju cabro Voir le message
    Pour expliciter la partie fonctionnelle, chaque table correspond à un élément d'une voiture (roue, volant, porte...) et l'ensemble (table_source) correspond à la voiture complète.
    Ok, donc on est bien dans un cas où "demain" votre modèle pourra évoluer : la roue peut avoir différentes jantes, de différents matériaux, diamètre, largeur, etc.
    Idem pour le volant qui peut avoir différentes finitions, diamètres, etc. Potentiellement, la porte aura des options, etc.
    => Donc il est beaucoup plus sage d'avoir une table par attribut plutôt qu'une table poubelle qui contient tout : car si demain on doit stocker les options de la porte est les dimensions de la roue dans la même table, on va multiplier les colonnes "poubelle" (null pour 99% des lignes, et d'un d'un type "générique" afin de permettre n'importe quelle valeur de n'importe quel attribut).

    Citation Envoyé par lefju cabro Voir le message
    Pour résumer, il vaut mieux "exploser" le plus possible les tables pour une meilleure optimisation même si on prend plus de place sur le disque (à cause de la multiplication des champs type varChar(255)).
    Oui, en revanche, contrairement à ce que vous croyez, ça prend moins de place d'avoir N petites tables sans colonnes inutiles et des type des données adaptés aux besoin plutôt qu'une table avec 30 colonnes nulles et des DECIMAL(40) pour stocker un booléen (ou un varchar(255) pour stocker l'indice de vitesse du pneu)
    On ne jouit bien que de ce qu’on partage.

  5. #5
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    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 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    PS: J'avais pas fait gaffe à vos colonnes "commentaire" en varchar(255).

    Préférez le type "varchar(max)" car autant il permet de contenir BEAUCOUP plus de caractères (2 ^ 31-1 caractères soit 2 147 483 647 - 2 Go -) sans grosse perte de place, mais ces colonnes spéciales peuvent être stockées dans un fichier de données séparé, ce qui permet de monter en charge de façon bien plus robuste et évite de polluer les données avec du commentaire qui n'est pas utilisé dans 90% des requêtes.

    => Si je cherche toutes les voitures qui ont des jantes allu de 17", je me moque de savoir que Ghyslène a demandé au livreur de poser les jantes du le quai de chargement A...
    On ne jouit bien que de ce qu’on partage.

  6. #6
    Membre régulier
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    228
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 228
    Points : 113
    Points
    113
    Par défaut
    Merci pour votre complément.

    Préférez le type "varchar(max)"
    OK

    ces colonnes spéciales peuvent être stockées dans un fichier de données séparé, ce qui permet de monter en charge de façon bien plus robuste
    Comment faire pour créer ces fichiers séparés ? On ne parle pas de BLOB ?

    évite de polluer les données avec du commentaire qui n'est pas utilisé dans 90% des requêtes
    Si on ne sélectionne pas la colonne commentaire (qui ne sera pas souvent utilisée), les requêtes seront robustes/rapides même si on ne place pas le champ commentaire dans une fichier séparé ?

  7. #7
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    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 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Oui, un varchar(max) est considéré comme un LOB.

    De ce fait, fichier séparé ou non, les données ne sont pas stockées dans la ligne elle-même : ça accélèrera de toute façon vos requêtes.

    Le mieux étant tout de même de créer un fichier dédié aux LOB :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    CREATE TABLE [dbo].[LOBTest](
     
    [c1] [int] IDENTITY(1,1) NOT NULL,
     
    [c2] [char](8000) NULL,
     
    [c3] [varchar](max) NULL
     
    ) ON [Filegroup1]
     
      TEXTIMAGE_ON [LOBFilegroup]
    => Dans cet exemple, la table est stockée dans le filegroup "Filegroup1" et la colonne c3 dans le filegroup "logfilegroup".

    Ceci permet de séparer sur des disques physiques différents notamment.
    On ne jouit bien que de ce qu’on partage.

  8. #8
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Citation Envoyé par StringBuilder Voir le message
    Oui, un varchar(max) est considéré comme un LOB.

    De ce fait, fichier séparé ou non, les données ne sont pas stockées dans la ligne elle-même
    Sauf erreur de ma part, un varchar(max) sera stocké en ligne tant... qu'il tiendra dans la ligne. En d'autre termes, un varchar(max) contenant quelques caractères sera stocké en ligne, puis déplacé uniquement si la ligne dépasse 8ko (par exemple lors d'un update).
    Si un nouvel update diminue de nouveau la taille du varchar, il ne sera pas réintégré lors de la mise à jour (mais le sera lors d'une reconstruction de l'index cluster ou heap).

  9. #9
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    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 772
    Points : 52 732
    Points
    52 732
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Bonjour,
    Sauf erreur de ma part, un varchar(max) sera stocké en ligne tant... qu'il tiendra dans la ligne. En d'autre termes, un varchar(max) contenant quelques caractères sera stocké en ligne, puis déplacé uniquement si la ligne dépasse 8ko (par exemple lors d'un update).
    Si un nouvel update diminue de nouveau la taille du varchar, il ne sera pas réintégré lors de la mise à jour (mais le sera lors d'une reconstruction de l'index cluster ou heap).
    Oui et non et c'est spécifique à SQL Server.

    Lorsque vous créez une table dans SQL Server vous pouvez préciser dans quel espace de stockage les données y seront mises. Pour les LOBS (BLOB, CLOB, NCLOB, XML, et données de SIG) vous pouvez spécifier un espace de stockage différent des données relationnels, avec la directive TEXTIMAGE_ON, hélas rarement utilisée.
    Comme cela on ne mélange pas données relationnelles et LOBS.

    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/ * * * * *

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

Discussions similaires

  1. Regroupement de deux tables avec juste les valeurs identiques
    Par ange_dragon dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 04/07/2007, 15h42
  2. Jointure et regroupement sur 2 tables
    Par rocs dans le forum Langage SQL
    Réponses: 1
    Dernier message: 26/07/2005, 11h04
  3. Optimiser les tables mysql, nécessaire ?
    Par Michaël dans le forum Requêtes
    Réponses: 5
    Dernier message: 15/07/2005, 18h11
  4. Optimisation des tables
    Par le-roy_a dans le forum Décisions SGBD
    Réponses: 5
    Dernier message: 24/01/2005, 10h04
  5. Optimiser les tables
    Par blizar dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 04/06/2004, 08h34

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