2011-11-04 16 views
5

Sto creando un'app in cui più utenti possono postare commenti sopra o sotto altri commenti. Questa non è una struttura di tipo thread. È più come collaborare a un documento Word. Sto avendo problemi a progettare il metodo in cui queste voci sono ordinate.Come ordinare/ordinare una lista in cui più utenti inseriscono in posizioni diverse?

Utilizzando mySQL e PHP, l'ordinamento in base all'ora di immissione non funziona e nessuno dei due esegue l'ordinamento in base alla posizione del commento perché la posizione cambia se l'utente inserisce tra altri commenti. Non voglio dover ri-serializzare le posizioni dei commenti per ogni nuova voce (cosa succede se ci sono migliaia di voci e dozzine di utenti che fanno la stessa cosa).

Qual è il modo migliore per progettare questo?

+0

Ricordati di ** accettare ** una risposta se ti ha aiutato a risolvere il tuo problema. –

risposta

-1

Vorrei assolutamente andare con gli ordini per posizione. Quando si inserisce, si tratta solo di incrementare tutte le voci sottostanti - una singola query update. Una caratteristica importante di tale implementazione è che gestisce la concorrenza molto bene; se ci sono due inserimenti simultanei, non ti interessa in quale ordine l'incremento è fatto (ma hai bisogno di un pk non posizionale, quindi non c'è turbamento quando un inserto accade sopra di te).

Un'alternativa è quella di modellarlo come un albero, il che significa che è necessario aggiornare solo le voci sottostanti nel ramo. Ma sarà una situazione rara in cui il sovraccarico di manutenzione è giustificabile. (Un compromesso è modellare come un salice piangente - dividi il totale in pezzi che formano rami, ma non permetti rami da rami, che evita di dover aggiornare ogni singolo record, tuttavia sto ancora indovinando non vale il sovraccarico rispetto al primo approccio.)

+0

Si noti che l'approccio di Gustav ha la peggiore performance dei tre suggerimenti. Vuoi essere in grado di eseguire rapidamente il rendering di un set di risultati possibilmente grandi in HTML, quindi assicurati di prendere in considerazione le prestazioni. – niczero

1

Quello che stai descrivendo è un linked list. Il problema è che di solito sono difficili da recuperare usando solo SQL. La mia soluzione è usare PHP per eseguire l'ordinamento al momento del recupero.

La tabella sarebbe simile a questa:

CREATE TABLE page { 
    page_id INT, 
    first_comment_id INT 
} 

CREATE TABLE comment { 
    comment_id INT PRIMARY KEY AUTOINCREMENT, 
    page_id INT, 
    next_comment_id INT 
} 

tua domanda è semplice:

SELECT comment_id, next_comment_id 
FROM comment 
WHERE page_id = $page_id 
ORDER BY comment_id DESC 

Il passo importante è quello di massaggiare i risultati da mysql_fetch_assoc() in un array che viene indicizzato in base to commentid:

$result = mysql_query($sql); 
$indexed_list = array(); 
while ($row = mysql_fetch_assoc($result)) 
{ 
    $indexed_list[$row['comment_id']] = $row; 
} 

Come risultato in un array simile a questo:

$indexed_list = array(
    1 => array("comment_id"=>1, "next_comment_id"=>2), 
    2 => array("comment_id"=>2, "next_comment_id"=>5), 
    3 => array("comment_id"=>3, "next_comment_id"=>4), 
    4 => array("comment_id"=>4, "next_comment_id"=>0), 
    5 => array("comment_id"=>5, "next_comment_id"=>3)); 

La funzione PHP per ordinarli in ordine visualizzabile è semplice:

function llsort($indexed_list, $first_comment_id) 
{ 
    $sorted_list = array(); 

    $node = $indexed_list[$first_comment_id]; 
    array_push($sorted_list, $node); 

    do 
    { 
     $node = $indexed_list[$node['next_comment_id']]; 
     array_push($sorted_list, $node); 
    } while ($node['next_comment_id'] != 0 
     AND isset($indexed_list[$node['next_comment_id']])); 

    return $sorted_list; 
} 

Si ottiene first_comment_id dalla tabella pagina. Naturalmente, devi ancora implementare le funzioni per inserire un nodo ed eliminare un nodo, ma questi sono lasciati come esercizi per il lettore. Non dimenticare di utilizzare le transazioni per l'inserimento e l'eliminazione dei nodi.

Maggiori informazioni sulle liste collegate in MySQL:

0

questo suona come un buon momento per usare MPTT, Modified Pre -Order Tree Traversa l. Viene spesso utilizzato per le schede commenti con thread e cose di questa natura. Di tutti i modi per mantenere le strutture gerarchiche in un RDBMS, ha l'overhead più basso durante l'eliminazione o l'aggiunta di nodi all'albero.

qui è un good intro, and another. Fare ricerche su Google dovrebbe darti qualche informazione in più. Non è difficile da implementare una volta capito il concetto.

Problemi correlati