лучшая практика для графоподобных сущностей на appengine ndb

Я разрабатываю приложение g+ для крупного международного бренда. объекты, которые мне нужно создать, в значительной степени имеют форму графа, следовательно, множество отношений «многие ко многим» (дуги), соединяющих узлы, которые можно перемещать в обоих направлениях. Я читаю все читаемые документы в Интернете, но пока не нашел ничего конкретного о передовых методах и рекомендациях по дизайну ndb. к сожалению, я не в курсе и не могу раскрыть детали приложения, но оно может почти один к одному соответствовать контексту научных конференций с материалами, авторами, статьями и темами.

ниже списка объектов, предусмотренных на данный момент (с измененным контекстом, чтобы соответствовать упомянутым темам):

  • организация (например, ACM)
  • конференция (например, ACM Multimedia)
  • выпуск конференции (например, acm Multimedia 13)
  • конференц-трек (например, nosql, машинное обучение, компьютерное зрение и т. д.)
  • автор (например, я)
  • бумага (например, «проектирование графика, подобного db для ndb»)

как видите, я могу посещать и перемещаться по графику в любом направлении (или аспекте, с точки зрения внешнего интерфейса):

  • автор с соавторами
  • автор треков конференции
  • конференция отслеживает документы
  • ...

и так далее, вы заполняете список.

Я хочу сделать его прямым и цельным, потому что он будет запущен с большим количеством пиара. и необходимо будет последовательно масштабировать сверхурочно, как по содержанию, так и по количеству пользователей. Я хотел бы закодировать его с нуля, поэтому разрабатываю свои собственные модели, успокаивающий API для чтения/записи этих данных, избегая нерелевантного django и сохраняя уровень представления с минимальным механизмом шаблонов. Мне нужно связаться с компанией, в которой я работаю, но мы могли бы выпустить часть кода с приличной лицензией с открытым исходным кодом (в идеале, безотказный сервис для моделей ndb).

если бы кто-нибудь мог указать мне правильное направление, это было бы здорово.

Благодарность! Томас

[править: исправлена ​​опечатка, связанная с отношениями «многие ко многим»]


person gru    schedule 02.08.2013    source источник


Ответы (2)


Существует два способа реализации отношений "один ко многим" в App Engine.

  1. Внутри объекта A сохраните список ключей к объектам B1, B2, B3. В старой БД вы должны использовать ListProperty db.Key. В ndb вы должны использовать KeyProperty с повторением = True.

  2. Внутри сущности B1, B2, B3 сохраните KeyProperty для сущности A.

Если вы используете 1:

  • Когда у вас есть Entity A, вы можете получить B1, B2, B3 по идентификатору. Это может быть потенциально более согласованным, чем результаты запроса.
  • Это может быть немного дешевле, поскольку вы экономите 1 операцию чтения по запросу (при условии, что вы не считаете стоимость выборки объекта A). Запись экземпляров B немного дешевле, так как для обновления на один индекс меньше.
  • Вы ограничены в количестве экземпляров B, которые вы можете хранить, максимальным размером объекта и количеством проиндексированных свойств в A. Это имеет смысл для таких вещей, как треки конференции, поскольку обычно существует ограниченное количество треков, которое не исчисляется тысячами. .
  • Если вам нужно произвольно отсортировать порядок B1, B2, B3, проще хранить их по порядку в списке, чем сортировать их с помощью какого-либо отсортированного индексированного свойства.

Если вы используете 2:

  • Вам нужен только ключ объекта A, чтобы запросить B1, B2, B3. На самом деле вам не нужно извлекать объект A, чтобы получить список.
  • Вы можете иметь практически неограниченное количество объектов B.
person dragonx    schedule 03.08.2013
comment
эй, dragonx, спасибо, что нашли время ответить, но я не уверен, что это решит мою проблему. Я полагаю, что под referenceProperty вы имеете в виду ключевое свойство с видом = один из других объектов, верно? Я читал, что это может легко достичь предела в 1 МБ при извлечении объектов с большим количеством соединений, это может быть мой случай. Я бы, вероятно, использовал повторяющиеся свойства для простых связанных сущностей, но я думаю, что вся структура данных, возможно, должна полагаться на более нормализованное представление, отсюда и мое искушение хранить дуги как сущности. имеет смысл? - person gru; 05.08.2013
comment
Вы правы, KeyProperty. Как я уже упоминал, если вы используете метод 1, вы столкнетесь с ограничением в 1 МБ, но не при использовании метода 2. Я не знаю, что вы подразумеваете под нормализованным представлением. Также не совсем понимаю, что вы подразумеваете под хранением дуг как сущностей. Если вы имеете в виду, что хотите создать объект для каждой связи между двумя узлами в вашем графе, это определенно неправильный способ сделать это. Это будет дорого и медленно извлекать объекты. В App Engine обычно требуется денормализация, если это возможно, чтобы уменьшить количество извлекаемых сущностей и, следовательно, снизить затраты и повысить производительность. - person dragonx; 06.08.2013
comment
хм, я понимаю, что вы имеете в виду, но я вижу метод 2 просто как зеркальную версию метода 1 (в моем случае все сущности A, B, C, ... могут иметь связи многие-ко-многим со всеми остальными) поэтому я снова столкнулся с ограничением в 1 МБ. есть официальное демонстрационное приложение googleplus, которое использует метод, который я упоминаю, для хранения соединений между объектами, вы можете увидеть это, щелкнув здесь. они не должны быть полностью неправильными, не так ли? - person gru; 07.08.2013
comment
Ваш вопрос задавался об отношениях «один ко многим», а не «многие ко многим». Если вам нужно очень большое количество отношений «многие ко многим», то да, это путь. Я использую это в некоторых частях своего приложения, но я обнаружил, что гораздо дешевле использовать список ключей, если вы можете, и использовать метод промежуточного объекта только тогда, когда вам нужен неограниченный рост, потому что это стоит НАМНОГО дороже. , так как вам нужно запрашивать ссылки, а затем извлекать фактические объекты. Вы можете немного сократить это, если денормализуете и сохраните некоторые данные в объекте ссылки. - person dragonx; 07.08.2013
comment
да, я так и думал. Я пытаюсь разделить объекты на те, которые действительно требуют большого роста (например, документы/темы в моем примере), и те, которые были бы достаточно небольшими (например, конференции/выпуски). и спасибо, что заметили опечатку, я отредактирую исходный пост, чтобы отразить реальную структуру «многие ко многим». - person gru; 08.08.2013

после тщательных исследований вот что обнаружилось:

  • нет единого шаблона проектирования, которому нужно следовать, это, конечно, зависит от конкретного приложения и моделирования данных (достаточно справедливо)
  • следует предпринять действия, чтобы избежать превышения ограничений по размеру, указанных в нижнем этой страницы, в основном для размера одного объекта (1 МБ), размера транзакции (10 МБ) и лимиты индекса
  • избегайте, где это возможно, нормализации сущностей (например, сущностей, используемых только для создания набора дуг), хотя кажется, что разработчики googleplus используют их в своем демонстрационном приложении для простой социальный граф

любой другой более подробный ответ приветствуется

person gru    schedule 08.08.2013