2011-12-05 10 views
7

Ho una sceneggiatura che ho scritto mentre tornavo per i commenti, ma è solo a thread singolo. Mi piacerebbe che fosse multi-thread, ma solo così un utente può rispondere a un commento, non così un utente può rispondere a un commento di un commento. Quindi i fili sarebbero solo due profondi.Commenti multi-thread PHP?

Attualmente memorizzo un comment_id contro un user_id nel mio database.

L'unico modo in cui posso pensare di fare i commenti multi-thread, è di avere un campo parent nella tabella dei commenti. Ma se lo faccio allora quando seleziono i commenti con PHP, dovrò fare un altro comando SELECT per selezionare i commenti figli (se ce ne sono) per ogni commento. Sembra un sacco di lavoro sul database.

Ci deve essere un modo migliore. Qualche idea su questo? Oppure tutorial?

+0

Senza leggere la domanda per il contesto, la domanda non ha assolutamente senso poiché "multi-thread" e "commenti" in genere si riferiscono ad altri. – Davy8

risposta

16

ci sono tre (quattro) possibilità alternative:

  1. Un query ricorsive per selezionare tutti i commenti sulla base di loro ID genitore. Questo è supportato da molti prodotti di database e la sintassi dipende dal tipo di database. Controlla i documenti per maggiori informazioni (cerca 'ricorsivo').

  2. Se si memorizza l'ID articolo in ogni (sotto-) commento, è sufficiente selezionare tutti i commenti con l'ID articolo in una query di selezione regolare. È possibile utilizzare gli ID genitore per visualizzare correttamente i commenti sulla pagina in base al diritto commento genitore:

    SELECT * FROM comments WHERE article_id = :article_id 
    
  3. Se avete solo bisogno di due livelli di commenti, è possibile utilizzare un esteso dove includere sia di primo livello e secondo i commenti di livello:

    SELECT * FROM comments 
    WHERE parent_id = :article_id 
    OR parent_id IN (SELECT id FROM comments WHERE parent_id = :article_id) 
    
  4. e 'anche possibile utilizzare uNION ALL di combinare due query che hanno le stesse colonne, ma dal momento che presumo che tutti i dati siano dalla stessa tabella, probabilmente non c'è bisogno di esso (vedere la cui clausola esteso sopra):

    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, vorrei andare per l'opzione 2 perché è semplice (senza costrutto SQL esotici richiesto), efficiente (1 query) e flessibile (supporta fino livelli di commenti che vuoi).

+0

Per favore potresti inserire un esempio di vita reale del codice php e del set di risultati ... ho letto la tua risposta più e più volte per ore e non riesco davvero a capire come codificarlo ... grazie – jcobhams

+0

@VyrenMedia. stanno cercando di implementare l'opzione 2. Non ti fornirò una guida completa per l'implementazione, ma forse questo ti aiuterà: http://blog.tcs.de/creating-trees-from-sql-queries-in-javascript/. Se hai bisogno di ulteriore aiuto, per favore pubblica una nuova domanda SO. –

1

Questa query potrebbe funzionare per voi (non sapevo la struttura, così ho indovinato a esso):

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

Sembra giusto. Suppongo che il secondo LEFT JOIN e il secondo AND siano per partecipare al commento di terzo livello? –

+0

@SeanHJenkins yep^_^provalo. Dovrebbe funzionare :-D – Neal

+0

Si noti che questo funziona per un massimo di 3 livelli di commenti e non filtra sull'articolo effettivo, che presumo sarebbe utile. –

2

1 query è sufficiente per questo, è solo bisogno di ciclo i dati e memorizzare in una matrice correttamente, quindi si esegue il ciclo della matrice e si visualizzano i commenti.

+0

Che è più di una query! Questo è il modo in cui mi sono lamentato che avrei fatto lo stesso, sto cercando modi migliori –

+0

Stavi parlando di usare un'altra istruzione SELECT e ti ho dato un modo migliore. – JanL

+0

Nessuna soluzione utilizzerà ancora SELEZIONA. Grazie per la risposta. –

2

Questo è un uso comune per i dati gerarchici o struttura ad albero. Ho scritto una risposta popolare a questa domanda Stack Overflow: What is the most efficient/elegant way to parse a flat table into a tree?

Ho anche scritto una presentazione che descrive le alternative per i dati strutturati ad albero: Models for Hierarchical Data with SQL and PHP.

Un'altra soluzione che non è inclusa nella mia presentazione è il modo in cui Slashdot esegue commenti con thread. Utilizzano una colonna parent come fai tu, quindi ogni commento fa riferimento al commento a cui risponde. Ma poi includono anche una colonna root così ogni commento conosce il post a cui appartiene. Ci sono raramente più di poche centinaia di commenti su un determinato posto, e di solito si desidera ottenere l'intero albero di commenti per un determinato posto a partire dalla cima del commento filo:

SELECT * FROM comments WHERE root = 1234; 

Poi, come si recupera il commenti, è possibile scrivere codice PHP per elaborarli in matrici di array in base alle colonne parent (questo è ciò a cui allude la risposta di @ JanL). Ho inserito il codice per farlo nella mia risposta ad un'altra domanda di overflow dello stack, Convert flat array to the multi-dimentional.

+0

So che questo è un vecchio post ma stavo vagando con il metodo che hai descritto come funzionerebbe se tu avessi un post con commenti a migliaia, ovviamente non selezioneresti tutte le righe, tuttavia se hai usato un LIMIT si perderebbe il struttura ad albero ... c'è un modo per aggirare questo? ... Cordiali saluti J – jon

+0

@jon, potresti usare LIMIT ma ordina per la data del commento. Quindi otterresti i thread dei commenti più vecchi. Quindi, se l'utente desidera espandere i thread, potrebbe richiederlo, ma per impostazione predefinita vedrebbe solo un sottoinsieme della discussione. Se vuoi maggiori dettagli, scarica il sorgente Slashdot e guarda come lo fanno. http://slashcode.com/ –

+0

grazie per la risposta, tuttavia se sto capendo correttamente, questo mostrerebbe solo i thread di commento originali e quindi se volessero espandere un thread di commenti per vedere eventuali risposte, faresti una selezione su quel thread di commenti, tuttavia voglio davvero mostrare anche le risposte dei thread di commento nella prima query, ma anche essere in grado di LIMIT? .. è possibile utilizzare la gerarchia di adiacenza? .. grazie ancora J. – jon