Требуется совет по проектированию хранилища данных AppEngine - PullRequest
0 голосов
/ 29 сентября 2011

Я строю распределенную систему учета. С точки зрения структуры и требований к БД, вероятно, проще всего описать приложение как приложение в стиле Twitter, но с иерархической структурой БД из 14 таблиц. Компания, которая использует приложение, может иметь 1 и более пользователей, которые все делятся информацией о компании.

В настоящее время каждый объект представляет тип записи, т.е. клиенты, счета и т. Д. У всех сущностей есть родитель, который является пользователем приложения. (по причинам согласованности запросов HRD)

Каждый запрос к БД состоит из 14 запросов AppEngine. По одному на каждый стол. Запрос включает фильтрацию свойств.

Новое требование заключается в том, что для запроса пользователя могут потребоваться разные значения свойств на основе каждого из других пользователей. Это означает, что нам нужно (в 14 раз больше пользователей) запросов AppEngine. Это кажется слишком много.

Запросы Kindless Ancestor, которые могут фильтровать по свойствам, были бы действительно хороши, увы, нет, ничего не могу сделать:)

Мои варианты:

  1. Установить вид сущности для пользователя. Нет родителей. Это означает, что все типы записей являются смешанными. (Отфильтрованные поля существуют во всех типах записей). Это не красиво. Но вы считаете это?

  2. Иметь фиксированный вид объекта и выполнять запрос только по фильтру. Результат эквивалентен запросам Kindless Ancestor. Тем не менее, я боюсь, что это будет медленным при многопользовательском использовании.

Некоторые номера: Мы планируем создать 10 000 компаний, в среднем по 5 пользователей на компанию и от 1 до 5 миллионов записей на тип записи. (всего 14 x)

Спасибо за ваше терпение до сих пор ..:)

1 Ответ

1 голос
/ 29 сентября 2011

Честно говоря, мне было трудно следовать вашему описанию, так что это может быть не так. Просмотр вашего существующего кода может помочь. Но я понимаю, что вам нужна эффективная альтернатива собственно подобранным запросам добрых предков, так что давайте начнем с этого.

Подумайте о нормализации вашей модели данных, включив в нее мета-сущность только для запросов:

class User(db.Model):
  pass

class OwnedObject(db.Expando):
  object_key = db.StringProperty()

class Customer(db.Model):
  name = db.StringProperty()
  created_on = db.DateProperty()

class Invoice(db.Model):
  amount = db.IntegerProperty()
  created_on = db.DateProperty()

# on write
customer = Customer()
customer.name = name
customer.created_on = date.today()
customer.put()

user = User(key_name=users.get_current_user().user_id())

owned_object = OwnedObject(parent=user)
owned_object.object_key = customer.key()
owned_object.created_on = customer.created_on
owned_object.put()

# on read
query = OwnedObject.all()
query.ancestor(user)
query.filter('created_on =', date.today())

entities = db.get([x.object_key for x in query])

Так что здесь вы делаете больше работы над записью и меньше над чтением.

Каждый реальный объект связан с объектом OwnedObject, который происходит от соответствующего предка и указывает на ключ реального объекта. OwnedObject - это расширение, поэтому вы будете стремиться назначить любые свойства, по которым вы хотите запросить (в этом примере, made_on).

При чтении вы можете запросить любые свойства, которые вы скопировали в мета-сущность expando, и вы можете извлечь все объекты пользователя с фиксированными издержками на один запрос и получить один пакет.

Редактировать : Вы можете сделать нечто подобное без мета-сущности, используя PolyModel .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...