Во-первых, вы должны знать, компромиссы, которые вы собираетесь получить с MongoDB и любой другой базы данных NoSQL (но понимаю, что я фанат этого). Если вы пытаетесь нормализовать свои данные полностью, вы делаете большую ошибку. Даже в реляционных базах данных, чем больше ваше приложение получает, тем больше ваши данные становятся денормализованными (см. this post от Hot Potato). Я видел это снова и снова. Вы не должны сходить с ума и сделать огромный беспорядок, но не беспокойтесь о повторении информации в двух местах. Одним из основных моментов (по моему мнению) NoSQL является то, что ваша схема перемещается в ваш код, а не только в базу данных.
Теперь, чтобы ответить на ваш вопрос, я думаю, что ваша первоначальная стратегия - это то, что я буду делать. MongoDB может размещать индексы на элементах, которые являются массивами, поэтому это сделает вещи намного быстрее, если вы ищете, сколько у друзей друзей. Но на самом деле единственный способ убедиться в этом - запустить какую-то тестовую программу, которая генерирует базу данных, полную имен и отношений.
Вы можете записывать некоторые данные на Python или Perl или как угодно, и использовать файл имен для создания некоторых отношений. Проверьте Census website, у которого есть список фамилий. Скачать файл dist.all.last
и написать какую-то программу, как:
#! /usr/bin/env python
import random as rand
f = open('dist.all.last')
names = []
for line in f:
names.append(line.split()[0])
rels = {}
for name in names:
numOfFriends = rand.randint(0, 1000)
rels[name] = []
for i in range(numOfFriends):
newFriend = rand.choice(names)
if newFriend != name: #cannot be friends with yourself
rels[name].append(newFriend)
# take relationships (i.e. rels) and write them to MongoDB
Кроме того, как общее примечание, ваши имена полей, кажется, своего рода долго. Помните, что имена полей повторяются с каждым документом в этой коллекции, потому что вы не можете полагаться на одно поле, находящееся в любом другом документе. Чтобы сэкономить место, общая стратегия заключается в использовании более коротких имен полей, таких как «unam» вместо «username», но это небольшая вещь. См. Отличный совет в thesetwo сообщений.
EDIT:
На самом деле, в обдумывая проблему немного больше, я хотел бы сделать еще одно предложение: разбить типы подписки на различные поля, чтобы сделать индексы более эффективными.Например, вместо:
{
"username" : "alan",
"photo": "123.jpg",
"subscriptions" : [
{"username" : "john", "status" : "accepted"},
{"username" : "paul", "status" : "pending"}
]
}
Как было сказано выше, я хотел бы сделать это:
{
"username" : "alan",
"photo": "123.jpg",
"acc_subs" : [ "john" ],
"pnd_subs" : [ "paul" ]
}
Так что вы могли бы иметь индекс для каждого типа подписки, таким образом, делая запросы, как «Hoy много у людей есть Павел в ожидании? " и «Сколько людей подписывается на Пола?» супер быстрый в любом случае. Индексирование Монго по значениям массива действительно является эпической победой.
хороший пост, +1, но я не согласен с тем, чтобы сделать имена короткими. Сделайте их настолько необходимыми, чтобы не нужно было ничего объяснять другому разработчику. Затем профиль/оптимизируйте по мере необходимости. Если имена являются проблемой значительного размера при масштабировании, то рефакторинг. – Lee