2009-07-10 5 views
0

MS SQL Server 2005를 사용 중입니다.고성능 위키 스키마

위키 계열 시스템에 가장 적합한 스키마는 무엇입니까? 여기서 사용자는 제출물을 편집/수정하고 시스템은 이러한 제출물을 추적합니다.

우리는 간단한 위키 기반 시스템을 만들고 있다고합니다. 각 개정판과 각 개정판의보기 및 최신 활동을 추적합니다. 다른 화면에서 시스템은 "Latest Submissions"및 "Most Viewed"를 나열하고 제목으로 검색합니다.

내 현재 스키마 (및 그 나쁜 사실을 알고 있습니다)는 단일 테이블을 사용하고 있습니다. "Latest Submissions"를보고 싶을 때 "LatestActivity"로 분류하고 "DocumentTitle"로 그룹화 한 다음 첫 번째 N 레코드를 가져옵니다. 많은 그룹화 (특히 nvarchar에서 그룹화)는 나쁜 소식이라고 가정합니다. 조회수가 가장 많은 항목을 나열하려면보기별로 정렬하고, 이름별로 그룹화하고, 첫 번째 N 개의 레코드를 취합니다. 대부분의 경우, 나는 또한 "Where DocumentName LIKE '% QUERY-HERE %'"를 수행 할 것입니다. 나의 현재 스키마 "버전 1"

, 아래 참조 : alt text http://www.anaimi.com/junk/schemaquestion.png

나는이 허용되지 않습니다 가정합니다. 그래서 나는 또 다른 /보다 뛰어난 디자인을 고안하려고 노력하고있다. 버전 2는 어떻게 당신에게 소리가 나나요? 버전 2에서는 숫자 인 WikiHeadId를 그룹화하는 이점을 얻습니다. 숫자 위에 그룹화하는 것이 nvarchar보다 낫다고 가정합니다.

아니면 더 그룹화를 수행하지 않습니다 버전 3,하지만 같은

또는 이 더 나은/알려진 스키마가있는 등, 코드에서이 값을 유지하고, 값을 복제 같은 몇 가지 단점을 가지고 극단적 인 경우 그런 시스템을 위해서?

감사합니다.

-

답변

2

먼저 호기심에서 벗어나 현재의 스키마가 현재 버전을 어떻게 나타 냅니까? 동일한 DocumentTitle을 가진 여러 개의 'WikiDocument'항목이 있습니까?

버전 수준에서 'LastActivity'가 필요한 이유가 명확하지 않습니다. 나는 'LastActivity'가 'Version'개념에 어울리는 지 보지 못합니다 - 위키에서 '버전'은 한 번 쓰기가 가능합니다. 버전을 수정하면 이 생성됩니다. 버전에서 마지막으로 업데이트 된 유형 값의 개념은 무의미합니다. 실제로는 '날짜 생성'입니다.

실제로 디자인의 '자연스러운'스키마는 # 2입니다. 개인적으로, 나는 구식 DB 공리의 팬이다. '상처를 입을 때까지 정상화하고, 정상적으로 작동 할 때까지 비정규 화한다.' # 2는 더 깔끔하고 멋진 디자인 (단순함, 중복 없음)이며, 버전 3으로 비정규화할 긴급한 이유가 없다면 걱정하지 않아도됩니다.

궁극적으로, 성능 문제가 발생했기 때문에 '성능이 더 좋은'디자인에 대해 걱정하고 있습니까? 아니면 가상으로 일 수도 있습니다.에 일부가있을 수 있습니까? # 2가 잘 수행되어서는 안되는 진정한 이유는 없습니다. 그룹화는 SQL Server에서 반드시 나쁜 소식이 아닙니다. 실제로 쿼리에 적절한 덮음 인덱스가있는 경우 인덱스의 특정 수준으로 이동하여 그룹화 된 값을 찾아서 사용할 수 있기 때문에 매우 성공적으로 수행 할 수 있습니다. MIN/MAX/whatever에 사용할 인덱스의 나머지 열. NVARCHAR로 그룹화하는 것은 그리 좋지 않습니다. 문제가 아닌 것으로 판명되면 (비 바이너리) 데이터 정렬을 사용하면 다소 까다로워 질지라도 걱정하지 마십시오.하지만 버전 2에서는 필요한 부분이 있습니다. WikiHeadId에서 그룹을 만들 수 있습니다. 맞습니까?

당신이 현재 버전에서 많은 작업을 수행한다면, 헤드 테이블에서 본체 테이블로 FK를 다시 추가하여 현재 버전을 나타내는 작업을 쉽게 할 수 있습니다. 그것이 의미대로 # 2, 히트 가장 높은 번호의 현재 버전을 보려는 경우 지금은 수 있습니다 :

SELECT TOP ... 
FROM WikiHead 
INNER JOIN 
    (SELECT WikiHeadId, MAX(WikiBodyVersion) /* or LastUpdated? */ AS Latest 
    FROM WikiBody GROUP BY WikiHeadId) AS LatestVersions 
INNER JOIN WikiBody ON 
    (Latest.WikiHeadId = WikiBody.WikiHeadId) 
    AND (WikiBody.WikiBodyVersion = LatestVersions.Latest) 
ORDER BY 
    Views DESC 

또는 둘 모두의 대안으로

... 
INNER JOIN WikiBody ON 
    (WikiHead.WikiHeadId = WikiBody.WikiHeadId) 
    AND (WikiBody.WikiBodyVersion = 
    (SELECT MAX(WikiBodyVersion) FROM WikiBody WHERE WikiBody.WikiHeadId = WikiHead.WikiHeadId) 
... 

는 구역질이다. WikiHead 현재 버전에 대한 포인터를 유지하면, 그냥

...  
INNER JOIN WikiBody ON 
    (WikiHead.WikiHeadId = WikiBody.WikiHeadId) 
    AND (WikiHead.Latest = WikiBody.WikiBodyVersion) 
... 

또는 그렇지 않은 성능을 위해, 당신의 인생을 쉽게해서 유용한 비정규 할 수있는 무엇이든.

+0

감사합니다. 버전 1에서는 "버전"속성을 잊어 버렸습니다. 하지만 어쨌든 버전 2를 사용하기 위해 다시 구현했습니다. – ANaimi

0

확인 this 아웃 (에 Serverfault에서 이동 내가는 IT 질문보다는 자사의 개발 질문 더 생각).

데이터베이스 스키마는 mediawiki이며, 위키 백과는 무엇을 기반으로하고 있습니다.

문서화가 잘되어있어 흥미로운 읽을 거리가 될 것입니다.

page.