Подтвердить что ты не робот

MySQL - вычисление полей "на лету" и хранение вычисленных данных

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

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

Пример 1. Скажите, что вы храните данные, относящиеся к автомобилю. Вы храните размер топливного бака в литрах и сколько литров оно использует на 100 км. Вы также хотите знать, сколько KM он может путешествовать, что можно рассчитать по размеру резервуара и экономии. Я вижу два способа сделать это:

  • Когда автомобиль добавлен или обновлен, вычислите количество KM и сохраните его как статическое поле в базе данных.
  • Каждый раз, когда автомобиль получает доступ, рассчитывайте количество KM на лету.

Поскольку размер экономичности/емкости автомобиля не изменяется (хотя он может быть отредактирован), KM - довольно статическое значение. Я не понимаю, почему мы будем вычислять его каждый раз, когда автомобиль будет доступен. Не будет ли это время отработанного процессора, а не просто хранить его в отдельном поле в базе данных и рассчитывать только при добавлении или обновлении автомобиля?

Мой следующий пример, который представляет собой совершенно другой вопрос (но по той же теме), относится к подсчету детей.

Скажем, у нас есть приложение, которое имеет категории и элементы. У нас есть представление, где отображаются все категории и количество всех элементов внутри каждой категории. Опять же, мне интересно, что лучше. Выполнять запрос MySQL для подсчета всех элементов в каждой категории каждый раз, когда к странице обращаются? Или сохранить счет в поле в таблице категорий и обновить, когда элемент добавлен/удален?

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

Я был бы признателен за любые ответы на оба этих сценария и на любой ресурс, который мог бы объяснить преимущества вычисления и хранения.

Спасибо заранее,

Christian

4b9b3361

Ответ 1

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

В вашем первом примере нет причин, по которым кто-то когда-нибудь должен будет изменить способ вычисления ваших KM. Я бы сохранил его в базе данных (через триггеры или через PHP на вставке/обновлении), потому что триггеры MySQl... ну, они... не так хороши, как некоторые другие триггеры БД).

Теперь, если мы возьмем второй пример, он действительно не уверен, что кто-то не захочет, чтобы какой-то день добавлял некоторые фильтры для этих категорий вычислений. Например, возьмите только детей, которые находятся между 2 и 5. Тогда все ваши заранее рассчитанные результаты ничего не обслуживают. Если вам нужны некоторые оптимизации и кеши тезисов, возможно, вам понадобится кеш уровня приложения, например, memcache или предварительно вычисленные результаты, хранящиеся в таблице кеша. Но этот кэш - это кэш приложений, который определенным образом связан с вашими параметрами приложения (запросы с разными фильтрами будут использовать другую запись в кеше).

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

Ответ 2

Введение избыточности в базу данных является действенным средством оптимизации. Как и при всех оптимизациях, не делайте этого, если вы не подтвердили, что это именно то место, где это узкое место.

Ответ 3

Другие затронули технические аспекты, поэтому позвольте мне дать вам еще одну точку зрения:

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

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

  • Сохраняйте переписывание логики агрегации всякий раз, когда вы меняете подробные таблицы
  • Проверьте больше (и часто, казалось бы, несвязанные части вашего приложения)
  • Записать дополнительную документацию
  • Упрощает обновления и исправления.

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

Ответ 4

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

Ответ 5

Почему следует избегать хранения вычисляемых полей в таблице:

  • Что если правила работы изменятся? Например, вы добавляете TVA
  • Ваша база данных будет очень трудно поддерживать. Потому что каждый раз, когда вы меняете его структуру, если она влияет на вычисляемое поле, вы должны пересчитать все