2010-11-25 2 views
5

하나 이상의 태그로 표시된 게시물 (예 : 게시물)이 많습니다. 게시물을 작성하거나 삭제할 수 있으며 사용자는 하나 이상의 태그 (논리 AND와 결합)에 대한 검색 요청을 할 수 있습니다. 내 마음에 온 첫 번째 아이디어는 간단한 모델을 생성 및 삭제 작업의Google App Engine (Python)의 확장 성이 뛰어난 태그

class Post(db.Model): 
    #blahblah 
    tags = db.StringListProperty() 

구현을 분명했다. 검색은 더욱 복잡합니다. N 개의 태그를 검색하려면 "SELECT * FROM Post WHERE tags = : 1"과 같은 N 개의 GQL 쿼리를 수행하고 커서를 사용하여 결과를 병합하면 성능이 좋지 않습니다.

두 번째 아이디어는 다른 엔티티

class Post(db.Model): 
    #blahblah 
    tags = db.ListProperty(db.Key) # For fast access 

class Tag(db.Model): 
    name = db.StringProperty(name="key") 
    posts = db.ListProperty(db.Key) # List of posts that marked with tag 

그것은 키 (훨씬 더 빨리 GQL에 의해 받아보다) 및 메모리에 병합 생각이 구현은 더 나은 성능을 제공하여 DB에서 태그 소요에 태그를 분리하는 것입니다 첫 번째 태그보다 더 많이 사용할 수 있지만 자주 사용되는 태그는 단일 데이터 저장소 개체에 허용되는 최대 크기를 초과 할 수 있습니다. 또 다른 문제가 있습니다. 데이터 저장소는 하나의 객체를 ~ 1/초로만 수정할 수 있기 때문에 자주 사용되는 태그의 경우 수정 대기 시간에 병목 현상이 있습니다.

제안 사항?

답변

0

아마도 두 번째 예제를 사용하여 큰 세트에 대한 효율적인 쿼리를 허용하는 방식으로 수정할 수 있습니다. 마음에 드는 한 가지 방법은 단일 태그에 대해 여러 데이터베이스 엔터티를 사용하고 거의 그룹을 확보하지 않아도되도록 그룹화하는 것입니다. 기본 정렬 순서 (우물 만 허용하는 경우)는 게시일 기준이며, 태그 그룹 엔티티를이 순서대로 채 웁니다. 추가하거나 그룹에 태그를 제거 할 때

class Tag(db.Model): 
    name = db.StringProperty(name="key") 
    posts = db.ListProperty(db.Key) # List of posts that marked with tag 
    firstpost = db.DateTimeProperty() 

, 100 개 게시물 말, 당신이 게시물을 만들 것입니다 추가 포스트가 이상이있는 경우, 해당 그룹에 얼마나 많은 게시물 확인 개의 태그로 분할 여러 떼. 그룹의 게시물 수가 50 개 미만이되도록 게시물을 제거하는 경우 이전 그룹 또는 다음 그룹의 게시물을 훔칩니다. 인접한 그룹 중 하나에 50 개의 게시물이있는 경우 함께 병합하십시오. 태그를 기준으로 게시물을 게시일 기준으로 나열 할 때 소수의 그룹 만 있으면됩니다.

이는 수요가 많은 태그 문제를 실제로 해결하지 못합니다.

생각해 보면 인서트가 좀 더 추측적일 수도 있습니다. 최신 태그 그룹 항목을 가져 와서 병합하고 새 태그 그룹을 배치하십시오. 트랜잭션의 지연은 실제 문제가 아닐 수도 있습니다.

+1

게시물 지연을위한 저널을 구현하면 트랜잭션 지연을 해결할 수 있습니다. 게시물이 추가 대기 중일 때 - memcache 복사가 만료 된 경우 저널이있는 각 태그에 대해 "해당 게시물이 해당 태그에 속합니다"(태그 엔티티의 memcache 사본을 수정 함)와 같은 정보가있는 특수 오브젝트를 작성합니다 applier는 모든 저널 항목을 수집하여 데이터 저장소의 태그 엔티티에 적용합니다 (또한 memcache로 복사). –

관련 문제