2012-02-25 12 views
0

私は以下のようなデータを保持する必要があります。GAEデータストアにデータを正しく保存するにはどうすればよいですか?

field1value=SomeStringValue 
field1score=10 
field2value=SomeOtherValue 
field2score=20 
... 
fieldNvalue=SomeNValue 
fieldNscore=N 

つまり、私はNフィールドを持って、各フィールドには、独自の名前、そこに格納された値とスコアを持っています。そのようなデータをGAEデータストアに正しく保存するにはどうすればよいですか?データはフィールド名で簡単にアクセスできます。また、最終得点(field1score + field1score + ... + fieldNscore)を計算する必要があります。

Nは約100です。データベース内のレコードの総数は膨大になります。

Upd。は、私は、次のアプローチを使用し、それは最高のものではないように見えました:

class User(db.Model): 
    field_names = db.StringListProperty() 
    field_values = db.StringListProperty() 
    field_scores = db.ListProperty(int) 
    score_value = db.IntegerProperty() 

def fields_add(user_key_name, field_name, field_value, field_score): 
    user = User.get(user_key_name) 
    if user: 
     field_names = user.field_names 
     field_values = user.field_values 
     field_scores = user.field_scores 
     if field_name in user.field_names: 
      field_index = user.field_names.index(field_name) 
      field_values[field_index] = field_value 
      field_scores[field_index] = field_score 
     else: 
      field_names.append(field_name) 
      field_values.append(field_value) 
      field_scores.append(field_score) 
     user.field_names = field_names 
     user.field_values = field_values 
     user.field_scores = field_scores 
     # TODO: update user.score_value 
     user.put() 

答えて

0

おそらくあなたのアクセスパターンが似ているかに依存し、どのようなNの最大値です。

最も簡単な方法は、2 ListPropertiesを維持するために、次のようになります。

from google.appengine.ext import db 

class MyClass(db.Model): 
    valueList = db.StringListProperty() 
    scoreList = db.ListProperty(int) 
+0

ありがとう、Raven。フィールド名は何ですか?私は3番目のリストを持っているべきですか? –

+0

@LA_フィールド名のリストが静的な場合は、<->という名前のルックアップを維持し、Userクラスに格納しないこともできます。良いデフォルト(ゼロ?)の同じサイズの配列に皆を初期化するだけです。しかし、特定の名前付きスコアに基づいてクエリを実行する場合は、値/スコアをリストに格納する代わりに、各フィールドを明示的にリストすることを検討するとよいでしょう。私はこれを動的に行うことができると確信しています。200のプロパティを入力する必要はありません(また、フィールドのリストが静的でない場合はExpandoモデルが適切かもしれません)。 – Raven

1

これはあなたのアクセス・パターンに依存します。より詳細な情報と要件を知ることで、より良い答えが得られます。

これ以外の方法では分離できないエントリが5000を超える場合は、以下のような簡単な構造を使用する必要があります。得点の合計を得るには、allを照会してメモリーに追加することができます。多数のスコアがある場合は、MapReduceを使用してオンデマンドで合計を検索するか、または合計を維持するためにshard counterを使用できます。

class Score(db.Model): 
    value = db.StringProperty() 
    score = db.IntegerProperty() 

ListPropertyは、5000を超えるエントリがない場合に使用できます。これにより、すべての結果を返すクエリーが1つしかないので、メモリ内で合計することができるため、データストアの読み込みと書き込みの回数がはるかに少なくなります。 3番目のデータがある場合(以下の選手フィールドのように)、5000件未満のエントリがあることを保証できます。これはまあまあの解決策です。

class Score(db.Model): 
    player = db.StringProperty() 
    values = db.StringListProperty() 
    scores = db.ListProperty(int) 
+0

データストア内のレコードの総数は5000以上になりますが、フィールド数(上記のN)は約100になります。 –