2011-12-05 25 views
7

Tengo un script que escribí mientras estaba de vuelta para comentarios, pero solo tiene un único hilo. Me gustaría que tuviera varios subprocesos, pero solo así un usuario puede responder a un comentario, no para que un usuario pueda responder a un comentario de un comentario. Entonces los hilos solo serían dos profundos.Comentarios multihilo PHP?

Actualmente almacé un comment_id contra un user_id en mi base de datos.

La única forma en que puedo pensar para hacer los comentarios multihilo, es tener un campo parent en la tabla de comentarios. Pero si hago esto, cuando seleccione los comentarios con PHP, tendré que hacer otro comando SELECCIONAR para seleccionar los comentarios secundarios (si los hay) para cada comentario. Parece mucho trabajo en la base de datos.

Tiene que haber una manera mejor. Alguna idea sobre esto? ¿O tutoriales?

+0

Sin leer la pregunta por contexto, la pregunta no tiene ningún sentido, ya que "multi-threaded" y "comments" generalmente se refieren a otros. – Davy8

Respuesta

16

Hay tres (cuatro) posibilidades alternativas:

  1. Un consulta recursiva para seleccionar todos los comentarios sobre la base de sus documentos de identidad de los padres. Esto es compatible con muchos productos de base de datos y la sintaxis depende del tipo de base de datos. Verifique los documentos para obtener más información (busque 'recursivo').

  2. Si almacena el identificador de artículo en cada comentario (sub), sólo puede seleccionar todos los comentarios con el artículo id en una consulta de selección regular. Se pueden utilizar los identificadores de los padres para mostrar correctamente los comentarios sobre la página, debajo de la derecha comentario de los padres:

    SELECT * FROM comments WHERE article_id = :article_id 
    
  3. Si sólo necesita dos niveles de comentarios, usted puede utilizar un extendieron donde para incluir tanto el primer nivel y segundo comentarios nivel:

    SELECT * FROM comments 
    WHERE parent_id = :article_id 
    OR parent_id IN (SELECT id FROM comments WHERE parent_id = :article_id) 
    
  4. también es posible utilizar unión de todo combinar dos consultas que tienen las mismas columnas, pero como supongo que todos los datos son de la misma tabla, probablemente no hay necesidad de eso (ver la cláusula-where extendido arriba):

    SELECT * FROM comments WHERE parent_id = :article_id 
    UNION ALL 
    SELECT * FROM comments WHERE parent_id IN 
        (SELECT id FROM comments WHERE parent_id = :article_id) 
    

Personalmente, me gustaría ir para la opción 2 porque es simple (sin constructo SQL exótico necesario), eficiente (1 consulta) y flexible (soporta como muchos niveles de comentarios como quieras).

+0

Podría dejar caer un ejemplo real del código php y el conjunto de resultados ... He estado leyendo su respuesta una y otra vez durante horas y realmente no sé cómo codificarla ... gracias – jcobhams

+0

@VyrenMedia Supongo que usted estamos tratando de implementar la opción 2. No le proporcionaré una guía completa de implementación, pero tal vez esto ayude: http://blog.tcs.de/creating-trees-from-sql-queries-in-javascript/. Si necesita más ayuda, publique una nueva pregunta de SO. –

1

Esta consulta podría funcionar para usted (que no sabía que su estructura, por lo que supuse en ello):

SELECT * FROM comments a 
LEFT JOIN comments b ON a.comment_id = b.parent_coment_id 
LEFT JOIN comments c ON b.comment_id = c.parent_coment_id 
WHERE a.comment_id <> b.comment_id 
     AND a.comment_id <> c.comment_id 
     AND b.comment_id <> c.comment_id; 
+0

Esto parece correcto. Supongo que el segundo LEFT JOIN y el segundo AND son para unir un comentario de tercer nivel. –

+0

@SeanHJenkins sip^_^pruébelo. Debería funcionar :-D – Neal

+0

Tenga en cuenta que esto funciona para un máximo de 3 niveles de comentarios, y no se filtra en el artículo real, lo que supongo que sería útil. –

2

1 consulta es suficiente para esto, sólo tiene que bucle de los datos y almacenarlos en una matriz correctamente, luego realiza un bucle en la matriz y muestra los comentarios.

+0

¡Cuál es más de una consulta! Así es como yo explico que lo habría hecho de todos modos, estoy buscando mejores maneras. –

+0

. Estuviste hablando de usar otra declaración SELECT y te di una mejor manera. – JanL

+0

No su solución seguirá utilizando múltiples SELECT. Gracias por la respuesta. –

2

Este es un uso común para datos jerárquicos o de estructura de árbol. Escribí una respuesta popular a esta pregunta sobre desbordamiento de pila: What is the most efficient/elegant way to parse a flat table into a tree?

También escribí una presentación que describía alternativas para los datos estructurados en árbol: Models for Hierarchical Data with SQL and PHP.

Otra solución que no está incluida en mi presentación es la forma en que Slashdot realiza los comentarios. Utilizan una columna parent como usted, por lo que cada comentario hace referencia al comentario al que responde. Pero también incluyen una columna root, por lo que cada comentario conoce la publicación a la que pertenece. Rara vez hay más de unos pocos cientos de comentarios en un puesto determinado, y por lo general se quieren conseguir todo el árbol de comentarios para un puesto determinado a partir de la parte superior del hilo de comentarios:

SELECT * FROM comments WHERE root = 1234; 

Luego, a medida que buscar el comentarios, puede escribir código PHP para procesarlos en matrices de matrices de acuerdo con las columnas parent (a esto se refiere la respuesta de @ JanL). Publiqué el código para hacer esto en mi respuesta a otra pregunta de desbordamiento de pila, Convert flat array to the multi-dimentional.

+0

Sé que esta es una publicación anterior, pero estaba vagando con el método que describió cómo funcionaría si tuviera una publicación con comentarios de miles, obviamente no seleccionaría todas las filas, sin embargo, si usaba un LÍMITE, perdería el estructura de árbol ... ¿hay alguna forma de evitar esto? ... Saludos cordiales J – jon

+0

@jon, podría usar LIMIT pero ordenar antes de la fecha del comentario. Entonces obtendrías los hilos de comentarios más antiguos. Luego, si el usuario desea expandir los hilos, podría solicitarlos, pero de forma predeterminada solo verían un subconjunto de la discusión. Si desea obtener más información, descargue la fuente de Slashdot y vea cómo lo hacen. http://slashcode.com/ –

+0

gracias por su respuesta; sin embargo, si lo entiendo correctamente, esto solo mostraría los hilos de comentarios originales y luego, si deseaban expandir un hilo de comentarios para ver las respuestas, haría una selección en ese hilo de comentarios, sin embargo, realmente también quiero mostrar las respuestas de los hilos de comentarios en la primera consulta, ¿pero también puedo LIMITAR? ... ¿es posible usando la jerarquía de adyacencia? .. gracias de nuevo J. – jon