parent-> appengine python中的子关系(bigtable)

Bob*_*ian 9 python google-app-engine database-design bigtable nosql

我还在学习bigtable/nosql中关于数据建模的课程,并希望得到一些反馈.如果我经常需要与父母一起处理这些孩子,那么我的数据建模中是否应该避免父母与子女的关系,这是否公平?

举个例子,假设我正在建立一个博客,该博客将由许多作者提供,彼此有帖子,每个帖子都有标签.所以我可能会设置这样的东西:

class Author(db.Model): 
  owner = db.UserProperty()

class Post(db.Model): 
  owner = db.ReferenceProperty(Author, 
    collection_name='posts') 
  tags = db.StringListProperty() 
Run Code Online (Sandbox Code Playgroud)

据我了解,这将创建一个基于作者父级的实体组.如果我主要需要通过标签查询Posts,这会导致效率低下吗?

我理解对列表属性进行查询可能效率低下.假设每个帖子平均有大约3个标签,但可以一直到7个.我希望我的可能标签集合可以达到数百个.将模型改为这样的东西有什么好处吗?

class Author(db.Model): 
  owner = db.UserProperty()

class Post(db.Model): 
  owner = db.ReferenceProperty(Author, 
    collection_name='posts') 
  tags = db.ListProperty(db.Key)

class Tag(db.Model): 
  name = db.StringProperty() 
Run Code Online (Sandbox Code Playgroud)

或者我会做这样的事情会更好吗?

class Author(db.Model): 
  owner = db.UserProperty()

class Post(db.Model): 
  owner = db.ReferenceProperty(Author, 
    collection_name='posts')

class Tag(db.Model): 
  name = db.StringProperty() 

class PostTag(db.Model): 
  post = db.ReferenceProperty(Post, 
    collection_name='posts') 
  tag = db.ReferenceProperty(Tag, 
    collection_name='tags') 
Run Code Online (Sandbox Code Playgroud)

最后一个问题......如果我最常见的用例是通过多个标签查询帖子怎么办?例如,"在{'apples','oranges','cucumbers','bicycles'}中查找带有标签的所有帖子" 这些方法中的一种更适合查找具有任何标签集合的帖子的查询吗?

谢谢,我知道那是满口的.:-)

Rob*_*uin 5

像第一种或第二种方法的东西非常适合App Engine.请考虑以下设置:

class Author(db.Model): 
  owner = db.UserProperty()

class Post(db.Model): 
  author = db.ReferenceProperty(Author, 
    collection_name='posts') 
  tags = db.StringListProperty()

class Tag(db.Model): 
  post_count = db.IntegerProperty()
Run Code Online (Sandbox Code Playgroud)

如果使用字符串标记(case-normalized)作为Tag实体key_name,则可以有效地查询具有特定标记的帖子,或列出帖子的标记或获取标记统计信息:

post = Post(author=some_author, tags=['app-engine', 'google', 'python'])
post_key = post.put()
# call some method to increment post counts...
increment_tag_post_counts(post_key)

# get posts with a given tag:
matching_posts = Post.all().filter('tags =', 'google').fetch(100)
# or, two tags:
matching_posts = Post.all().filter('tags =', 'google').filter('tags =', 'python').fetch(100)

# get tag list from a post:
tag_stats = Tag.get_by_key_name(post.tags)
Run Code Online (Sandbox Code Playgroud)

第三种方法需要对大多数基本操作进行额外的查询或提取,如果要查询多个标记则更加困难.