Когда лучше перенести работу в СУБД, чем делать это в коде?

12

Хорошо, я справлюсь с этим: я лучше программист, чем в базах данных, и мне интересно, где размышления о «лучших практиках» лежат на предмет выполнения «простых» вычислений в запросе SQL по сравнению с код, такой как этот пример MySQL (я не писал его, я просто должен его поддерживать!) - возвращает имя пользователя и возраст пользователя на момент последнего события.

SELECT u.username as user, 
       IF ((DAY(max(e.date)) - DAY(u.DOB)) < 0 ,   
       TRUNCATE(((((YEAR(max(e.date))*12)+MONTH(max(e.date)))
       -((YEAR(u.DOB)*12)+MONTH(u.DOB)))-1)/12, 0),  
       TRUNCATE((((YEAR(max(e.date))*12)+MONTH(max(e.date))) -            
       ((YEAR(u.DOB)*12)+MONTH(u.DOB)))/12, 0)) AS age   
FROM users as u
JOIN events as e ON u.id = e.uid
...

По сравнению с «тяжелым» поднятием кода:

Запрос:

SELECT u.username, u.DOB as dob, e.event_date as edate
FROM users as u
JOIN events as e ON u.id = e.uid

код:

function ageAsOfDate($birth, $aod)
{    //expects dates in mysql Y-m-d format...
     list($by,$bm,$bd) = explode('-',$birth);
     list($ay,$am,$ad) = explode('-',$aod);

     //Insert Calculations here 
     ...
     return $Dy; //Difference in years
}

echo "Hey! ". $row['user'] ." was ". ageAsOfDate($row['dob'], $row['edate']) . " when we last saw him."; 

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

Благодарность!

GeminiDomino
источник
1
Это хороший вопрос - я сталкивался с той же проблемой.
Майкл К
Вот хороший пример того, когда этого не делать: calendar.sql (Да, это мое чудовище, да, это была плохая идея, и нет, это не медленно.)
Greyfade
Вы, бродячие боги ... Могу поспорить, что MD5 для этой вещи получится "CthulhuFhtagn"
GeminiDomino

Ответы:

13

Вы хотите выполнять все операции на основе множеств в базе данных по соображениям производительности. Так что функции агрегирования, сортировки, объединения и т. Д.

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

Джереми
источник
Я согласен. Код, который работает со значениями для отображения, должен быть в коде вашего приложения.
TehShrike
4

Каждый случай отличается

Это логика ...

  • нужен другим клиентам? СУХОЙ: в базе данных
  • используется для дальнейшей обработки? например, сортировка по возрастанию по убыванию: в базе данных
  • требуются региональные настройки? дд / мм / гггг или мм / дд / гггг: в клиенте
  • часто используется? Зачем вычислять это снова и снова: используйте вычисляемый и сохраненный столбец в базе данных

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

Могло быть и хуже: вы могли бы иметь это в базе данных:

"Hey! ". u.username." was ". <datecalc>. " when we last saw him."
ГБН
источник
3

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

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


источник
1

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

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

Существуют и другие приложения, которые могут нуждаться в логике вне вашего кода. Некоторые инструменты написания отчетов могут не использовать веб-сервис или API. Вы можете продублировать логику или почувствовать, что требования могут отличаться.

JeffO
источник
«У оборудования базы данных значительно больше ресурсов, чем у других серверов, и вы не можете это изменить». - а? Откуда взялись эти два заявления?
Питер Боутон
Я думаю, что Джефф может говорить об автономных серверах баз данных. Я, вероятно, должен был указать, что я работаю в основном над установками LA [MP] P.
Близнецы Домино
1
Настройка LAMP не является причиной отсутствия автономного сервера баз данных, и при этом автономный сервер баз данных не является гарантией большего количества ресурсов или неспособности изменить это.
Питер Боутон
Хмм. Не уверен тогда.
Близнецы Домино
@Peter Boughton, DB и приложение на одном и том же сервере имеют на порядок меньше времени для подключения интерфейса и величины IO во всем мире, есть реальные причины, чтобы найти эти два вместе.
Jé Queue
0

Я всегда ошибаюсь, помещая как можно больше обработки в БД. Ваш синтаксис выше также может быть написан с функциями БД, которые будут IMO очень чистое решение.

Jé Queue
источник