Статьи

Query of Queries

Помимо CFC , одним из моих любимых аспектов ColdFusion является Query of Queries, который был представлен в ColdFusion 5.x.

Что такое запрос запросов? Согласно документам Macromedia Live ,

запрос, который извлекает данные из набора записей, называется Query of Queries. После создания набора записей вы можете взаимодействовать с его результатами, как если бы они были таблицами базы данных, используя Query of Queries.

Для меня Query of Queries — это возможность повторно запросить существующий набор записей. Например, предположим, у вас есть интерфейс, который показывает вам всех пользователей в системе. Вероятно, вы использовали запрос, подобный для select * from users order by lastName а затем каким-то образом select * from users order by lastName их в свой HTML. Теперь предположим, что вы перечислили алфавит в верхней части этого вывода, чтобы пользователь мог, например, щелкнуть «J», чтобы увидеть всех, чья фамилия начинается с «J». Вам нужно будет повторно запросить базу данных и использовать что-то вроде select * from users where lastName like 'j%' order by lastName .

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

Снижение нагрузки — запрос запросов в действии

Теперь давайте снова посмотрим на этот вопрос. На этот раз, однако, мы будем использовать ColdFusion и возможность Query of Queries, чтобы облегчить загрузку и расширить функциональность нашего скрипта. Давайте предположим, что наш клиент запросил функцию отчетности, которая покажет ему следующее:

  • Общее количество зарегистрированных пользователей
  • Общее количество пользователей мужского пола
  • Общее количество женщин-пользователей
  • Общее число пользователей мужского пола в возрасте 18 лет или старше
  • Общее число женщин-пользователей в возрасте 18 лет или старше

Предположим, что наша таблица содержит следующие столбцы:

  • fname
  • lname
  • gender
  • age
  • email

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

Требование 1: Всего зарегистрированных пользователей

Учитывая наши требования, первое, что хочет клиент, — это общее количество зарегистрированных пользователей. Наш SQL будет выглядеть так:

 <cfquery name="allUsers" datasource="#APPLICATION.dbSource#">  select fname, lname, gender, age, email from users  </cfquery> 

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

Теперь вышеприведенный запрос соберет всех пользователей в базе данных и вернет набор записей с именем allUsers . Вы заметите, что я не делал Select COUNT(*) as count from users запроса Select COUNT(*) as count from users , но вместо этого решил выбрать все столбцы и поместить эти данные в набор записей. Я выбрал этот маршрут, потому что он позволяет нам расширять код, если в будущем клиенту нужны подробные списки или отчеты. Если бы мы просто запустили запрос на подсчет, нам бы пришлось внести серьезные изменения в будущие отчеты, поскольку фактические данные пользователя отсутствовали.

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

Всего пользователей в системе: <cfoutput>#allUsers.RecordCount#</cfoutput><br />

При размещении на HTML-странице ColdFusion (.cfml или .cfm) приведенный выше код сгенерирует текстовую строку, показывающую нашему клиенту общее количество пользователей, которые в настоящее время находятся в системе. Это будет отображаться в виде числового значения, которое автоматически рассчитывается и генерируется сервером ColdFusion в качестве переменной RecordCount .

Требование 2. Общее количество пользователей мужского и общего числа женщин в системе.

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

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

 <!--- grab all users --->  <cfquery name="allUsers" datasource="#APPLICATION.dbSource#">  select fname, lname, gender, age, email from users  </cfquery>   <!--- grab all the men --->  <cfquery name="allMales" dbtype="query">  select * from allUsers where gender = 'male'  </cfquery>   <!--- grab all the women --->  <cfquery name="allFemales" dbtype="query">  select * from allUsers where gender = 'female'  </cfquery> 

Приведенный выше код является нашими первыми двумя запросами запросов. Чтобы выполнить Query of Queries, у вас должен быть действительный набор записей для запроса. Для этого приложения допустимым набором записей является allUsers запросов / записей allUsers .

Теперь мы обновляем вывод новым кодом, снова выделенным жирным шрифтом.

 Total users in system: <cfoutput>#allUsers.RecordCount#</cfoutput><br />  Total male users in system: <cfoutput>#allMales.RecordCount#</cfoutput><br />  Total female users in system: <cfoutput>#allFemales.RecordCount#</cfoutput><br /> 

