Помимо 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 .