Делать вычисления в MySQL против PHP

Контекст:

  • У нас есть приложение PHP/MySQL.
  • Некоторые части вычислений выполняются непосредственно в SQL. Например: все пользователи, созданные за последние 24 часа, будут возвращены с помощью SQL-запроса ( NOW() - 1 день)

Между мной и моим коллегой-разработчиком идет спор, где я придерживаюсь мнения, что мы должны:

A. Сохраняйте все вычисления / код / ​​логику в PHP и рассматривайте MySQL как "тупое" хранилище информации

Его мнение:

Б. Делайте микс и подбирайте в зависимости от того, что легче / быстрее. http://www.onextrapixel.com/2010/06/23/mysql-has-functions-part-5-php-vs-mysql-performance/

Я смотрю на точку зрения ремонтопригодности. Он смотрит на скорость (которая, как указано в статье, некоторые операции выполняются быстрее в MySQL).


@ bob-the-разрушитель @tekretic @OMG Пони @mu слишком короткий @Tudor Constantin @tandu @Harley

Я согласен (и вполне очевидно), что эффективные предложения WHERE относятся к уровню SQL. Тем не менее, как насчет примеров, таких как:

  1. Вычисление 24 периода с использованием NOW () - 1 день в SQL для выбора всех пользователей, созданных за последние 24 часа?
  2. Вернуть заглавные имя и фамилию всем пользователям?
  3. Конкатенация строки?
  4. (мысли, ребята?)

Ясные примеры, принадлежащие домену SQL:

  1. конкретные ГДЕ выбор
  2. Вложенные операторы SQL
  3. Заказ / Сортировка
  4. Выбор DISTINCT пунктов
  5. Подсчет строк / предметов

5 ответов

Решение

Я бы играл на сильные стороны каждой системы.

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

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

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

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


Re: конкретные примеры...

  1. Я знаю, что это не то, что вы имеете в виду, но даты - это почти особый случай. Вы хотите убедиться, что все даты, сгенерированные системой, созданы либо на веб-сервере, либо в базе данных. В противном случае возникнут некоторые коварные ошибки, если сервер БД и веб-сервер когда-либо будут настроены для разных часовых поясов (я видел, как это происходило). Представьте себе, например, у вас есть createdDate столбец со значением по умолчанию getDate() который применяется на вставке БД. Если вы должны были вставить запись тогда, используя дату, сгенерированную в PHP (например, date("Y-m-d", time() - 3600) выберите записи, созданные за последний час, вы можете не получить то, что ожидаете. Что касается того слоя, на котором вы должны сделать это, я бы предпочел DB, поскольку, как в примере, он позволяет использовать значения по умолчанию для столбцов.

  2. Для большинства приложений я бы сделал это на PHP. Сочетание имени и фамилии звучит просто, пока вы не поймете, что иногда вам нужны приветствия, названия и средние инициалы. Кроме того, вы почти наверняка окажетесь в ситуации, когда вам понадобятся имя, фамилия И имя пользователя + объединенное приветствие + имя + фамилия. Объединение их на стороне DB означает, что вы в конечном итоге перемещаете больше данных, хотя на самом деле это довольно незначительно.

  3. Зависит. Как и выше, если вы когда-нибудь захотите использовать их по отдельности, вам лучше по отдельности извлекать их и объединять при необходимости. Тем не менее, если наборы данных, с которыми вы имеете дело, невелики, вероятно, есть другие факторы (например, как вы упоминаете, ремонтопригодность), которые имеют большее значение.

Несколько правил:

  • Генерация инкрементных идентификаторов должна происходить в БД.
  • Лично мне нравится мой по умолчанию применяется БД.
  • При выборе все, что уменьшает количество записей, должно быть сделано БД.
  • Обычно хорошо делать вещи, которые уменьшают размер DB-стороны набора данных (как в примере с строками выше).
  • И, как вы говорите; упорядочение, агрегация, подзапросы, объединения и т. д. всегда должны быть на стороне БД.
  • Кроме того, мы не говорили о них, но триггеры обычно плохи / необходимы.

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

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

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

Кроме того, если другие системы обращаются к БД напрямую (например, для создания отчетов или импорта / экспорта), вы получите больше логики в БД. Например, если вы хотите импортировать пользователей из другого источника данных напрямую, в SQL реализовано что-то вроде функции проверки электронной почты, которая будет использоваться повторно.

Краткий ответ: это зависит.:)

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

  • Когда я могу получить набор результатов прямо из БД без дальнейшей обработки, я делаю это - в вашем случае это простой запрос с простым WHERE пункт. Представьте себе, что происходит, когда у вас есть 10 миллионов пользователей и вы получаете их в PHP, просто нужно 100 из них - как вы уже догадались - вполне возможно, что ваш веб-сервер аварийно завершится
  • Когда вам нужно получить данные из 2 или более таблиц одновременно, опять же, MySQL намного лучше, чем PHP
  • Когда нужно посчитать записи - БД в этом хороша
  • Я склонен отдавать предпочтение обработке на уровне приложений ограничениям FK
  • Кроме того, я стараюсь избегать хранимых процедур, предпочитая реализовывать эту бизнес-логику на уровне приложений (если, конечно, речь не идет об огромных наборах данных).

