Google Appengine DataStore의 계층 적 최적화
-
06-07-2019 - |
문제
나는 다음과 같은 것처럼 보이는 모델을 사용하여 데이터 저장소에 저장된 계층 적 데이터가 있습니다.
class ToolCategories(db.Model):
name = db.StringProperty()
parentKey = db.SelfReferenceProperty(collection_name="parent_category")
...
...
계층 구조를 유지하는 모든 카테고리 이름을 인쇄하고 싶습니다.
--Information Gathering
----OS Fingerprinting
----DNS
------dnstool
----Port Scanning
------windows
--------nmap
----DNS3
----wireless sniffers
------Windows
--------Kismet
위의 작업을 수행하기 위해 후면 참조 기능을 사용하여 간단한 재귀를 사용했습니다.
class GetAllCategories (webapp.RequestHandler) :
def RecurseList(self, object, breaks) :
output = breaks + object.name + "</br>"
for cat in object.parent_category:
output = output + self.RecurseList(cat, breaks + "--")
return output
def get (self) :
output = ""
allCategories = ToolCategories.all().filter(' parentKey = ', None)
for category in allCategories :
output = output + self.RecurseList(category, "--")
self.response.out.write(output)
App Engine 프로그래밍을 처음 접했기 때문에 (코드 작성을 시작한 지 거의 3 일이 지났음), 데이터 스토어 액세스 관점에서 가장 최적화 된 방법이 원하는 작업을 수행하기 위해 가장 최적화 된 방법인지 확실하지 않습니다.
이것이 가장 좋은 방법입니까? 그렇지 않다면?
해결책
당신은 매우 합리적인 접근 방식이 있습니다! 나의 주요 경고는 GAE와 거의 관련이없고 Python과는 많은 경고가 될 것입니다. ~하지 않다 조각에서 끈을 만듭니다 +
또는 +=
. 오히려, 당신은 문자열 조각 목록을 만듭니다 ( append
또는 extend
또는 COMPREHENSIONS & C를 나열하고 모두 완료되면 최종 문자열 결과에 가입합니다. ''.join(thelist)
또는 같은. 최근의 Python 버전은 본질적으로 최적화하기 위해 열심히 노력하지만 O(N squared)
성능 +
또는 +=
루프, 결국 당신은 길을 따라 줄 목록을 만드는 것이 좋습니다. ''.join
끝에 그들을 ing!
다른 팁
접근 방식의 주요 단점은 트리를 나타내는 "인접력 목록"방법을 사용하기 때문에 트리의 각 지점에 대해 하나의 데이터 스토어 쿼리를 수행해야한다는 것입니다. DataStore 쿼리는 상당히 비싸기 때문에 (각각 약 160ms) 나무를 구성하는 것은 특히 큰 경우 트리를 구성하는 것이 다소 비쌀 수 있습니다).
기본적으로 엔티티 그룹을 대표하기 위해 데이터 스토어가 취한 또 다른 접근법이 있습니다. 부모 키를 저장하는 대신 ListProperty를 사용하여 조상의 전체 목록을 저장하십시오.
class ToolCategories(db.Model):
name = db.StringProperty()
parents = db.ListProperty(db.Key)
그런 다음 나무를 구성하려면 하나의 단일 쿼리에서 전체를 검색 할 수 있습니다.
q = ToolCategories.all().filter('parents =', root_key)