Struttura dati corretta per commenti commentabili

4

Hai lottato con questo a livello di architettura.

Ho un oggetto che può essere commentato, chiamiamolo Post . Ogni post ha un ID univoco.

Ora voglio commentare quel Post e posso usare l'ID come chiave esterna, e ogni PostComment ha un campo ItemID che si correla al Post. Poiché ogni post ha un ID univoco, è molto facile assegnare i commenti "di primo livello".

Quando commento un commento, tuttavia, sento che ora ho bisogno di un PostCommentComment, che si collega all'ID del PostComment. Dato che gli ID sono assegnati in sequenza, non posso più semplicemente usare ItemID per differenziare dove nell'albero è assegnato il commento. OSSIA sia un post che un commento possono avere un ID di "5", quindi la mia relazione di chiave esterna non è valida.

Sembra che potrebbe continuare all'infinito, con PostCommentCommentComment's etc ...

Qual è il modo migliore per risolvere questo? Dovrei avere un campo nel commento chiamato "IsPostComment" o qualcosa del genere per sapere a quale collezione allegare l'ID? Questo mi sembra la soluzione migliore che ho visto finora, ma ora mi sento come se avessi bisogno di effettuare chiamate ricorsive a DataBase che iniziano a diventare costose.

Significato, ottengo un Post e ottieni tutti i PostComments where ItemID == Post.ID && where IsPostComment == true

Poi lo prendo come una raccolta, raccolgo tutti gli ID di PostComments , e faccio un'altra ricerca where ItemID == PostComment[all].ID && where IsPostComment == false , quindi ripeterò all'infinito.

Ciò significa che effettuo una chiamata per ogni livello e, se sto chiamando 100 post, potrei fare 1000 chiamate DB per ottenere 10 livelli di commenti ciascuno.

Qual è il modo giusto per farlo?

    
posta Wesley 28.08.2012 - 21:50
fonte

2 risposte

11

Tutto ciò di cui hai bisogno è un PostID per ogni cosa che un utente scrive e un ParentPostID che è annullabile e punta a un% gen coe%. Se è nullo, è un post e, se non è nullo, è un commento. I commenti possono contenere commenti.

Struttura ad albero di base.

    
risposta data 28.08.2012 - 21:54
fonte
4

Ecco un esempio per SQL Server 2005+ basato sulla risposta di Scott sopra.

CREATE TABLE posts 
(
    PostID INT NOT NULL CONSTRAINT PK_Posts PRIMARY KEY IDENTITY(1,1)
    , ParentPostID INT NULL, PostText NVARCHAR(255)
);

INSERT INTO posts VALUES (NULL, 'This is top-level post #1');
INSERT INTO posts VALUES (NULL, 'This is top-level post #2');
INSERT INTO posts VALUES (1, 'This is a comment on post #1');
INSERT INTO posts VALUES (1, 'This is also a comment on post #1');
INSERT INTO posts VALUES (3, 'This is a sub-comment on comment #1');
INSERT INTO posts VALUES (2, 'This is a comment on post #2');
INSERT INTO posts VALUES (2, 'This is a comment on post #2');

WITH Comments(ParentID, PostText)
AS 
(
    SELECT ParentPostID, posts.PostText 
FROM posts 
WHERE ParentPostID IS NOT NULL
    UNION ALL
    SELECT ParentPostID, posts.PostText 
FROM posts 
    INNER JOIN Comments c ON posts.PostID = c.ParentID 
)
SELECT p1.PostText AS Post, Comments.PostText AS Comment
FROM Comments 
LEFT JOIN posts p1 ON Comments.ParentID = p1.PostID
WHERE ParentID IS NOT NULL;

Ecco il risultato:

    Post                            Comment
    This is top-level post #1       This is a comment on post #1
    This is top-level post #1       This is also a comment on post #1
    This is a comment on post #1    This is a sub-comment on comment #1
    This is top-level post #2       This is a comment on post #2
    This is top-level post #2       This is a comment on post #2
    This is top-level post #1       This is a comment on post #1
    
risposta data 28.08.2012 - 23:06
fonte

Leggi altre domande sui tag