В заключение скажу, что ваш коллега прав в представленном случае.

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

Тем не менее, ваши запросы к базе данных должны иметь достаточную логику, чтобы они предоставляли вашему php именно те данные, которые ему нужны. Если вы обнаруживаете, что просматриваете тысячи записей mysql в своем php-коде, значит, вы делаете что-то не так. На другом конце шкалы, хотя, если вы выполняете операторы if / else в ваших запросах mysql, вы также делаете что-то не так (вероятно, просто нужно переписать ваш запрос).

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

MySQL будет масштабироваться лучше по мере увеличения набора результатов. Честно говоря, обработка базы данных как хранилища "глупых данных" - пустая трата ресурсов...

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

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

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

Некоторые основные моменты:

  1. Форматирование даты в MYSQL является сильным, большинство форматов доступны в Mysql. Если у вас очень специфический формат даты, вы можете сделать это PHP.

  2. Манипулирование строками просто отстой в SQL, лучше сделайте это в PHP. Если у вас нет больших манипуляций со строками, то вы можете сделать это в Mysql SELECTs.

  3. При выборе все, что уменьшает количество записей, должно быть сделано SQL, а не PHP

  4. Данные заказа всегда должны быть сделаны в Mysql

  5. Агрегация всегда должна выполняться в Mysql, потому что механизмы DB специально разработаны для этого.

  6. Подзапросы и объединения всегда должны быть на стороне DB. Это сократит количество вашего PHP-кода. Когда вам нужно получить данные из 2 или более таблиц одновременно, опять же, SQL намного лучше, чем PHP

  7. Хочешь посчитать записи, SQL отлично.

Ответы на каждый следующий:

  1. Вычисление периода 24 с помощью NOW() - 1 день в SQL для выбора всех пользователей, созданных за последние 24 часа?

  2. Используйте PHP для создания даты и предложения WHERE для поиска данных. Манипуляции с датой намного быстрее реализовать в PHP.

  3. Вернуть имя и фамилию всех пользователей с заглавной буквы?

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

  5. Объединение строки?

  6. Опять же, PHP для обработки строк.

(мысли, ребята?)

Используйте PHP для всех манипуляций с данными, так как это проще реализовать. Чтобы быть понятнее, манипулируя простым$variableв PHP проще, чем записывать целые операции со строкой в ​​SQL. Манипулируйте в PHP, а затем обновляйте базу данных в SQL.

Наглядные примеры, относящиеся к домену SQL:

конкретные варианты выбора WHERE - да.

Вложенные операторы SQL - я бы пересмотрел вашу обработку данных PHP, но если вам нужно, хорошо.

Упорядочивание / сортировка -Ordering - это, безусловно, задача оператора SQL, но вы должны выполнять сортировку только в операторе SELECT. Любой другой порядок, такой как упорядочивание и ОБНОВЛЕНИЕ базы данных, должен быть заказан PHP, потому что, опять же, легче манипулировать $vars, чем записывать операторы UPDATE SQL.

Выбор DISTINCT пунктов - да.

Подсчет строк / предметов - использование: $Number_Of_Results = count($Results); в PHP.

Другие вопросы по тегам