24

Estoy desarrollando una aplicación web que puede admitir comentarios enhebrados. Necesito la capacidad de reorganizar los comentarios según la cantidad de votos recibidos. (Idéntico a la forma roscada comentarios trabajo en reddit)¿Cómo implemento los comentarios de subprocesos?

me gustaría escuchar las aportaciones de la comunidad SO sobre cómo hacerlo.

¿Cómo debo diseñar los comentarios table? Esta es la estructura que estoy utilizando ahora:

Comment 
    id 
    parent_post 
    parent_comment 
    author 
    points 

¿Qué cambios debería hacer más para esta estructura?

¿Cómo debo obtener los detalles de esta tabla para mostrarlos de la manera correcta? (La implementación en cualquier idioma es bienvenida. Solo quiero saber cómo hacerlo de la mejor manera posible)

¿Cuáles son las cosas que debo tener cuidado al implementar esta función para que haya menos carga en la CPU /¿Base de datos?

Gracias de antemano.

Respuesta

14

Almacenar árboles en una base de datos es un tema que tiene muchas soluciones diferentes. Depende de si también desea recuperar una sub jerarquía (por lo tanto, todos los elementos secundarios del elemento X) o si simplemente desea obtener todo el conjunto de jerarquías y construir el árbol de forma O (n) en la memoria utilizando un diccionario.

Su tabla tiene la ventaja de que puede obtener todos los comentarios en una publicación en 1 paso, filtrando en el poste principal. Como ha definido el padre del comentario en forma de libro de texto/ingenuo, debe construir el árbol en la memoria (ver a continuación). Si desea obtener el árbol de la base de datos, se necesita una forma diferente para almacenar un árbol: Ver mi descripción de un enfoque basado en el pre-calc aquí: http://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID=17746&ThreadID=3208 o using balanced trees described by CELKO here:

o otro enfoque: http://www.sqlteam.com/article/more-trees-hierarchies-in-sql

Si está obteniendo todo en una jerarquía en la memoria y construir el árbol de ahí, puede ser más eficiente debido al hecho de que la consulta es bastante simple: seleccionar .. de comentario donde ParentPost = @id ORDER BY ParentComment ASC

Después de esa consulta, usted construye d el árbol en memoria con solo 1 diccionario que realiza un seguimiento de la tupla ComentarioID - Comentario. Ahora recorre el conjunto de resultados y construye el árbol sobre la marcha: cada comentario que se encuentra, puede buscar su comentario original en el diccionario y luego almacenar el comentario actualmente procesado también en ese diccionario.

+0

Por "en memoria" qué se refiere al nivel de aplicación? – Ced

3

Su diseño actual es básicamente bien para las pequeñas jerarquías (menos de mil artículos)

Si se desea obtener a nivel certian o profundidad, añadir un elemento de 'nivel' a su estructura y computar como parte de el guardar

Si el rendimiento es un problema utilizar un caché decente

+0

No entiendo el nivel? –

3

me gustaría añadir los siguientes nuevos campos a la tabel arriba:

  • thread_id: identificador para todos los comentarios adjuntos a un objeto específico

  • fecha: la fecha de comentario (permite ir a buscar los comentarios en orden)

  • rango: el comentario pertinencia (permite ir a buscar el comentario de la orden por ranking)

el uso de estos campos serás capaz de:

  1. obtener todos los comentarios en un hilo en un solo op
  2. comentarios de la orden en un hilo, ya sea por fecha o rango

Desafortunadamente, si desea conservar sus consultas DB cerca del estándar SQL que volver a crear el árbol en la memoria. Algunos DBs están ofreciendo consultas especiales para datos jerárquicos (Fe Oracle)

./alex

+0

Alex, gracias por la respuesta, pero no entendí algunos de tus puntos. Creo que thread_id es lo mismo que post_id, la fecha puede ser reemplazada por una identificación autoincrementada, rank = points. Eso es lo que hice en mi diseño. ¿Pueden aclarar cualquier diferencia por mi diseño y el diseño propuesto? – Niyaz

+0

@Niyaz: supongo que es posible que necesite editar su pregunta ya que no veo un post_id (y de hecho entendí mal los puntos). thread_id: identificación única para todos los comentarios en un hilo (adjunta a un artículo). autoincrement puede proporcionar el orden pero no es equivalente a una fecha (verifique casi todos los foros). – alexpopescu

+0

Estaba confundido con. Si "parent_comment" apunta al ID de comentario del padre, lo llamaría "parent_comment_id" para borrar el aire. No estoy seguro de qué significa "parent_post" y por qué es diferente de "parent_comment". –

4

par de cosas a tener en cuenta también ...

1) Cuando se dice "género como reddit" basada en el rango o fecha, ¿te refieres al nivel superior o al conjunto?

2) Cuando se elimina un nodo, lo que ocurre con las ramas? ¿Los vuelves a criar? En mi aplicación, estoy pensando que los editores decidirán - o bien ocultar el nodo y mostrarlo como "comentario oculto" junto con los niños visibles, ocultar el comentario y de los niños, o bombardear todo el árbol. Re-crianza de los hijos debe ser fácil (acaba de establecer padre de los Chidren a los padres de borrado), pero cualquier cosa que implica a todo el árbol parece ser difícil de implementar en la base de datos.

He estado buscando en el módulo ltree para PostgreSQL. Se debe hacer que las operaciones de base de datos que implican las partes del árbol un poco más rápido. Básicamente le permite configurar un campo en la tabla que se parece a:

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

Sin embargo, no garantiza ningún tipo de integridad referencial por su cuenta. En otras palabras, se puede tener un registros para "Top.Science.Astronomy" sin tener un registro de "Top.Science" o "superior". Pero lo que sí te deja hacer es cosas como:

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

o

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

si se combina con el tradicional "comment_id" enfoque/"parent_id" uso de procedimientos almacenados, pienso que usted puede conseguir lo mejor de ambos mundos.Puede atravesar rápidamente el árbol de comentarios en la base de datos utilizando su "ruta" y aún garantizar la integridad referencial a través de "comment_id"/"parent_id". Estoy imaginando algo como:

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 cadena de ruta para una mirada comentario como sea

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

lo tanto un comentario raíz del hilo "102" con un comment_id de "1" tendría un camino de:

102.1

Y un niño cuya comment_id es "3" sería:

102.1.3

A algunos niños de la identificación del "3" que tienen de "31" y "54" sería:

102.1.3.31 
102.1.3.54 

Para ocultar el nodo "3" y sus hijos, que le emite este :

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

No obstante, podría agregar una sobrecarga innecesaria. Además, no sé qué tan bien mantenido está.

Cuestiones relacionadas