2

我的背景是关系数据库,我正在用 Google AppEngine 做一些实验,主要是为了学习。我想构建一个“选举”应用程序,其中用户属于一个州(加利福尼亚州、纽约州、德克萨斯州等),他们选择一个政党(共和党、民主党等)并为特定年份投票(目前为 2012 年,但该应用程序可以在 2016 年重复使用)。

我希望用户能够查看他们的投票历史记录,并可能在当前选举中更改一次。此外,我将要求用户指定他们的邮政编码,并认为按州和/或邮政编码运行一些报告会很好。

使用关系数据库,您似乎会创建一些像这样的表:

Users(userid, username, city, state, zip)
UserVote(userid, year, vote)

然后使用 SQL 运行报表。对于 AppEngine 数据存储,运行汇总报告似乎有些困难。

我最初的想法是User在每个用户可以包含一个列表的位置进行分片Votes,然后可能会将聚合双重保存在其他地方。

有什么建议么?

PS 我已经看过AppEngine-MapReduce项目,但不确定这是否是矫枉过正。

4

1 回答 1

1

我不记得我在哪里读到这篇文章,但是 GAE 中的 List 属性在达到大约 200 个项目后会变慢。我建议不要这样做,而支持用户和投票的外键方法。

聚合是一个挑战,因为没有常见的辅助函数,如 MAX、SUM、COUNT 等。最好的方法是将聚合和计数存储在单独的数据类型中,您可以轻松查询并在每次用户投票时更新它。在 AppEngine 中,您可以更轻松地花时间进行编写,以便您以后可以进行更快的查询。

下面是 Java 中的对象示例:

@PersistenceCapable
public class User{
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;
    ...
}

@PersistenceCapable
public class Vote{
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    @Persistent
    private Key userKey;  // References a User
    ...
}

@PersistenceCapable
public class UserStats{
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    @Persistent
    private Key userKey;  // References a User
    ...
}

此外,传统的分片在 AppEngine 中没有多大意义,因为底层数据存储旨在轻松处理对海量数据集的查询。例外情况是,如果您有一个可以经常更改的特定计数器,并且有可能让多个用户同时更改它。这是一种不同于您在 MySQL 中使用的分片类型。这是 Google 关于分片计数器的文章:http ://code.google.com/appengine/articles/sharding_counters.html

于 2011-05-31T03:41:35.280 回答