Question

J'envisage d'utiliser le module Ltree de PostgreSQL dans mon application pour aider avec les commentaires filetés. Je la cherche depuis un moment à utiliser pour les commentaires filetés. Je pense que cela aiderait dans les cas où vous devez mettre à jour un nœud et ses enfants, comme lorsque vous souhaitez masquer un commentaire et ses réponses.

Je pense que ltree (ou quelque chose de ce genre) serait utile s'il était associé à une liste de contiguïté traditionnelle ("comment_id" / "parent_comment_id").

Avant de me lancer dans l’utilisation de ltree, je me pose quelques questions:

  1. Êtes-vous ou avez-vous utilisé ltree? Est-ce ce que l'on pourrait appeler "prêt à la production"?
  2. Si oui, quels problèmes l'avez-vous utilisé pour résoudre? At-il fait du bon travail?
  3. Pensez-vous que cela convient bien à un système de commentaires fileté?
    1. Si vous l'avez utilisé, qu'avez-vous utilisé pour le "texte"? une partie du chemin? Avez-vous configuré quelque chose comme l’exemple DMOZ qui utilise "Top.Astronomy.Cosmology"? ou le baser sur quelque chose comme la clé primaire "1.403.29.5"??
    2. Y a-t-il une meilleure façon de faire cela? Je suis un peu nerveux en utilisant une approche de liste imbriquée - tout ce que j'ai lu suggère que ce n'est pas trop chaud avec UPDATES ou INSERTS (ne devez-vous pas tout réorganiser?). Je ne suis pas non plus un grand spécialiste de la société civile et ce type de structure de données est quelque chose que je pourrais oublier à l'avenir. Quelqu'un utilise-t-il des listes imbriquées pour les commentaires ou quelque chose de similaire?

Si cela peut vous aider, voici le schéma que je considère:

CREATE TABLE comments (
    comment_id SERIAL PRIMARY KEY,
    parent_comment_id int REFERENCES comments(comment_id) ON UPDATE CASCADE ON DELETE CASCADE,
    thread_id int NOT NULL  REFERENCES threads(thread_id) ON UPDATE CASCADE ON DELETE CASCADE,
    path ltree NOT NULL,
    comment_body text NOT NULL,
    hide boolean not null default false
);

Le "chemin" " colonne, utilisée par ltree, ressemblerait à quelque chose comme:

<thread_id>.<parent_comment_id_#1>.<parent_comment_id_#2>.<my_comment_id>

Y at-il un problème avec l’utilisation des clés primaires dans le chemin? Dois-je inclure la clé primaire du noeud dans le chemin? Si je le faisais, aurait-il un sens de mettre un index unique sur celui-ci pour servir de contrainte?

Était-ce utile?

La solution

  1. Oui et oui;
  2. Hiérarchie des sections dans une base de connaissances (une des implémentations);
  3. oui;

La définition de l'une des tables en question:

                                                   Table "knowledgebase.section"
           Column           |           Type           |                                  Modifiers
----------------------------+--------------------------+-----------------------------------------------------------------------------
 section_sid                | integer                  | not null default nextval('knowledgebase.section_section_sid_seq'::regclass)
 section                    | character varying        | not null
 description                | character varying        |
 path                       | ltree                    | not null
 is_active                  | boolean                  | not null default true
 role_sid                   | integer                  | not null
 last_modified_by           | integer                  | not null
 creation_datetime          | timestamp with time zone | not null default now()
 last_modification_datetime | timestamp with time zone | not null default now()
 is_expanded                | boolean                  | not null default false
 section_idx                | tsvector                 |
Indexes:
    "section_sid_pkey" PRIMARY KEY, btree (section_sid)
    "section_section_key" UNIQUE, btree (section)
    "idxsection_idx" gist (section_idx)
    "path_gist_idx" gist (path)
Foreign-key constraints:
    "last_modified_by_fkey" FOREIGN KEY (last_modified_by) REFERENCES "user"."role"(role_sid) ON UPDATE CASCADE ON DELETE RESTRICT
    "role_sid_fkey" FOREIGN KEY (role_sid) REFERENCES "user"."role"(role_sid) ON  UPDATE CASCADE ON DELETE RESTRICT
Triggers:
    section_idx_update BEFORE INSERT OR UPDATE ON knowledgebase.section FOR EACH ROW EXECUTE PROCEDURE tsearch2('section_idx', 'section')

Le "chemin" " colonne utilise la clé primaire comme une étiquette.

Un exemple du contenu actuel de cette table (en ce qui concerne la clé primaire et la colonne "chemin"):

  section_sid | path
 -------------+-------
           53 | 34.53
           56 | 56
           55 | 29.55
           35 | 35
           54 | 34.54
           37 | 30.37
          ... | ...

Autres conseils

Je recommande à quiconque implémentant des relations hiérarchiques dans SQL de lire Les arbres et les hiérarchies de Joe Celko dans SQL pour Smarties .

Traverser des liens parent parents de profondeur arbitraire peut s'avérer très inefficace si vous utilisez uniquement un parent_id. Le livre décrit des techniques qui rendent cet accès rapide.

Une stratégie (que j’utilise par hasard) peut également être trouvée gratuitement dans cette série d’articles:

La version 8.4 de PostgreSQL intégrera la fonctionnalité Expressions de table communes dans le noyau avec les expressions WITH et WITH ... RECURSIVE . Si vous modifiez un ancien code, vous voudrez peut-être attendre la publication de la 8.4, car vous ne craindrez plus aucune incompatibilité entre Ltree et la nouvelle syntaxe principale. Si vous travaillez avec un ancien code ou ne voulez pas attendre la version 8.4, vous voudrez probablement vous assurer que vous écrivez du code facilement traduisible dans la nouvelle syntaxe, en particulier si vous modifiez un ancien schéma ou créez un nouveau. un.

Voir aussi:

scroll top