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

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

Контекст:

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

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

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

Его мнение:

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

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


@боб-The-разрушитель @tekretic @OMG Ponies @mu слишком короткое @Tudor Constantin @tandu @Harley

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

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

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

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

Ответ 1

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

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

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

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

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

  • Обработка строк просто всасывает SQL, лучше это работает в PHP. Если вам не нужны большие манипуляции с строками, вы можете сделать это в Mysql SELECT.

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

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

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

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

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