Ответ 1
Хорошо, это компромисс с хранилищами документов. Вы можете хранить в нормализованном порядке, как и любые стандартные RDMS, и вы должны стремиться к нормализации как можно больше. Это только там, где его производительность поразила, что вы должны нарушить нормализацию и сгладить ваши структуры данных. Компромисс - эффективность чтения и стоимость обновления.
У Mongo действительно эффективные индексы, которые упрощают нормализацию, как традиционная RDMS (большинство хранилищ документов не дают вам этого бесплатно, поэтому Mongo скорее гибрид, чем чистый хранилище документов). Используя это, вы можете создать коллекцию отношений между пользователями и событиями. Он аналогичен суррогатной таблице в табличном хранилище данных. Индекс полей событий и пользователей должен быть довольно быстрым и поможет вам нормализовать ваши данные.
Мне нравится строить эффективность выравнивания структуры и поддержания ее нормализации, когда дело доходит до времени, которое требуется мне для обновления данных записей, а также для чтения того, что мне нужно в запросе. Вы можете сделать это с точки зрения большой нотации O, но вам не обязательно быть такой фантазией. Просто поместите некоторые цифры на бумаге, основанные на нескольких вариантах использования с различными моделями для данных, и получите хорошее представление о том, сколько требуется работы.
В основном, я пытаюсь предсказать вероятность того, сколько обновлений будет иметь запись, и как часто это делается. Затем я пытаюсь предсказать, какая стоимость обновления соответствует чтению, когда он нормализуется или сглаживается (или, может быть, частично сочетается с двумя, которые я могу представить... множество опций оптимизации). Затем я могу судить о том, как сохранить его в сравнении с затратами на сбор данных из нормализованных источников. После того, как я построил все переменные, если сбережения от его сохранения сэкономит мне кучу, тогда я сохраню ее.
Несколько советов:
- Если вам требуется быстрый поиск, чтобы быть быстрым и атомарным (совершенно современно), вам может понадобиться услуга, в которой вы предпочитаете выравнивание по нормализации и попадание в обновление.
- Если вам требуется, чтобы обновление было быстрым, а доступ сразу же стал нормализацией.
- Если вам требуются быстрые поисковые запросы, но они не требуют совершенно свежих данных, подумайте о том, чтобы построить нормализованные данные в пакетных заданиях (возможно, используя карту/уменьшить).
- Если ваши запросы должны быть быстрыми, а обновления редки и не обязательно требуют немедленного доступа к вашему обновлению или требуют блокировки уровня транзакции, которая прошла через 100% времени (чтобы гарантировать, что ваше обновление было записано на диск), вы можете рассмотреть возможность записи своих обновлений в очередь, обрабатывая их в фоновом режиме. (В этой модели вам, вероятно, придется столкнуться с разрешением конфликтов и согласованием позже).
- Профиль разных моделей. Создайте в своем коде слой абстракции запроса данных (например, ORM), чтобы позднее можно было реорганизовать структуру хранилища данных.
Есть много других идей, которые вы можете использовать. Там много замечательных блогов на линии, которые входят в него, как highscalabilty.org, и убедитесь, что вы понимаете теорему CAP.
Также рассмотрите слой кэширования, например Redis или memcache. Я поставлю один из этих продуктов перед своим слоем данных. Когда я запрашиваю mongo (который сохраняет все нормализованное), я использую данные для построения сплющенного представления и сохранения его в кеше. Когда я обновляю данные, я аннулирую любые данные в кеше, которые ссылаются на то, что я обновляю. (Хотя вам необходимо потратить время, чтобы аннулировать данные и данные отслеживания в кэше, который обновляется с учетом ваших коэффициентов масштабирования). Кто-то однажды сказал: "Две самые трудные вещи в" Компьютерной науке "называют и недействительными кэш-памяти".
Надеюсь, что это поможет!