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 :

Quelle solution pour représenter un arbre dans une base de données ?


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2012
    Messages : 9
    Par défaut Quelle solution pour représenter un arbre dans une base de données ?
    Bonjour à tous,

    Je développe un site dont le système est plus au moins similaire à disqus (système de commentaires avec pagination des commentaires)

    Schématiquement:
    une table item (plusieurs millions)
    une table user (plusieurs millions)
    une table comments (plusieurs millions) <== c'est là que je m'interroge

    (mon environnement : PostgreSQL 9.1 + JPA Hibernate)

    Je me demandais quelle pouvait être la meilleurs manière de persister en DB les informations de l'arbre des commentaires.

    D'après ce lien:
    Models for hierarchical data
    Il existe 4 manières différentes de faire :
    1 - "adjacency liste" : le plus commun, chaque noeud contient l'id de son parent
    2 - "path énumération" : les chemins matérialisés
    3 - nested set : arbre par représentation intervallaire
    4 - closure table
    5 - recursive CTE

    Pour le 1 : cela implique des sous requêtes complexes et non performantes
    Pour le 2 : ca me semble bien mais je crains que les requêtes sur des path avec des like % soit couteux
    pour le 3 : l'idée est bonne mais dès que tu ajoutes un nœud il faut recalculer tous les autres, je pense que c'est une mauvaise idée pour des tables volumineuses et dont les insertions sont fréquentes (je table sur des millions de rows)
    pour le 4 : ça semble idéal mais il y a peu de retour utilisateur et c'est surtout l'auteur de ce pattern qui en fait l'éloge donc j'ai des doutes (d'autant que j'ai l'impression que cette technique peut devenir très consommatrice en terme d'espace disque si l'arborescence est profonde)
    pour le 5 : je sais que PostgreSQL supporte ça mais je ne pense pas que ça s'interface facilement avec Hibernate.

    Je sais que d'autres solutions dérivées du nested set existent mais je n'ai pas la compétence pour juger de leur intérêt dans mon cas (entre autre : Nested Intervals Tree Encoding with Continued Fractions qui semble bien mais assez complexe à mettre en œuvre)

    Bref, je ne sais pas quelle solution choisir parmi les 4 (même si je penche pour la 2 et la 4)

    N'importe laquelle des solutions pourrait aller mais je dois choisir celle qui assure les meilleurs performances (table énorme et sollicitations très fréquentes) et une bonne maintenabilité.

    vos avis et retours d'expériences sont les bienvenus

    Merci

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 998
    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 998
    Billets dans le blog
    6
    Par défaut
    de toutes la meilleure solution est généralement l'arbre intervallaire, spécialement si le classement arborescent ne varie pas au fil du temps (pas d'update concernant les bornes de l’intervalle.

    Lisez les articles que j'ai écrit à ce sujet :
    http://sqlpro.developpez.com/cours/arborescence/
    http://blog.developpez.com/sqlpro/p8...allaire-proce/
    http://blog.developpez.com/sqlpro/p7...dure-de-depla/
    http://blog.developpez.com/sqlpro/p7...dure-de-derec/

    A noter 1 et 5 reviennent au même...

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

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2012
    Messages : 9
    Par défaut
    Bonjour SQLpro,

    Tes articles ont bien sur été le point de départ de ma réflexion

    Cependant, malgré toutes les qualités des arbre intervallaires, je ne suis pas sur que c'est adapté dans mon cas (rappel: fort trafic et fort volume) car :
    1 - j'ai des tables volumineuses (dès que tu ajoutes un nœud il faut recalculer tous les autres). De plus, je trouve qu'on perd le principe d'indépendance des rows du relationnel en recalculant les intervalles
    2 - j'ai de nombreux accès concurrents (j'imagine que le recalcul des intervalles lors d'une insertion doit poser de nombreux verrous sur la base... pas glop)

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 998
    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 998
    Billets dans le blog
    6
    Par défaut
    Il faut être un peu plus malin... et ne pas oublier de penser...

    1) le volume n'est pas important. J'ai mis en œuvre des arbres intervallaire testé au départ avec un millions de lignes et qui sont aujourd'hui sur plusieurs dizaines de millions. Plus l'arbre est profond et plus on est gagnant par rapport au modèle adjacent ou path
    2) si tu as peur que la mise à jour soit bloquante, on peut au choix :
    2.1) placer les composantes de l'arbre dans une table externe, et présenter une
    vue
    2.2) utiliser des intervalles décimaux qui ne propagent pas les updates. Cela s'apelle "Modélisation intervallaire par intercalage" (voir ma très ancienne présentation pour InterBase/FireBird : http://sqlpro.developpez.com/cours/borcon2003/)

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

  5. #5
    Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2012
    Messages : 9
    Par défaut
    Merci pour la qualité de ta réponse.

    Citation Envoyé par SQLpro Voir le message
    2.1) placer les composantes de l'arbre dans une table externe, et présenter une
    vue
    La perspective ne m'enchante guère... en tant que développeur java, j'ai tendance à effectuer la majorité du traitement coté applicatif et de ne pas laisser la base s'en charger, par manque de compétences dans ce domaine. J'ai aussi tendance à simplifier au maximum les choses et créer une vue pour résoudre un problème de mise à jour bloquante me parait un peu lourd à gérer.

    Citation Envoyé par SQLpro Voir le message
    2.2) utiliser des intervalles décimaux qui ne propagent pas les updates. Cela s'apelle "Modélisation intervallaire par intercalage" (voir ma très ancienne présentation pour InterBase/FireBird : http://sqlpro.developpez.com/cours/borcon2003/)
    La perspective évoquée dans ta présentation est très séduisante
    Ça rejoint l'article "Nested Intervals Tree Encoding with Continued Fractions" qui explique la mise en œuvre de ce principe. A première vue, ça semble assez complexe à mettre en œuvre. Et le requétage étant plus long en flottant qu'avec des numériques, je me dis autant utiliser dans ce cas des chemins matérialisés qui ont les mêmes avantages que la Modélisation intervallaire par intercalage sans la complexité apparente.

    Également, il est difficile de récupérer uniquement les enfants d'un noeud avec les nested set ou les chemins matérialisés alors que les "closure table" le permette.
    J'ai l'impression que les "closure table" permettent autant voir plus de souplesse que les nested set. Le recalcul des rows des nested set nécessite un update sur chacun des noeuds, soit un lock sur chacun des noeuds. Les closures table ne nécessitent qu'un insert donc pas de lock sur les noeuds (je dis peut être des bêtises, je ne suis pas compétant dans le mécanisme des verrous)

    quelle dilemme!

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 998
    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 998
    Billets dans le blog
    6
    Par défaut
    NON, non, non et non !!! Vous commettez de nombreuses fautes dans votre raisonnement !

    Citation Envoyé par zeb_zed Voir le message
    ...
    La perspective ne m'enchante guère... en tant que développeur java, j'ai tendance à effectuer la majorité du traitement coté applicatif et de ne pas laisser la base s'en charger,
    C'est la pire de choses pour les performances. D'un coté vous demandez un conseil sur les perf. De l'autre vous allez détruire tous les axes de performances possible. Lisez l'article que j'ai écrit au sujet du style de dev.
    http://sqlpro.developpez.com/cours/b...s-epaisses.pdf
    Si vous voulez des perf, me seule moyen est de mettre le maximum d'intelligence dans le base et le minimum du côté client; En effet un code client (donc itératif) n'est jamais optimisable dynamiquement, alors que c'est ce que pratiquent en permanence les bons SGBGDR du fait du code ensembliste, de l'indexation, de l'optimiseur et des contraintes !


    par manque de compétences dans ce domaine. J'ai aussi tendance à simplifier au maximum les choses et créer une vue pour résoudre un problème de mise à jour bloquante me parait un peu lourd à gérer.
    Manue de compétence, c'est hélas le point n°1 des mauvaises perf... quand on ne sait pas comment fonctionne un système quelconque il est impossible d'en tirer le meilleur partit !
    De plus l'usage des vues est normalement impérative. Aucune application ne devrait attaquer directement les tables ! L'ensemble des vues et des routines (procédures, fonctions, déclencheurs...) con situant le MED (Modèle Externe de Données). Pensez simplement à ceci : que va t-il se passer une fois votre application écrite si il faut restructurer une table parce que les performance,ces ne sont pas bonnes ? Avec une vue, vous n'avez pas à récrire toute votre application. En utilisant un accès directe aux tables, vous êtes dans le merde....
    La perspective évoquée dans ta présentation est très séduisante
    Ça rejoint l'article "Nested Intervals Tree Encoding with Continued Fractions" qui explique la mise en œuvre de ce principe. A première vue, ça semble assez complexe à mettre en œuvre. Et le requétage étant plus long en flottant qu'avec des numériques,
    Vous confondez entier et décimaux. En SQL il existe 3 types de nombres: les entiers (smallint, INT, BIGINT), les décimaux (DECIMAL, NUMEFRIC) et les réels (REAL, FLOAT). Vous ne devez surtout pas utiliser les réels car vous pourriez perdre définitivement certaines bornes du fait de l'imprécision des calculs en virgule flottante. C'est pourquoi SQL propose les décimaux qui ne sont pas entachés de ce problème

    je me dis autant utiliser dans ce cas des chemins matérialisés qui ont les mêmes avantages que la Modélisation intervallaire par intercalage sans la complexité apparente.
    Pas du tout !!!! Les performances d'une base de données relationnelle sont directement liées à la volumétrie et à la non redondance des informations. Avec ce modèle vous explosez les deux, à moins de trouver un moyen de compresser le path, comme le fait MS SQL Server depuis la version 2008 avec le type Hierarchyid (mais c'est toujours pas aussi bon que l'intervallaire).L

    Également, il est difficile de récupérer uniquement les enfants d'un noeud avec les nested set ou les chemins matérialisés alors que les "closure table" le permette.
    J'ai l'impression que les "closure table" permettent autant voir plus de souplesse que les nested set. Le recalcul des rows des nested set nécessite un update sur chacun des noeuds, soit un lock sur chacun des noeuds. Les closures table ne nécessitent qu'un insert donc pas de lock sur les noeuds (je dis peut être des bêtises, je ne suis pas compétant dans le mécanisme des verrous)

    quelle dilemme!
    Ne vous posez pas les problématique de verrouillage; C'est le SGBDR qui les gèrent au mieux en fonction notamment de :
    • la granularité des informations à verrouiller
    • de la nature de la transaction
    • de la concurrence à l'instant t


    le fait de déporter Les données intervallaire dans une table à part minimise encore plus ces verrous....

    Le choix d'un bon SGBDR pour gérer cela est encore plus important. par exemple MySQL comme PostGreSQL ne sont pas réellement des SGBD relationnel dans le sens ou il ne sont pas capable de réaliser des traitements ensemblistes. Lisez l'article que j'ai écrit à ce sujet : http://blog.developpez.com/sqlpro/p1...d-relationn-1/
    Pire, MySQL est farci de bug tous plus débiles les uns que les autres. A me lire : http://blog.developpez.com/sqlpro/p9...udre-aux-yeux/

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 08/09/2009, 17h07
  2. [Web] Quelles solutions pour de la 3D dans le browser?
    Par ShevchenKik dans le forum OpenGL
    Réponses: 2
    Dernier message: 06/05/2009, 13h12
  3. Réponses: 5
    Dernier message: 10/05/2008, 17h26
  4. Réponses: 7
    Dernier message: 26/05/2007, 15h14
  5. Modélisation d'un arbre dans une base de données
    Par compu dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 11/04/2005, 18h29

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