interfaz performance database-design comments query-optimization table-structure

performance - interfaz mysql



¿Cómo implemento los comentarios roscados? (4)

Agregaría los siguientes campos nuevos a la tabla anterior:

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

  • fecha: la fecha del comentario (permite buscar los comentarios en orden)

  • rango: el rango de comentario (permite obtener el orden de comentario por ranking)

Al usar estos campos, podrás:

  1. buscar todos los comentarios en un hilo en una sola operación
  2. ordenar comentarios en un hilo por fecha o rango

Desafortunadamente, si desea conservar sus consultas de BD cerca de SQL estándar, deberá recrear el árbol en la memoria. Algunos DB ofrecen consultas especiales para datos jerárquicos (por ejemplo, Oracle)

./alex

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 cómo funcionan los comentarios con subprocesos en reddit )

Me encantaría escuchar las aportaciones de la comunidad SO sobre cómo hacerlo.

¿Cómo debería diseñar la tabla de comentarios ? Aquí está la estructura que estoy usando ahora:

Comment id parent_post parent_comment author points

¿Qué cambios se deben hacer a 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 por adelantado.


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, necesita una forma diferente de almacenar un árbol: consulte mi descripción de un enfoque basado en cálculos previos aquí: http://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID=17746&ThreadID=3208 o usando árboles balanceados descritos por CELKO aquí :

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

Si busca todo en una jerarquía en la memoria y crea el árbol allí, puede ser más eficiente debido a que la consulta es bastante simple: seleccione ... desde Comentario donde ParentPost = @id ORDER BY ParentComment ASC

Después de esa consulta, construye el árbol en memoria con solo 1 diccionario que realiza un seguimiento de la tupla CommentID - 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.


Su diseño actual está básicamente bien para pequeñas jerarquías (menos de mil elementos)

Si desea obtener un nivel o profundidad de certificado, agregue un elemento de "nivel" a su estructura y calcúlelo como parte de la operación de guardar

Si el rendimiento es un problema usa un caché decente


Un par de cosas a considerar también ...

1) Cuando dices "ordenar como reddit" según el rango o la fecha, ¿te refieres al nivel superior o al conjunto?

2) Cuando eliminas un nodo, ¿qué ocurre con las ramas? ¿Los vuelves a criar? En mi implementación, estoy pensando que los editores decidirán: oculten el nodo y lo muestren como "comentario oculto" junto con los niños visibles, oculten el comentario y sus hijos o nukeen todo el árbol. La re-crianza debería ser fácil (simplemente configure el padre de los hijos con el padre eliminado), pero cualquier cosa que involucre todo el árbol parece ser difícil de implementar en la base de datos.

He estado buscando en el módulo ltree para PostgreSQL. Debería hacer que las operaciones de la base de datos que involucran partes del árbol sean un poco más rápidas. Básicamente, le permite configurar un campo en la tabla que se ve así:

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 sí mismo. En otras palabras, puede tener un registro para "Top.Science.Astronomy" sin tener un registro para "Top.Science" o "Top". Pero lo que te permite 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 enfoque tradicional "comment_id" / "parent_id" usando procedimientos almacenados, estoy pensando que puedes obtener 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 así 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 un comentario parece ser

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

Por lo tanto, un comentario raíz del subproceso "102" con un comment_id de "1" tendría una ruta de acceso de:

102.1

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

102.1.3

Algunos hijos de "3" con id de "31" y "54" serían:

102.1.3.31 102.1.3.54

Para ocultar el nodo "3" y sus hijos, deberías emitir esto:

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

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