Денормализация

Отступление 10.5

На данный момент переведено

В этой главе вы:

  • Узнаете, что такое денормализация.
  • Сравните Mongo с традиционными реляционными базами данных.
  • Узнаете, когда данные *не стоит* денормализовать.
  • Денормализация данных означает что данные не сохраняются в “обычном” формате. Другими словами, денормализация означает множество копий одних и тех же данных, но в разных местах.

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

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

    С другой стороны, у реляционного подхода есть и свои минусы. Без параметра commentsCount нам пришлось бы запросить все комментарии с сервера каждый раз, когда нам потребовалось бы посчитать их количество - то же самое, что творилось у нас с самого начала. Денормализование данных помогает полностью избежать этого.

    Особенная Публикация

    На самом деле возможно создать особенную публикацию, которая будет отсылать только значение с количеством комментариев - именно то, в чем мы заинтересованы.

    С другой стороны, всегда стоит взвешивать сложность создания подобной публикации против сложностей подхода с денормализацией данных.

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

    Внедряемые Документы или использование множества Коллекций

    Если вы уже работали с Mongo, вероятно, вы удивились, когда мы создали отдельную коллекцию для комментариев. Вместо этого мы вполне могли бы внедрить лист комментариев прямо в документ с постом.

    Оказывается, большинство встроенных инструментов Meteor работают гораздо лучше, если они оперируют на уровне коллекции. Например:

    1. Функция-помощник {{each}} гораздо эффективнее, когда она работает с курсором (результатом запроса функции collection.find()). Та же функция гораздо менее эффективна, когда нужно просматривать массив объектов, внедренных в большой документ.
    2. allow и deny работают на уровне документа. По этой причине фильтрование комментариев легко воплотить, когда они находятся в отдельной коллекции - и гораздо сложнее, если они внедрены в другую коллекцию.
    3. DDP работает на уровне атрибутов первого уровня у документов. Это означает, если у comments есть свойство post, то каждый раз, когда новый комментарий добавлен к посту, сервер будет посылать обновленный лист со всеми комментариями на все подключенные клиенты.
    4. Контролировать публикации и подписки гораздо проще на уровне документов. Например, если бы мы хотели разбить длинный список комментариев на несколько страниц, это оказалось бы сложнее, если бы комментарии не были сохранены в своей отдельной коллекции.

    Mongo предлагает внедрять документы, чтобы уменьшить количество запросов к базе данных. С другой стороны, если мы вспомним про архитектуру Meteor - большая часть запросов происходит на клиенте, где запросы к MiniMongo происходят мгновенно.

    Обратная сторона Денормализации

    Есть хороший аргумент, согласно которому вам не стоит денормализовать данные. Мы рекомендуем прочитать следующий блогпост Почему вам никогда не стоит использовать MongoDB от Sarah Mei.