2011-05-30 107 views
2

我的背景是關係數據庫的,我正在做一些實驗,主要用於學習Google AppEngine。我想建立一個「選舉」應用程序,用戶屬於一個州(CA,NY,TX等),他們選擇一個黨(共和黨,民主黨等),並投票支持某一年該應用可以在2016年重新使用)。谷歌AppEngine分片問題

我希望用戶能夠看到他們的投票歷史,並且可能會在當前選舉中更改一次。此外,我將要求用戶指定他們的郵政編碼,並認爲按州和/或郵政編碼運行一些報告會很好。

使用關係數據庫,看來你會創造一些像這樣的表:

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

然後使用SQL來運行報告。使用AppEngine數據存儲區看來,運行彙總報告似乎是一項挑戰。

我最初的想法是按User分片,其中每個用戶可以包含一個Votes的列表,然後可以雙重保存其他地方的聚合。

有什麼建議嗎?

P.S.我見過AppEngine-MapReduce項目,但我不確定這是否會過度。

+0

你是什麼意思的'用戶分片'?爲什麼mapreduce過度殺傷? – 2011-05-30 21:53:02

+0

關於'用戶分片' - 根據我對數據存儲的有限瞭解,除非存在層次關係,否則無法跨實體加入。仔細挑選「根」實體(即用戶)可讓您按相關實體進行查詢。關於mapreduce的過度殺傷 - 看起來它可能是一種計算聚合的方法,但在我嘗試學習的許多其他事物之上增加了一層額外的複雜性。 – dana 2011-05-31 14:46:09

回答

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中習慣的不同類型的分片。這裏是谷歌關於分片計數器的文章:http://code.google.com/appengine/articles/sharding_counters.html

+0

感謝您的提示!不幸的是,我認爲這可能是一個場景,多個用戶可以同時更新同一個計數器:((來自同一州的2個用戶投票)我認爲這可能是值得我去查看mapreduce項目,但我喜歡你的建議,從'Stats'中的'Vote'中分出'User'。 – dana 2011-05-31 14:54:06

+0

你可以將計數器分割。例如,請參閱http://code.google.com/p/google-app - 發動機採樣/源/瀏覽/中繼/分片的計數器/ generalcounter.py – 2011-08-04 04:34:17