문제

스레드 댓글을 지원할 수있는 웹 응용 프로그램을 개발 중입니다. 받은 투표 수에 따라 의견을 재정렬 할 수있는 능력이 필요합니다. (나사의 주석이 작동하는 방식과 동일합니다 레딧)

SO 커뮤니티의 입력을 듣고 싶습니다.

어떻게 설계해야합니까? 코멘트 테이블? 여기에 내가 사용하고있는 구조는 다음과 같습니다.

Comment
    id
    parent_post
    parent_comment
    author
    points

이 구조에 어떤 변화가 있어야합니까?

이 테이블에서 세부 정보를 올바른 방식으로 표시하려면 어떻게해야합니까? (모든 언어 구현을 환영합니다. 최선의 방법으로 수행하는 방법을 알고 싶습니다)

CPU/데이터베이스에 부하가 적을 수 있도록이 기능을 구현하면서 조심해야 할 사항은 무엇입니까?

미리 감사드립니다.

도움이 되었습니까?

해결책

데이터베이스에 트리를 저장하는 것은 다양한 솔루션을 가진 주제입니다. 그것은 당신이 subhierarchy를 검색하려는 경우 (따라서 항목 X의 모든 어린이) 또는 전체 계층 세트를 잡고 사전을 사용하여 메모리의 O (n) 방식으로 트리를 만들려고하는 경우에 따라 다릅니다.

테이블은 ParentPost를 필터링하여 1 GO의 게시물에 모든 의견을 가져올 수있는 이점이 있습니다. 교과서/순진한 방식으로 주석의 부모를 정의 했으므로 트리를 메모리에 만들어야합니다 (아래 참조). DB에서 트리를 얻으려면 트리를 저장하는 다른 방법이 필요합니다. 여기에서 사전 CALC 기반 접근법에 대한 설명을 참조하십시오.http://www.llblgen.com/tinyforum/gotomessage.aspx?messageid=17746&threadid=3208또는에 의해 Celko가 묘사 한 균형 잡힌 나무 사용:

또는 또 다른 접근법 :http://www.sqlteam.com/article/more-trees-hierarchies-in-sql

메모리의 계층 구조로 모든 것을 가져와 트리를 만들면 쿼리가 매우 간단하다는 사실 때문에 더 효율적일 수 있습니다. select .. parentpost where parentpost = @id 주문에서 hate ..

그 쿼리 후, 당신은 튜플 commentid- 댓글을 추적하는 단 1 사전으로 메모리에 트리를 빌드합니다. 이제 결과 세트를 걸어 가서 즉석에서 나무를 만듭니다. 당신이 달리는 모든 의견은 사전에서 부모를 조회 한 다음 해당 사전에서도 현재 처리 된 주석을 저장할 수 있습니다.

다른 팁

고려해야 할 몇 가지 사항 ...

1) 순위 또는 날짜를 기준으로 "Reddit과 같은 종류"라고 말할 때, 최상위 또는 모든 것을 의미합니까?

2) 노드를 삭제하면 분기는 어떻게됩니까? 당신은 그들을 다시 부모에게 입수합니까? 내 구현에서, 나는 편집자들이 노드를 숨기고 눈에 보이는 어린이들과 함께 "댓글 숨겨진"것으로 표시하거나, 주석을 숨기거나, 나무 전체를 핵무기로 표시 할 것이라고 생각합니다. 다시 부모는 쉬워야하지만 (Chidren의 부모를 삭제 된 부모에게 설정) 전체 트리와 관련된 것은 데이터베이스에서 구현하기가 까다로워 보입니다.

나는보고 있었다 Ltree PostgreSQL 모듈. 트리의 일부와 관련된 데이터베이스 작업을 조금 더 빨리 만들어야합니다. 기본적으로 테이블에 필드를 설정할 수 있습니다.

ltreetest=# select path from test where path <@ 'Top.Science';
                path                
------------------------------------
 Top.Science
 Top.Science.Astronomy
 Top.Science.Astronomy.Astrophysics
 Top.Science.Astronomy.Cosmology

그러나 그것은 자체적으로 어떤 종류의 참조 무결성을 보장하지 않습니다. 다시 말해, "top.science"또는 "top"에 대한 기록이 없으면 "top.science.astronomy"에 대한 레코드를 가질 수 있습니다. 그러나 그것이 당신이하는 일은 다음과 같은 것입니다.

-- hide the children of Top.Science
UPDATE test SET hide_me=true WHERE path @> 'Top.Science';

또는

-- nuke the cosmology branch
DELETE FROM test WHERE path @> 'Top.Science.Cosmology';

저장된 절차를 사용하여 기존의 "comment_id"/"parent_id"접근법과 결합 된 경우 두 세계를 최대한 활용할 수 있다고 생각합니다. "경로"를 사용하여 데이터베이스에서 주석 트리를 신속하게 통과하고 "comment_id"/"parent_id"를 통해 참조 무결성을 보장 할 수 있습니다. 나는 다음과 같은 것을 상상하고있다.

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
);

주석의 경로 문자열은 BE처럼 보입니다

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

따라서 "1"의 댓글 _id가있는 스레드 "102"의 루트 주석은 다음과 같은 경로를 갖습니다.

102.1

댓글이 "3"인 어린이는 다음과 같습니다.

102.1.3

"31"및 "54"의 ID를 가진 "3"의 일부 어린이는 다음과 같습니다.

102.1.3.31
102.1.3.54

노드 "3"과 그 아이들을 숨기려면 다음과 같은 발행됩니다.

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

그래도 나는 불필요한 오버 헤드를 추가 할 수 있습니다. 게다가 나는 Ltree가 얼마나 잘 유지되었는지 모르겠습니다.

현재 디자인은 기본적으로 작은 계층 구조에 적합합니다 (수천 항목 미만)

Certian 레벨 또는 깊이를 가져 오려면 구조에 '레벨'항목을 추가하고 저장의 일부로 계산하십시오.

성능이 문제 인 경우 괜찮은 캐시를 사용하십시오

위의 Tabel에 다음 새 필드를 추가하겠습니다.

  • Thread_id : 특정 개체에 첨부 된 모든 주석에 대한 식별자

  • 날짜 : 댓글 날짜 (댓글을 순서대로 가져올 수 있음)

  • RANK : 댓글 순위 (순위를 통해 댓글 주문을 가져올 수 있음)

이 필드를 사용하면 다음을 수행 할 수 있습니다.

  1. 단일 OP의 스레드에서 모든 주석을 가져 오십시오.
  2. 날짜 또는 순위별로 스레드에서 댓글을 주문

불행히도 SQL 표준에 가까운 쿼리 DB를 보존하려면 메모리에서 트리를 재현해야합니다. 일부 DBS는 계층 적 데이터에 대한 특별 쿼리를 제공합니다 (Fe Oracle)

./alex

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top