Выполнение вычислений в MySQL и PHP

Контекст:

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

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

A. Держите все вычисления / код / ​​логику в PHP и рассматривайте MySQL как «немой» репозиторий информации

Его мнение:

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

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


@ bob-the-destroyer @tekretic @OMG Пони @mu слишком короткий @Tudor Constantin @tandu @Harley

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

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

Очистить примеры, принадлежащие домену SQL:

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

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

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

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

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

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


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

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

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

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

Несколько эмпирических правил:

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

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

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

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

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

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

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

  • Когда я могу получить набор результатов прямо из БД без дальнейшей обработки, я делаю это – ваш случай – это простой запрос с простым WHERE . Представьте себе, что происходит, когда у вас 10 миллионов пользователей, и вы получаете их на PHP, просто нужно 100 из них – вы догадались, это очень возможно для вашего веб-сервера
  • Когда вам нужно получить данные из двух или более таблиц сразу, опять же, 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 SELECT.

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

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

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

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

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