Question

Je développe une application web qui peut supporter des commentaires filetés. J'ai besoin la possibilité de réorganiser les commentaires en fonction du nombre de votes reçus. (Identique à la façon dont le travail commentaires fileté reddit )

J'aimerais entendre les contributions de la communauté SO sur la façon de le faire.

Comment dois-je concevoir les commentaires table? Voici la structure que je suis maintenant en utilisant:

Comment
    id
    parent_post
    parent_comment
    author
    points

Quels changements faut-il faire à cette structure?

Comment dois-je obtenir les détails de ce tableau pour les afficher de manière correcte? (Mise en œuvre dans toutes les langues est la bienvenue. Je veux juste savoir comment le faire de la meilleure manière possible)

Quelles sont les choses que je dois prendre soin tout mettre en œuvre cette fonction pour qu'il y ait moins de charge sur la CPU / base de données?

Merci d'avance.

Était-ce utile?

La solution

Stockage des arbres dans une base de données est un sujet qui a beaucoup de solutions différentes. Cela dépend si vous voulez récupérer un chemin dans la mémoire et sous-hiérarchie (de sorte que tous les enfants du point X) ou si vous voulez juste saisir l'ensemble des hiérarchies et de construire l'arbre dans un O (n) en utilisant un dictionnaire.

Votre table a l'avantage que vous pouvez chercher tous les commentaires sur un poste en 1 Go, en filtrant le parentpost. Comme vous l'avez défini le parent du commentaire de la manière de manuel / naïve, il faut construire l'arbre en mémoire (voir ci-dessous). Si vous voulez obtenir l'arbre de la DB, vous avez besoin d'une autre façon de stocker un arbre: Voir ma description d'une approche pré-calc ici: http://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID = 17746 & ThreadID = 3208 ou par en utilisant des arbres équilibrés décrit par Čelko ici:

ou encore une autre approche: http://www.sqlteam.com/article/more-trees-hierarchies -en-sql

Si vous allez chercher tout dans une hiérarchie dans la mémoire et de construire l'arbre là-bas, il peut être plus efficace en raison du fait que la requête est assez simple: sélectionner .. de Commentaire où ParentPost = @id ORDER BY ASC ParentComment

Après cette requête, vous construisez l'arbre en mémoire avec seulement 1 dictionnaire qui garde la trace du tuple CommentID - Commentaire. Vous marchez maintenant à travers l'ensemble de résultats et de construire l'arbre à la volée: tous les commentaires que vous rencontrez, vous pouvez rechercher son parentcomment dans le dictionnaire, puis stocker le commentaire en cours de traitement aussi dans ce dictionnaire.

Autres conseils

couple de choses à considérer aussi ...

1) Quand vous dites « genre comme reddit » basé sur le classement ou la date, voulez-vous dire le haut niveau ou la chose?

2) Lorsque vous supprimez un nœud, ce qui arrive aux branches? Avez-vous re-parents eux? Dans ma mise en œuvre, je pense que les éditeurs décideront - soit cacher le nœud et l'afficher comme « commentaire caché » avec les enfants visibles, cacher le commentaire et enfants, ou atomiser l'arbre entier. Re-parentalité devrait être facile (juste mettre le parent de chidren à la société mère est supprimé), mais tout ce qui concerne l'arbre entier semble être difficile à mettre en œuvre dans la base de données.

J'ai regardé le module ltree PostgreSQL. Il devrait faire des opérations de base de données impliquant des parties de l'arbre un peu plus vite. Il permet essentiellement de configurer un champ dans la table qui ressemble à:

ltreetest=# select path from test where path <@ 'Top.Science';
                path                
------------------------------------
 Top.Science
 Top.Science.Astronomy
 Top.Science.Astronomy.Astrophysics
 Top.Science.Astronomy.Cosmology

Toutefois, il ne garantit pas tout type d'intégrité référentielle lui-même. En d'autres termes, vous pouvez avoir des enregistrements pour « Top.Science.Astronomy » sans avoir un record pour « Top.Science » ou « Top ». Mais qu'est-ce que cela ne vous laisse faire des choses est:

-- hide the children of Top.Science
UPDATE test SET hide_me=true WHERE path @> 'Top.Science';

ou

-- nuke the cosmology branch
DELETE FROM test WHERE path @> 'Top.Science.Cosmology';

Si combiné avec l'approche traditionnelle « comment_id » / « parent_id » en utilisant des procédures stockées, je pense que vous pouvez obtenir le meilleur des deux mondes. Vous pouvez rapidement parcourir l'arborescence de commentaires dans la base de données en utilisant votre « chemin » et assurer encore l'intégrité référentielle via « comment_id » / « parent_id ». Je suis quelque chose comme envisager:

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
);

La chaîne de chemin pour un look commentaire comme être

<thread_id>.<parent_id_#1>.<parent_id_#2>.<parent_id_#3>.<my_comment_id>

Ainsi un commentaire racine de fil « 102 » avec un comment_id de « 1 » aurait un chemin de:

102.1

Et un enfant dont comment_id est "3" serait:

102.1.3

A certains enfants de "3" ayant id de "31" et "54" seraient:

102.1.3.31
102.1.3.54

Pour masquer le nœud « 3 » et ses enfants, vous auriez émettez ceci:

UPDATE comments SET hide=true WHERE path @> '102.1.3';

Je ne sais pas si - il pourrait ajouter les frais généraux inutiles. De plus, je ne sais pas comment bien entretenu ltree est.

Votre conception actuelle est fondamentalement bien pour les petites hiérarchies (moins de mille articles)

Si vous voulez chercher à un niveau certian ou de profondeur, ajouter un élément « niveau » à votre structure et le calculer dans le cadre de la sauvegarde

Si la performance est un problème utilisez un cache décent

Je rajouterais les nouveaux champs aux tableaux suivants:

  • thread_id: identificateur pour tous les commentaires attachés à un objet spécifique

  • Date: la date de commentaire (permet la récupération des commentaires dans l'ordre)

  • rang: le rang de commentaire (permet la récupération de l'ordre de commentaire par le classement)

L'utilisation de ces champs, vous serez en mesure de:

  1. fetch tous les commentaires dans un fil en une seule op
  2. commentaires de commande dans un fil par date ou rang

Malheureusement, si vous voulez conserver vos requêtes DB proche de SQL standard, vous devrez recréer l'arbre en mémoire. Certains offrent des requêtes BDs spéciales pour les données hiérarchiques (Oracle F.E.)

./ alex

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top