如何在App Engine中建模关注者流?

3 投票
4 回答
975 浏览
提问于 2025-04-15 23:05

我正在设计一些表格,用来建立用户之间的关注关系。

假设我有一串140个字符的记录,这些记录包含用户、话题标签和其他文本。

用户可以关注其他用户,也可以关注话题标签。

下面是我设计的思路,但我的设计有两个限制。我想知道有没有人有更聪明的方法来实现同样的目标。

这个设计的问题是:

  1. 每条记录都复制了一遍关注者的列表。
  2. 如果新增一个关注者或者移除一个关注者,'所有'的记录都得更新。

代码如下:

class HashtagFollowers(db.Model):
    """
    This table contains the followers for each hashtag
    """
    hashtag = db.StringProperty()
    followers = db.StringListProperty()

class UserFollowers(db.Model):
    """
    This table contains the followers for each user
    """
    username = db.StringProperty()
    followers = db.StringListProperty()

class stream(db.Model):
    """
    This table contains the data stream
    """
    username = db.StringProperty()
    hashtag = db.StringProperty()
    text = db.TextProperty()

    def save(self):
        """
        On each save all the followers for each hashtag and user
        are added into a another table with this record as the parent
        """
        super(stream, self).save()
        hfs = HashtagFollowers.all().filter("hashtag =", self.hashtag).fetch(10)
        for hf in hfs:
            sh = streamHashtags(parent=self, followers=hf.followers)
            sh.save()
        ufs = UserFollowers.all().filter("username =", self.username).fetch(10)
        for uf in ufs:
            uh = streamUsers(parent=self, followers=uf.followers)
            uh.save()



class streamHashtags(db.Model):
    """
    The stream record is the parent of this record
    """
    followers = db.StringListProperty() 

class streamUsers(db.Model):
    """
    The stream record is the parent of this record
    """
    followers = db.StringListProperty()

Now, to get the stream of followed hastags 

    indexes = db.GqlQuery("""SELECT __key__ from streamHashtags where followers = 'myusername'""")
    keys = [k,parent() for k in indexes[offset:numresults]]
    return db.get(keys)

有没有更聪明的方法来做到这一点呢?

4 个回答

0

你可以使用一种叫做引用属性的东西,然后创建一个包含所有关注者的公共表格,这样你就可以通过这个表格来进行引用。

5

你想解决的问题被称为“扇出问题”。

来自谷歌应用引擎团队的Brett Slatkin曾做过一个演讲,介绍了一个高效且可扩展的解决方案来应对扇出问题。你可以在这里找到这个演讲的视频:

http://code.google.com/events/io/2009/sessions/BuildingScalableComplexApps.html

1

是的,这就是大家提到的“扇出问题”,如果你对这个感兴趣,可以看看Brett Slatkin的演讲。

不过,我提到了两个具体的限制,也就是:

  • 每条记录都要复制一遍关注者的列表。

他们说这不是个bug,而是一种特性。实际上,正是通过这种方式,App Engine上的扇出才能扩展。

  • 如果添加了新的关注者或者移除了某个关注者,所有的记录都得更新。

要么这样,要么就什么都不做,这样未来的记录就不会被关注。换句话说,你并不是一直关注某个人的动态,而是关注某个人在特定时间的动态。所以如果在第二天你取消关注,你的关注列表仍然会显示第一天的记录,但不会显示第二天及之后的记录。[注意:这和推特的做法不同]

撰写回答