2012-02-25 2 views
0

Мне нужно хранить данные, как показано ниже:Как правильно сохранить данные в хранилище данных GAE?

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

т.е. у меня есть N полей, каждое поле имеет свое собственное имя, значение, хранящееся там и оценка. Как правильно хранить такие данные в хранилище данных GAE? Данные должны быть легко доступны по названию поля. Мне также нужно будет рассчитать итоговый балл (field1score + field1score + ... + fieldNscore).

N около 100, общее количество записей в базе данных будет огромным.

Обновление. Я использовал следующий подход, но похоже, что это не самый лучший:

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 есть.

Самый простой способ будет поддерживать два ListProperties:

from google.appengine.ext import db 

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

Спасибо, Ворон. Что такое имена полей? Должен ли я иметь 3-й список? –

+0

@LA_ Если ваш список имен полей статичен, вы, вероятно, захотите сохранить имя индекса <-> и даже не хранить его в классе User. Просто инициализируйте всех в массивы одинакового размера с хорошими значениями по умолчанию (нули?). Но если вы хотите делать какие-либо запросы на основе определенных именных баллов, вам может потребоваться явно указать каждое поле, а не хранить значения/баллы в списках. Я уверен, что это можно сделать динамически - не нужно вводить 200 свойств (и, возможно, модель Expando будет полезна, если список полей не является статическим). – Raven

1

Это зависит от ваших шаблонов доступа. Знание более подробной информации и требований позволит лучше ответить.

Если у вас когда-либо будет более 5000 записей, которые вы не можете разделить отдельно, вы должны использовать простую структуру, как показано ниже. Чтобы получить сумму баллов, вы можете запросить все и добавить их в память. Если у вас есть большое количество баллов, вы можете либо использовать MapReduce, чтобы найти сумму по запросу, либо shard counter, чтобы сохранить общую сумму.

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

Вы можете использовать ListProperty, если вы не будете иметь более чем 5000 записей. Это приведет к значительно меньшему количеству чтения и записи хранилища данных, поскольку только один запрос возвращает все результаты, которые вы затем можете суммировать в памяти. Если у вас есть третья часть данных (например, поле игрока ниже), вы можете использовать, чтобы гарантировать, что у вас менее 5000 записей, это может быть достойным решением.

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

Общее количество записей в хранилище данных будет больше 5000. Но количество полей ('N' выше) будет около 100. –

Смежные вопросы