Суммируйте одну таблицу и обновляйте другую с результатом, или просто делайте `sum` на select? - PullRequest
1 голос
/ 31 марта 2020

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

При загрузке изображения я обновляю images таблица с размером изображения в КБ и другая информация.

Теперь я должен также отслеживать общий размер изображений каждого пользователя в таблице users? Или я должен просто делать select sum(size) from images where user = xxx каждый раз, когда я хочу проверить предел? Что может быть при каждой новой загрузке?

Каков наилучший подход с точки зрения отношений?

Ответы [ 2 ]

1 голос
/ 31 марта 2020

Хранение суммы в таблице users - это один из типов денормализации.

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

Но вы принимаете на себя риск того, что сохраненная в таблице users сумма не будет синхронизирована c с действительными SUM(size) связанных изображений.

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

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

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

По моему опыту, все оптимизации имеют свою цену.

1 голос
/ 31 марта 2020

Вы можете использовать любой из этих методов.

Однако, поскольку у вас есть бизнес-правило, связанное с суммой размеров, я мог бы предложить использовать триггеры для поддержания суммы на уровне пользователя. Хотя это имеет некоторые дополнительные издержки для insert с / update с / delete с, у него гораздо меньше накладных расходов при возврате информации о пользователе.

Это также имеет несколько других преимуществ:

  • Вы можете навязать бизнес-правила по размерам. Например, вы можете округлить размеры до ближайшего 1К, а затем сложить их. Вы не хотели бы, чтобы такие бизнес-логики c распространялись по нескольким запросам.
  • Вы можете реализовать проверочное ограничение непосредственно в таблице users (ну, вы можете сделать это в самых последних версиях MySQL).
  • Вы можете индексировать общий размер изображения, чтобы вы могли легко увидеть, кто находится ближе всего к их пределу.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...