Нам необходимо дополнительно запросить allMales записей allMales и allFemales чтобы мы могли сообщать об общем количестве пользователей старше 18 лет.

Требование 3: Общее количество пользователей каждого пола старше 18 лет.

Мы изменили наши части кода SQL, чтобы они выглядели следующим образом (новый код выделен жирным шрифтом):

 <!--- grab all users --->  <cfquery name="allUsers" datasource="#APPLICATION.dbSource#">  select fname, lname, gender, age, email from users  </cfquery>   <!--- grab all the men --->  <cfquery name="allMales" dbtype="query">  select * from allUsers where gender = 'male'  </cfquery>   <!--- grab all the men at or over age of 18 --->  <cfquery name="allMales18" dbtype="query">  select * from allMales where age >= 18  </cfquery>   <!--- grab all the women --->  <cfquery name="allFemales" dbtype="query">  select * from allUsers where gender = 'female'  </cfquery>   <!--- grab all the women at over age of 18 --->  <cfquery name="allFemales18" dbtype="query">  select * from allFemales where age >= 18  </cfquery> 

Теперь обновите ваш выходной код следующим образом:

 Total users in system: <cfoutput>#allUsers.RecordCount#</cfoutput><br />  Total male users in system: <cfoutput>#allMales.RecordCount#</cfoutput><br />  Total male users in system at or over age 18: /<cfoutput>#allMales18.RecordCount#</cfoutput><br />  Total female users in system: <cfoutput>#allFemales.RecordCount#</cfoutput><br />  Total female users in system at or over age 18: <cfoutput>#allFemales18.RecordCount#</cfoutput><br /> 

Давайте потратим несколько минут, чтобы глубже погрузиться в этот код. Первое, что вы заметили, было то, что в наших запросах запросов не указывался источник данных, а вместо этого указывался запрос типа базы данных ( dbtype="query" ). Это говорит движку ColdFusion, что мы хотим повторно запросить существующий набор записей, создавая тем самым Query of Queries. Вы также заметите, что в нашем утверждении select мы не ссылались на пользователей таблицы. Вместо этого мы ссылались на наш исходный запрос, который, в случае с нашими первыми двумя запросами запросов, был allUsers . Обратите внимание, что мы не указываем пол в запросах 18 и более. Это условие было изначально оговорено в наших allMales и allFemales , поэтому его не нужно применять снова.

Легкая нагрузка

Вот оно — очень простое, но мощное введение в мир Query of Queries.

Я уверен, что вы хотите знать, как это облегчает вашу нагрузку. Что ж, увеличение производительности трудно измерить без базы данных, заполненной пользователями, с которыми вы можете проводить тесты. Но если вы остановитесь и сравните то, что сервер должен делать с нашим кодом Query of Queries, с обработкой, которую он завершил бы, если бы мы выполнили новый запрос к базе данных для каждой из этих статистических данных, повышение производительности неизбежно. Да, ColdFusion должен тратить больше времени и памяти на получение полного списка пользователей из базы данных в первом запросе, но, в свою очередь, он рассчитывает статистику на лету, просто манипулируя наборами записей в памяти, а не возвращаясь к база данных, которая всегда является дорогостоящим процессом.

Применение запроса к запросам

Когда вы должны использовать Query of Queries? По моему скромному мнению, Query of Queries следует использовать, когда вы можете ограничить количество подключений к серверу базы данных, не мешая при этом кодированию и дизайну вашего приложения. Я не рекомендую вам спешить и запускать 10 операторов select * from Table , используя Queries of Queries во всем приложении. Имейте в виду, что созданные вами результирующие наборы должны где-то храниться. Большую часть времени они хранятся в памяти (будь то ОЗУ или виртуальная), и, если вы не планируете должным образом, ваш сервер может замедлить сканирование или даже остановиться из-за нехватки ресурсов памяти.

Как и в любом проекте, лучше сначала спланировать всю систему, а затем вернуться и многократно ее улучшить, поскольку вы ищете способы повышения производительности, безопасности и общей стабильности. Именно на этом этапе уточнения вы можете определить возможные области, в которых Query of Queries будет полезен для приложений и системных ресурсов. Я надеюсь, что эта статья дала вам возможность просмотреть ваш код и посмотреть, как вы можете реализовать функциональность запроса запросов в своих проектах. Если вам нужна дополнительная помощь, напишите мне или оставьте сообщение на форуме SitePoint .