Moje pytanie dotyczy modelowania relacji jeden-do-wielu w ndb. Rozumiem, że można to zrobić na (przynajmniej) na dwa różne sposoby: z powtarzającą się własnością lub z "obcym kluczem". Poniżej stworzyłem mały przykład. Zasadniczo mamy artykuł, który może mieć dowolną liczbę znaczników. Załóżmy, że tag można usunąć, ale nie można go zmienić po dodaniu. Załóżmy też, że nie martwimy się bezpieczeństwem transakcyjnym.Modelowanie ndb jeden-do-wielu: zalety powtarzania KeyProperty kontra klucz obcy
Moje pytanie brzmi: jaki jest preferowany sposób modelowania tych relacji?
Moje rozważania:
- Approach (A) wymaga dwóch pisze dla każdego znacznika, który jest dodawany do artykułu (jeden dla artykułu oraz jeden dla Tag) natomiast zbliżyć (b) wymaga tylko jeden pisze (tylko Tag).
- Approach (A) wykorzystuje mechanizm buforowania NDB, gdy ściągam wszystkie tagi do artykułu natomiast w przypadku podejścia (b) jest wymagane zapytanie (a dodatkowo niektóre zwyczaj buforowania)
istnieją pewne rzeczy że tu jestem, jakieś inne uwagi, które należy wziąć pod uwagę?
Dziękuję bardzo za pomoc.
Przykład (A):
class Article(ndb.Model):
title = ndb.StringProperty()
# some more properties
tags = ndb.KeyProperty(kind="Tag", repeated=True)
def create_tag(self):
# requires two writes
tag = Tag(name="my_tag")
tag.put()
self.tags.append(tag)
self.put()
def get_tags(self):
return ndb.get_multi(self.tags)
class Tag(ndb.Model):
name = ndb.StringProperty()
user = ndb.KeyProperty(Kind="User") # User that created the tag
# some more properties
Przykład (B):
class Article(ndb.Model):
title = ndb.StringProperty()
# some more properties
def create_tag(self):
# requires one write
tag = Tag(name="my_tag", article=self.key)
tag.put()
def get_tags(self):
# obviously we could cache this query in memcache
return Tag.gql("WHERE article :1", self.key)
class Tag(ndb.Model):
name = ndb.StringProperty()
article = ndb.KeyProperty(kind="Article")
user = ndb.KeyProperty(Kind="User") # User that created the tag
# some more properties
Rozważ sprawdzanie wydajności za pomocą appstats, ponieważ podczas gdy twoje konkretne pytanie może mieć konkretną odpowiedź, prawdopodobnie bardziej odnosi się do twojego rzeczywistego użycia, a więc appstats może ci powiedzieć, które z powyższych opcji są bardziej skuteczne w życiu. https://developers.google.com/appengine/docs/python/tools/appstats –
Czy utworzyć nowe tagi dla każdego artykułu, nawet jeśli jest to ten sam tag? wybrałbym opcję "A", ponieważ będziesz mógł użyć tego samego "tagu" dla każdego artykułu, a będziesz w stanie przesłać zapytanie "Artykuły" według tagu. – aschmid00
@PaulC thanks. Rzeczywiście sprawdziłem z appstats iw moim przypadku opcja B jest bardziej wydajna (1 write vs 2). Ponieważ jednak optymalizacja jest niewielka, nie jestem pewien, czy warto byłoby zrezygnować z udokumentowanej metody (np. Opcji A) w celu rozwiązania relacji jeden do wielu. –