6 запросов для MySQL


Содержание

PHP и MySQL

Запросы MySQL с примерами: часть 2.

Введение

В первой части, основы MySQL и PHP, мы научились подключаться серверу MySQL, выбирать базу данных для работы, узнали PHP-функцию отправки запросов серверу MySQL, узнали два простейших запроса (создание и удаление таблицы), ну и узнали как закрывать соединение.

Теперь мы будем более глубоко изучать запросы MySQL. Итак, приступим!

Создание таблицы — CREATE TABLE

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

Вот код скрипта, который создаст нужную нам табличку:

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

Итак, таблица создана.

Добавление строк (записей) в таблицу — INSERT

Добавить новую строку в таблицу можно при помощи SQL команды insert. Вот пример:

SQL запрос состоит из команды INSERT INTO , имени базы данных users, затем в скобках идут имена полей, потом слово VALUE , после которого в скобках следуют добавляемые значения. Значения берутся в кавычки.

Синтаксис запроса выглядит так:

INSERT INTO имя_таблицы (столбец1, столбец2) VALUE (‘х1’, ‘х2’)

Кавычки во вторых скобках обязательны.

На месте значений могут быть переменные. Вот пример:

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

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

Как видим, перечисляемые данные просто отделены запятыми.

Итак, при помощи команды INSERT мы научились добавлять записи в таблицу. Идём дальше.

Просмотр таблицы: команда SELECT

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

Для получения данных из таблицы используется SQL-команда SELECT . Знак * обозначает что мы запрашиваем все данные, затем после слова FROM пишем имя таблицы, из которой хотим получить данные.

Запросим все данные из таблицы users:

Функция mysqli_query() вернула нам — мы его помещаем в переменную и в дальнейшем будем работать с ним при помощи других функций PHP.

Число записей в запросе

Давайте определим сколько строк в нашем запросе? Я вот запустил скрипт добавления записи в таблицу сам не помню сколько раз и теперь не знаю сколько строк в моей таблице.

Для определения числа строк в результате запроса используют функцию mysqli_num_rows() . Этой функции передаётся идентификатор результата запроса, а вернёт она число записей.

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

Число записей в таблице SELECT COUNT(*)

Чтобы узнать число записей в таблице можно воспользоваться командой SELECT COUNT(*) FROM имя_таблицы .

Обратите внимание, тут мы использовали новую функцию PHP mysqli_fetch_row() для получения данных. Эта функция возвращает ряд результата запроса в форме простого массива, в нашем случае в ряду одно поле и оно имеет индес 0.

Просмотр результата запроса в цикле

После выполнения SQL-запроса с командой SELECT и получения идентификатора результата запроса, PHP создаёт в наборе записей результата внутренний указатель. Этот указатель автоматически перемещается на следующую запись, после обращения к текущей записи. Благодаря этому механизму набор результа запроса SELECT очень удобно просматривать в цикле.

В PHP есть несколько функций, при помощи которых можно дла каждой строки результирующего запроса получить массив, состоящий из её полей. Для примера возьмём функцию mysqli_fetch_row() . Этой функции передают идентификатор запроса, а возвращает она массив. Так в цикле просматривается весь результат запроса, по достижению конца результата запроса функция вернёт false .

Итак, запрашиваем все данные из таблицы users ( SELECT * FROM users ).

Функция mysqli_fetch_row() возвращает простой массив. В каждой итерации цикла мы получим массив с строкой из таблицы, доступ к полям которой мы можем получить указав числовой индекс.

То же самое можно сделать используя функцию mysql_fetch_assoc() , она возвращает ассоциативный массив.

Также есть функции mysqli_fetch_array() — возвращает любой тип массива, и mysqli_fetch_object() — возвращает объект.

Запрос SELECT DISTINCT — уникальные значения полей

Давайте создадим новую таблицу:

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

SQL-запрос » SELECT DISTINCT name FROM users » вернул результат со всеми уникальными именами в нашей таблице. Каждое уникальное имя в новой строке результата запроса.

Сортировка результата — ORDER BY

Добавив в SQL-запрос команду ORDER BY мы сортируем результат запроса по возрастанию (цифры и буквы по алфавиту). Вот пример, в котором можно сравнить обычный запрос и отсортированный по возрасту (поле age).

Можете заменить поле age в команде ORDER BY на поле name и посмотреть результат.

Чтобы сортировать результат запроса в обратном порядке используйте команду ORDER BY age DESC .

Соответствие условию — WHERE

Добавив в SQL-запрос команду WHERE мы запросим только те записи, которые соответствуют условию. Например, сделаем запрос на людей младше 30 лет.

Для этого используем SQL-запрос » SELECT * FROM users WHERE age «.

Также мы можем сразу отсортировать результат по возрастанию age:
» SELECT * FROM users WHERE age «.

Если мы сделаем запрос » SELECT name FROM users WHERE age «, то в результате нам вернут только значения поля «name», но они также будут отсортированы по age.

Мы можем запросить значения двух полей: » SELECT name, age FROM users WHERE age «.

Теперь запросим все пользователей, с именем «Max».

И ещё пример запроса , — выберет только имена (name) из таблицы users, все кроме Max.

SELECT name FROM users WHERE name!=’Max’

На этом с запросом WHERE всё.

Ограничение записей — LIMIT

Добавив в SQL-запрос команду LIMIT мы ограничим размер результата.

Запрос, который выводит первые три записи: » SELECT * FROM users LIMIT 3 «. Давайте посмотрим как он работает:

Также тут мы использовали запрос: » SELECT * FROM users LIMIT 3, 3 «. Вторая тройка указывает смещение в результате запроса.

Соответствие шаблону — LIKE

Язык SQL поддерживает простые шаблоны. Для этого используется команда LIKE и шаблон задаётся с использованием символа % .

Вот пример запроса, который вернёт все записи с именами, начинающимися на букву S.

SELECT * FROM users WHERE name LIKE ‘S%’

Вот пример запроса, который вернёт все записи с фамилиями, заканчивающимися на букву s.

SELECT * FROM users WHERE name LIKE ‘%s’

Соответствие условию — IN

Этот запрос с использованием команды IN вернёт только те строки, которые строго соответствую условию.

Например, нас интересуют люди с возрастом 21, 26 и 33 года.

SELECT * FROM users WHERE age IN (21,26,33)

Максимальное и минимальное значение в столбце

Выбирает максимальное значение age в таблице users.

SELECT max(age) FROM users

Следующий запрос выбирает данные из таблицы users по полям name и age где age принимает минимальное значение.

SELECT name, min(age) FROM users

Обновление записи — UPDATE

Давайте Max Lopes установим возраст 15 лет. Это делается запросом MySQL:

UPDATE users SET age=’15’ WHERE name=’Max’ AND surname=’Lopes’

Обратите внимание на новую команду AND (and — по английски значит «и») в запросе. Если мы не уточним фамилию, то возраст 15 лет будет установлен всем Максам в таблице.

Одним запросом можно обновить два и более полей в одной строке. Делается это следующим образом:

UPDATE users SET age = ’18’, surname = ‘Coocker’ WHERE

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

Удалить запись — DELETE

Запрос к базе данных MySQL для удаления записи:

DELETE FROM users WHERE

Опять же, в нашей таблице нет поля id. Но мы можем удалить из неё всех людей, младше 18 лет.

DELETE FROM users WHERE age

Удалить таблицу — DROP TABLE


Запрос к базе данных MySQL который удаляет целиком таблицу users:

DROP TABLE users

Удалить столбец — ALTER TABLE . DROP .

Иногда может потребоваться удалить столбец из таблицы, давайте например удалим из users столбец age:

ALTER TABLE users DROP age

Этот запрос MySQL удалил столбец окончательно и безвозвратно.

Добавить столбец — ALTER TABLE . ADD .

Иногда может потребоваться добавить столбец в существующую таблицу, давайте например снова добавим в таблицу users столбец age:

ALTER TABLE users ADD age TINYINT UNSIGNED

Этот запрос MySQL добавил столбец age с типом данных TINYINT UNSIGNED .

Переименование столбца — ALTER TABLE . CHANGE .

Иногда может потребоваться переименовать столбец, например столбец age переименовать в vozrast. Делаем это так:

ALTER TABLE users CHANGE age vozrast TINYINT UNSIGNED

Этот запрос MySQL переименовал столбец age в vozrast с типом данных TINYINT UNSIGNED .

Переименование таблицы — RENAME TABLE . TO .

Иногда может потребоваться переименовать таблицу:

RENAME TABLE users TO peoples

Удаление базы данных — DROP DATABASE

Этот запрос может удалить базу данных с имененм tester:

DROP DATABASE tester

У меня на денвере этот запрос работает, но на хостинге может и не сработать, если у пользователя базы данных нет прав на выполнение удаления.

Создание базы данных — CREATE DATABASE

Этот запрос создаёт базу данных с имененм tester:

CREATE DATABASE tester

У меня на денвере этот запрос работает, но на хостинге может и не сработать, если у пользователя базы данных нет прав на выполнение удаления.

Итоги

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

Некоторые запросы обычно делают только из phpMyAdmin (создание и удаление баз данных например).

В работе сайтов обычно нужно добавить запись в таблицу, редактировать запись или удалить запись из таблицы.

Следующим шагом будет изучение типов данных в MySQL.

Основные команды SQL, которые должен знать каждый программист

Язык SQL или S tructured Query Language (язык структурированных запросов) предназначен для управления данными в системе реляционных баз данных (RDBMS). В этой статье будет рассказано о часто используемых командах SQL, с которыми должен быть знаком каждый программист. Этот материал идеально подойдёт для тех, кто хочет освежить свои знания об SQL перед собеседованием на работу. Для этого разберите приведённые в статье примеры и вспомните, что проходили на парах по базам данных.

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

Настройка базы данных для примеров

Создайте базу данных для демонстрации работы команд. Для работы вам понадобится скачать два файла: DLL.sql и InsertStatements.sql. После этого откройте терминал и войдите в консоль MySQL с помощью следующей команды (статья предполагает, что MySQL уже установлен в системе):

Затем введите пароль.

Выполните следующую команду. Назовём базу данных «university»:

Команды для работы с базами данных

1. Просмотр доступных баз данных

2. Создание новой базы данных

3. Выбор базы данных для использования

4. Импорт SQL-команд из файла .sql

5. Удаление базы данных

Работа с таблицами

6. Просмотр таблиц, доступных в базе данных

7. Создание новой таблицы

Ограничения целостности при использовании CREATE TABLE

Может понадобиться создать ограничения для определённых столбцов в таблице. При создании таблицы можно задать следующие ограничения:

  • ячейка таблицы не может иметь значение NULL;
  • первичный ключ — PRIMARY KEY (col_name1, col_name2, …) ;
  • внешний ключ — FOREIGN KEY (col_namex1, …, col_namexn) REFERENCES table_name(col_namex1, …, col_namexn) .

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

Пример

Создайте таблицу «instructor»:

8. Сведения о таблице

Можно просмотреть различные сведения (тип значений, является ключом или нет) о столбцах таблицы следующей командой:

9. Добавление данных в таблицу

При добавлении данных в каждый столбец таблицы не требуется указывать названия столбцов.

10. Обновление данных таблицы

11. Удаление всех данных из таблицы

12. Удаление таблицы

Команды для создания запросов

13. SELECT

SELECT используется для получения данных из определённой таблицы:

Следующей командой можно вывести все данные из таблицы:

14. SELECT DISTINCT

В столбцах таблицы могут содержаться повторяющиеся данные. Используйте SELECT DISTINCT для получения только неповторяющихся данных.

15. WHERE

Можно использовать ключевое слово WHERE в SELECT для указания условий в запросе:

В запросе можно задавать следующие условия:

  • сравнение текста;
  • сравнение численных значений;
  • логические операции AND (и), OR (или) и NOT (отрицание).

Пример

Попробуйте выполнить следующие команды. Обратите внимание на условия, заданные в WHERE :

16. GROUP BY

Оператор GROUP BY часто используется с агрегатными функциями, такими как COUNT , MAX , MIN , SUM и AVG , для группировки выходных значений.

Пример

Выведем количество курсов для каждого факультета:

17. HAVING

Ключевое слово HAVING было добавлено в SQL потому, что WHERE не может быть использовано для работы с агрегатными функциями.

Пример

Выведем список факультетов, у которых более одного курса:

18. ORDER BY

ORDER BY используется для сортировки результатов запроса по убыванию или возрастанию. ORDER BY отсортирует по возрастанию, если не будет указан способ сортировки ASC или DESC .

Пример

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

19. BETWEEN

BETWEEN используется для выбора значений данных из определённого промежутка. Могут быть использованы числовые и текстовые значения, а также даты.

Пример

Выведем список инструкторов, чья зарплата больше 50 000, но меньше 100 000:

20. LIKE


Оператор LIKE используется в WHERE , чтобы задать шаблон поиска похожего значения.

«КРОК», Москва, Санкт-Петербург, Троицк, Челябинск, Воронеж, Иркутск, Краснодар, Нижний Новгород, Самара, Пермь, от 120 000 до 240 000 ₽

Есть два свободных оператора, которые используются в LIKE :

  • % (ни одного, один или несколько символов);
  • _ (один символ).

Пример

Выведем список курсов, в имени которых содержится «to» , и список курсов, название которых начинается с «CS-» :

21. IN

С помощью IN можно указать несколько значений для оператора WHERE :

Пример

Выведем список студентов с направлений Comp. Sci., Physics и Elec. Eng.:

22. JOIN

JOIN используется для связи двух или более таблиц с помощью общих атрибутов внутри них. На изображении ниже показаны различные способы объединения в SQL. Обратите внимание на разницу между левым внешним объединением и правым внешним объединением:

Пример 1

Выведем список всех курсов и соответствующую информацию о факультетах:

Пример 2

Выведем список всех обязательных курсов и детали о них:

Пример 3

Выведем список всех курсов вне зависимости от того, обязательны они или нет:

23. View

View — это виртуальная таблица SQL, созданная в результате выполнения выражения. Она содержит строки и столбцы и очень похожа на обычную SQL-таблицу. View всегда показывает самую свежую информацию из базы данных.

Создание

Удаление

Пример

Создадим view , состоящую из курсов с 3 кредитами:

24. Агрегатные функции

Эти функции используются для получения совокупного результата, относящегося к рассматриваемым данным. Ниже приведены общеупотребительные агрегированные функции:

  • COUNT (col_name) — возвращает количество строк;
  • SUM (col_name) — возвращает сумму значений в данном столбце;
  • AVG (col_name) — возвращает среднее значение данного столбца;
  • MIN (col_name) — возвращает наименьшее значение данного столбца;
  • MAX (col_name) — возвращает наибольшее значение данного столбца.

25. Вложенные подзапросы

Вложенные подзапросы — это SQL-запросы, которые включают выражения SELECT , FROM и WHERE , вложенные в другой запрос.

Пример

Найдём курсы, которые преподавались осенью 2009 и весной 2010 годов:

6 запросов для MySQL

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

Сегодня идет много разговоров о Dig Data и других новых технологиях. NoSQL и облачные решения это супер, но много популярного софта (такого как WordPress, phpBB, Drupal) до сих пор работает на MySQL. Миграция на новейшие решения может вылиться не только в изменении конфигурации на серверах. К тому же, эффективность MySQL до сих пор на уровне, особенно версия Percona.

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

Хорошее понимание SQL это важнейший инструмент для веб-разработчика, именно он позволит эффективно оптимизировать и использовать реляционные базы данных. В этой статье мы сфокусируемся на популярной открытой базе данных, часто используется в связке с PHP, и это MySQL.

Для кого эта статья?

Для веб-разработчиков, архитекторов и разработчиков баз данных и системных администраторов, хорошо знакомых с MySQL. Если раньше вы не использовали MySQL, эта статья может не принести вам пользы, но я все равно буду стараться быть как можно более информативным и полезным даже для новичков в MySQL.

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

Делать бэкапы MySQL просто, используя утилиту mysqldump:

Вы можете узнать больше о mysqldump .

Что делает запрос медленным?

Вот общий список факторов, влияющих на скорость выполнения запросов и нагрузки сервера:

  • индексы таблиц;
  • условие WHERE(и использования внутренних функций MySQL, например, таких как IF или DATE);
  • сортировка по ORDER BY;
  • частое повторение одинаковых запросов;
  • тип механизма хранения данных (InnoDB, MyISAM, Memory, Blackhole);
  • не использование версии Percona;
  • конфигурации сервера ( my.cnf / my.ini );
  • большие выдачи данных (более 1000 строк);
  • нестойкое соединение;
  • распределенная или кластерная конфигурация;
  • слабое проектирование таблиц.

Далее мы обратимся ко всем этим проблемам. Также, установите Percona , если вы еще не используете эту встроенную замену стандартному MySQL — это придаст сильное увеличение мощности базы данных.

Что такое индексы?

Индексы используются в MySQL для поиска строк с указанными значениями колонок, например, с командой WHERE. Без индексов, MySQL должна, начиная с первой строки, прочитать всю таблицу в поисках релевантных значений. Чем больше таблица, тем больше затрат.

Если таблица имеет индексы на колонках, которые будут использованы в запросе, MySQL быстро найдет расположения необходимой информации без просмотра всей таблицы. Это гораздо быстрее, чем последовательный поиск в каждой строке.

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

Уменьшаем частое повторение одинаковых запросов

Наиболее быстрый и эффективный способ, который я нашел для этого — это создание хранилища запросов и результатов их выполнения с помощью Memcached или Redis. С Memcache вы можете легко положить в кэш результат выполнения вашего запроса, например, следующим образом:

Теперь тяжелый запрос, использующий LEFT JOIN, будет выполняться только раз за каждые 86 400 секунд (то есть раз в сутки), что значительно уменьшит нагрузку MySQL сервера, оставив ресурсы для других соединений.

Примечание: Допишите p: в начале аргумента хоста MySQLi для создания постоянного соединения.

Цукерберг рекомендует:  Помощь - Помогите разобрать код на JS, итеративный процесс.

Распределенная или кластерная конфигурация

Когда данных становится все больше, и скорость вашего сервиса идет под уклон, паника может овладеть вами. Быстрым решением может стать распределения ресурсов (sharding). Однако я не рекомендую делать это, если вы не обладаете хорошим опытом, поскольку распределение по своей сути делает структуры данных сложнейшими.

Слабое проектирование таблиц

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

Обеспечение правильного проектирования для нужного использования является первостепенным в создании вашего приложения. Храните различные данные в различных таблицах (например, категории и статьи) и убедитесь, что отношения к другу (many to one) и один ко многим (one to many) могут быть легко связаны с идентификаторами (ID). Использование FOREIGN KEY в MySQL идеально подходит для хранения каскадных данных в таблицах.

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

  • Создавайте эффективные таблицы для решения ваших задач, а не заполняйте таблицы лишними данными и связями.
  • Не ожидайте от MySQL выполнения вашей бизнес логики или програмности — данные должны быть готовы к вставке строки вашей скриптовым языком. Например, если вам нужно отсортировать список в случайном порядке, сделайте это в массиве PHP, не используя ORDER BY из арсенала MySQL.
  • Используйте индексные типы UNIQUE для уникальных наборов данных и применяйте ON DUPLICATE KEY UPDATE, чтобы хранить дату обновленной, например, для того, чтобы знать, когда строка была в последний раз изменена.
  • Используйте тип данных INT для сохранения целых чисел. Если вы не укажете размер типа данных, MySQL сделает это за вас.

Основы оптимизации

Для эффективной оптимизации мы должны применять три подхода к вашему приложению:

  1. Анализ (логирование медленных запросов, изучение системы, анализ запросов и проектирование базы данных)
  2. Требования к исполнению (сколько пользователей)
  3. Ограничения технологий (скорость железа, неправильное использование MySQL)

Анализ может быть сделан несколькими путями. Сначала мы рассмотрим наиболее очевидные способы, чтобы заглянуть под капот вашей MySQL, в котором выполняются запросы. Самый первый инструмент оптимизации в вашем арсенале это EXPLAIN. Если добавить этот оператор перед вашим запросом по SELECT, результат запроса будет таким:

Колонки, вы видите, сохраняют важную информацию о запросе. Колонки, на которые вы должны обратить наибольшее внимание это possible_keys и Extra.

Колонка possible_keys покажет индексы, в которые MySQL имел доступ, чтобы выполнить запрос. Иногда нужно назначить индексы, чтобы запрос выполнялся быстрее. Колонка Extra покажет, были ли использованы дополнительные WHEREили ORDER BY. Наиболее важно обратить внимание, есть ли Using Filesort в выводе.

Что делает Using Filesort, указано в справке MySQL:

MySQL должен выполнить дополнительный проход, чтобы понять, как вернуть строки в отсортированном виде. Это сортировка происходит проходом по всем строкам в соответствии с типом объединения и сохраняет ключ к сортировке и указатель на строку для всех строк, совпадающих с условным выражением WHERE. Ключи сортируются и строки возвращаются в нужном порядке.

Лишний проход замедлит ваше приложение, этого нужно избегать, чего бы это ни стоило. Другой критический результат Extra, который мы должны избегать — это Using temporary. Он говорит о том, что MySQL пришлось создать временную таблицу для выполнения запроса. Очевидно, это ужасное использования MySQL. В таком случае результат запроса должен быть сохранен в Redis или Memcache и не выполняться пользователями лишний раз.

Чтобы избежать проблемы с Using Filesort мы должны увериться, что MySQL использует INDEX. Сейчас указано несколько ключей в possible_keys, из которых можно выбирать, но MySQL может выбрать только один индекс для финального запроса. Также индексы могут быть составлены из нескольких колонок, также вы можете ввести подсказки (хинты) для оптимизатора MySQL, указывая на индексы, что вы создали.

Оптимизатор MySQL будет использовать статистику, основанную на запросах таблиц, чтобы выбрать лучший индекс для выполнения запроса. Он действует достаточно просто, основываясь на встроенной статистической логике, поэтому имея несколько вариантов, не всегда делает правильный выбор без помощи хинтинга. Чтобы убедиться, что был использован правильный (или неправильный) ключ, воспользуйтесь ключевым словам FORCE INDEX, USE INDEX и IGNORE INDEX в вашем запросе. Вы можете прочитать больше о хинтинге индексов в справке MySQL .

Чтобы вывести ключи таблицы, используйте команду SHOW INDEX. Вы можете задать несколько хинтов для использования оптимизатором.

В дополнение к EXPLAIN существует ключевое слово DESCRIBE. Вместе с DESCRIBE можно просматривать информацию из таблицы следующим образом:

Для добавления индексов в MySQL надо использовать синтаксис CREATE INDEX. Есть несколько видов индексов. FULLTEXT Применяется для полнотекстового поиска, а UNIQUE — для хранения уникальных данных.

Чтобы добавить индекс в вашу таблицу, используйте следующий синтаксис:

Это создаст индекс на таблице books, которая будет использовать первые 10 букв из колонки, которая хранит названия книг и имеет тип varchar. В этом случае, любой поиск с запросом WHERE на название книги с совпадением до 10 символов будет давать такой же результат, как и просмотр всей таблицы от начала до конца.

Индексы имеют большое влияние на скорость выполнения запросов. Только назначения главного уникального ключа недостаточно — композитные ключи являются реальной областью применения в настройке MySQL, что иногда требует некоторых A/B проверок с использованием EXPLAIN.

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

Как только мы создали ключ на основе колонки username, в котором хранится имя пользователя и колонки active типа ENUM, определяющий, активен ли его аккаунт. Теперь все оптимизировано для запроса, который будет использовать WHERE для поиска валидного имени пользователя с активным аккаунтом (active = 1).

Насколько быстра ваша MySQL?

Включим профилирование, чтобы подробнее рассмотреть MySQL запросы. Это можно сделать, выполнив команду set profiling=1, после чего для просмотра результата надо выполнить show profiles.

Если вы используете PDO, выполните следующий код:

То же самое можно сделать с помощью mysqli:

Это вернет вам профилированные данные, содержащие время выполнения запроса во втором элементе ассоциативного массива.

Этот запрос выполнялся 0.00024300 секунд. Это довольно быстро, поэтому не будем беспокоиться. Но когда числа становятся большими, мы должны смотреть глубже. Перейдите к вашему приложению, чтобы потренироваться на рабочем примере. Проверьте константу DEBUG в конфигурации вашей базы данных, а затем начните изучать систему, включив вывод результатов профилирования с помощью функций var_dump или print_r. Так вы сможете переходить со страницы на страницу в вашем приложении, получив удобное профилирование системы.

Полный аудит работы базы вашего сайта

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


Чтобы включить логирование в MySQL 5.1.6 используйте глобальную переменную log_slow_queries, также вы можете отметить файл для логирования с помощью переменной slow_query_log_file. Это можно сделать, выполнив следующий запрос:

Также это можно указать в файлах конфигурации /etc/my.cnf или my.ini вашего сервера.

После внесения изменений не забудьте перезагрузить MySQL сервер необходимой командой, например service mysql restart, если вы используете Linux.

В версиях MySQL после 5.6.1 переменная log_slow_queries обозначена как устаревшая и вместо нее используется slow_query_log. Также для более удобного дебаггинга можно включить вывод в таблице, задав переменной log_output значение TABLE, однако эта функция доступна только с MySQL 5.6.1.

Переменная long_query_time определяет количество секунд, после которых выполнение запроса считается медленным. Значение это 10, а минимум это 0. Также можно указать миллисекунды, используя дробь; сейчас я указал одну секунду. И теперь каждый запрос, который будет выполняться дольше 1 секунды, записывается в логи в таблице.

Логирование будет вестись в таблицах mysql.slow_log и mysql.general_log вашей MySQL базы данных. Чтобы выключить логирование, измените log_output на NONE.

Логирование на рабочем сервере

На рабочем сервере, который обслуживает клиентов, лучше применять логирование только на короткий период и для мониторинга нагрузки, чтобы не создавать лишней нагрузки. Если ваш сервис перегружен и необходимо безотлагательное вмешательство, попробуйте выделить проблему, выполнив SHOW PROCESSLIST, или обратитесь к таблице information_schema.PROCESSLIST, выполнив SELECT * FROM information_schema.PROCESSLIST;.

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

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

Логирование множества запросов

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

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

Горячий и холодный кэш

Количество запросов и нагрузка сервера имеет сильное влияние на исполнение, также может повлиять на время выполнения запросов. При разработке вы должны взять за правило, что выполнение каждого запроса должно быть не более доли миллисекунды (0.0xx или быстрее) на свободном сервере.

Применение Memcache имеет сильный эффект на нагрузку серверов, освободит ресурсы, которые выполняют запросы. Убедитесь, что вы используете Memcached эффективно и протестовали ваше приложение с горячим кэшем (подгруженными данным) и с холодным кэшем.

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

Исправление медленных запросов

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

Если вы пока не нашли медленного запроса, проверьте настройки long_query_time, если вы пользуетесь этим методом логирования. Иначе, проверив все ваши запросы профилирования (set profiling=1), составьте список запросов, отнимают больше времени, чем доля миллисекунд (0.000x секунд) и начнем из них.

Вот шесть самых распространенных проблем, которые я находил, оптимизируя MySQL запросы:

ORDER BY и filesort

Предотвращение filesort иногда невозможно из-за выражения ORDER BY. Для оптимизации сохраните результат в Memcache, или выполните сортировку в логике вашего приложения.

Использование ORDER BY вместе с WHERE и LEFT JOIN

ORDER BY очень замедляет выполнение запросов. Если это возможно, старайтесь не использовать ORDER BY. Если же вам необходима сортировка, то используйте сортировку по индексам.

Применение ORDER BY по временным колонками

Просто не делайте этого. Если вам нужно объединить результаты, сделайте это в логике вашего приложения; не используйте фильтрацию или сортировку во временной таблице запроса MySQL. Это требует много ресурсов.

Игнорирование индекса FULLTEXT

Использование LIKE это самый лучший способ сделать полнотекстовый поиск медленным.

Беспричинный выбор большого количества строк

Забыв о LIMIT в вашем запросе можно сильно увеличить время выполнения выборки из базы данных в зависимости от размера таблиц.

Чрезмерное использование JOIN вместо создания композитных таблиц или представления

Когда в одном запросе вы пользуетесь больше чем тремя-четырьмя операторами LEFT JOIN, спросите себя: все ли здесь верно? Продолжайте, если у вас есть на то веская причина, например — запрос используется не часто для вывода в панели администратора, или результат вывода может быть сохранен в кэше. Если же вам нужно выполнять запрос с большим количеством операций объединения таблиц, тогда лучше задуматься о создании композитных таблиц из необходимых столбиков или использовать представления.

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

Также мы посмотрели на несколько примеров и классических ловушек, в которые вы можете попасть, используя MySQL. Используя хинтинг индексов, мы можем увериться в том, что MySQL выберет необходимые индексы, особенно при нескольких выборках в одной таблице. Чтобы продолжить изучение темы, я советую вам посмотреть в сторону Percona project.

25 примеров команды SELECT в MySQL

На этом уроке мы расскажем, как использовать команду SELECT в MySQL с несколькими практическими примерами.

1. Основной пример команды SELECT

Во-первых, для подключения к командной строке MySQL, выполните следующие действия в вашей строке операционной системы.

Далее, просмотреть все доступные базы данных.

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

Основное использование команды SELECT является просмотр строк из таблицы. Ниже приведен пример команды SELECT, где будет отображать все строки из таблицы “worker”.

Или выбрать конкретные столбцы, указав имена столбцов (вместо *, который даст все столбцы).

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

2. Выберите одну из двух – виртуальная таблица

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

Например, вы можете использовать выбор в две таблицы для выполнения арифметических операций, как показано ниже.

Вы можете также использовать двойную таблицу для просмотра текущей даты и времени. Функция now() в MySQL аналогична функции sysdate() в базе данных Oracle.

Если вы не укажете любую таблицу, MySQL будет считать, что вы хотите использовать двойную. Следующий пример точно такой же, как указано выше. Просто, чтобы избежать путаницы, я рекомендую вам использовать “from dual” в эти ситуации для лучшей читаемости и ясности.

3. Основные условия WHERE для ограничения записей

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

Кроме знака “больше >” вы можете также использовать “равно =”, “не равно! =”, как показано ниже.

4. Строки в условии WHERE

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

Точное совпадение строк работает как числовое совпадение с помощью “равным =”, как показано ниже. Этот пример покажет всех сотрудников, которые принадлежат к отделу IT.

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

Вы можете также использовать !=. Для отображения всех сотрудников, который не принадлежат к отделу IT, как показано ниже.

Кроме того, можно выполнить частичное совпадение строки с помощью % в ключевых словах. Ниже будут показаны все сотрудников фамилия которых начинается с “And”.

Ниже будут показаны все сотрудники имя которых заканчивается на “ex”.

Вы также можете дать % в обоих направлениях. В этом случае, он будет искать для данного ключевого слова в любом месте строки. Ниже будут показаны все сотрудники, которые содержат “Andr” в их имени в любом месте.

5. Объединение WHERE с OR, AND

Вы можете также использовать OR, AND, NOT в WHERE для объединения нескольких условий. В следующем примере показаны все сотрудники, которые находятся в отделении «IT» и с зарплатой> = 6000. Это будет отображать записи только тогда, когда оба условия выполнены.

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

6. Объединение значений столбцов с помощью CONCAT в SELECT

Вы можете использовать функцию CONCAT в команде SELECT, объединить значения из нескольких столбцов и отображать их. Следующий пример сочетает в себе имя и отдел (только для отображения), как показано ниже.

7. Общее количество записей Count

Использование COUNT(*) в команде SELECT, чтобы отобразить общее количество записей в таблице.

8. Группировка в команде Select

Команда Group By будет группировать записи на основе определенных условий. В следующем примере отображается общее число сотрудников в каждом отделе.

Пожалуйста, обратите внимание, что при использовании GROUP BY, вы можете использовать некоторые функции, чтобы получить более значимый вывод. В приведенном выше примере, мы использовали COUNT(*) группу по командам. Точно так же вы можете использовать sum(), avg(), и т.д., при указании GROUP BY.

9. Использование HAVING вместе с GROUP BY

При использовании GROUP BY, вы можете также использовать HAVING для дальнейшего ограничения записи.

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

10. Определение псевдонима с помощью ключевого слова ‘AS’

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

В следующем примере, даже при том, что настоящее имя столбца ID, он отображается как EmpId.

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

11. Left Join в команде SELECT

В следующем примере команда SELECT объединяет две таблицы. т.е. сотрудник и отдел. Для объединения их, он использует общий столбец между двумя этими таблицами отдела. Колонка “Location” показана на выходе из таблицы отдела.

Вы можете также использовать имя псевдонима таблицы в команде JOIN, как показано ниже. В этом примере я использовал “E” в качестве псевдонима для таблицы сотрудников, и “D” в качестве псевдонима для таблицы отделов. Это делает выбор команды меньше и легче читать.

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

12. Анализ производительности с помощью EXPLAIN

Когда ваш запрос на выборку медлителен, или ведет себя таким образом, что вы не понимаете, используйте команду EXPLAIN, которая будет отображать дополнительную информацию, MySQL использует внутренне для выполнения запроса. Это может дать вам некоторое представление о производительности вашего выбора команды MySQL.

13. Форсировать запрос SELECT, используя INDEX

При выполнении запроса на выборку, и объединения двух таблиц, MySQL будет решать, как эффективно использовать любые доступные индексы в таблицах. Ниже приведены несколько способов борьбы с индексами в SELECT.

  • USE INDEX (list_of_indexes) – будет использовать один из индексов, указанных для запроса записей из таблицы.
  • IGNORE INDEX (list_of_indexes) – будет использовать индексы, определенные для запроса записей из таблицы.
  • FORCE INDEX (index_name) – заставит MySQL использовать данный индекс, даже если MySQL делает лучше и быстрее запросы доступные для этой записи.

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

Следующие примеры MySQL использовать worker_emp_nm_idx для этого запроса.

Чтобы отобразить все доступные индексы конкретной таблицы, используйте команду “show index”. В следующем примере отображаются все индексы, доступные в таблице сотрудника.


14. Сортировка записей с помощью ORDER BY

Примечание: по умолчанию будет сортировать по убыванию. Если вы ничего не укажите, он будет по возрастанию.
Следующие записи будут указываться в алфавитном порядке, основанном на столбце DEPT.

Обратите внимание, что по умолчанию он будет сортировать в порядке возрастания. Если вы хотите отсортировать по убыванию, укажите ключевое слово “DESC” после “ORDER BY”, как показано ниже.

Вы также можете указать по нескольким столбцам, как показано ниже.

15. Ограничить количество записей

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

Следующий пример будет начинаться с номером записи 0 (который является первой записью), и выдаст 3 записи.

Ниже будут начинаться с номером записи 1 (которая является второй записью), и выдаст 3 записи.

Вы также можете опустить start_record, в этом случае, он всегда будет начинаться с номером записи 0 (т.е. первая запись).

В следующем примере, мы указали только одно значение. Таким образом, это будет исходить из рекордного числа 0, а также отображать 3 записи.

16. Ограничить количество записей с OFFSET

Формат ограничения OFFSET:

Вы также можете использовать ключевое слово OFFSET, где вы будете указывать начальную запись после ключевого слова OFFSET.

Ниже будет отображаться в общей сложности 3 записей. Так как смещение определяется как 1, то начнет со 2-й записи.

17. Получить уникальные значения из столбца

Чтобы отобразить все уникальные значения из столбца, используйте DISTINCT.

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

18. Сумма всех значений в столбце

Чтобы добавить все значения из столбца, используйте функцию sum().

Следующий пример покажет сумму столбца заработной платы для всех работников, которые принадлежат к отделу IT.

19. Среднее значение всех значений в столбце

Для того, чтобы вывести среднее арифметическое всех значений из столбца, используйте функцию avg().

Следующий пример покажет среднюю зарплату каждого и каждого отдела. Объединение GROUP BY с функцией avg().

20. SELECT в команде SELECT

Пример, приведенный ниже, является очень неточным. Там нет никаких причин, чтобы сделать это таким образом. Но это показывает вам, как вы можете использовать команду SELECT. В этом примере “ACTION” дает имя псевдонима для выбора подзапроса. Вы должны указать псевдоним в этом примере. “ACTION” это просто название. Вы можете изменить его как угодно.

21. Использование оператора Select при выводе в файл

Используя SELECT INTO, вы можете сохранить вывод команды в файл.

Вместо того, чтобы отображать выходные данные на экране, следующий пример команды select будет сохранять вывод выбора команды в файл /tmp/worker.txt.

Вы также можете сохранить вывод в файл с разделителями запятыми, указав “FIELDS TERMINATED BY”, как показано в приведенном ниже примере.

22. Выполнение процедур на наборе данных

Кроме того, можно вызвать процедуру MySQL, которая будет обрабатывать данные с выходом команды SELECT.

В следующем примере выполнения процедуры salary_report () на выходе данного команды SELECT.

23. Показать случайную запись из таблицы

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

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

Можно также передать текущую дату и время, как соль, используя функцию now() к команде rand, как показано ниже.

24. Высокий приоритет команды Select

При использовании ключевого слова HIGH_PRIORITY в операторе SELECT, даст конкретному оператору SELECT более высокий приоритет, чем любому обновление в таблице.

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

25. Последовательное чтение в команде Select

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

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

Следующая команда не позволит другому сеансу MySQL изменять записи, которые запрашиваются у оператора SELECT, пока она не прочитает все эти записи.

Обратите внимание, что вы также можете сделать “FOR UPDATE”, как показано ниже, которые будут блокировать другие сеансы “SELECT … LOCK IN SHARE MODE”, пока эта транзакция не закончится.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Часть 6. Специализированные формы запросов

Серия контента:

Этот контент является частью # из серии # статей: Практическое использование MySQL++

Этот контент является частью серии: Практическое использование MySQL++

Следите за выходом новых статей этой серии.

Запросы с параметрами или шаблоны запросов (template queries) представляют особый интерес в тех случаях, когда приходится выполнять множество почти одинаковых по форме команд SQL, отличающихся лишь фактическими параметрами в условиях отбора данных. С них мы и начнём, а затем рассмотрим некоторые другие специализированные запросы: команды создания таблиц в базе данных и процедуры извлечения, добавления и изменения данных при помощи специализированных структур SSQLS (Specialized SQL Structures).

1. Параметризованные запросы

Библиотека MySQL++ предоставляет возможность формирования и использования так называемых шаблонов запросов (template queries), то есть, запросов, в которых конкретные элементы условий выбора строк данных из таблиц заменены формальными параметрами. Можно провести некоторую аналогию с форматом функции printf(), широко применяемой в языке программирования C: вы передаёте MySQL++ строку, содержащую постоянные части запроса и форматные шаблоны (placeholdres) для переменных элементов, которые впоследствии будут заменяться соответствующими значениями.

Цукерберг рекомендует:  Обучение - Нету ли професионального курса C#

1.1. Пример формирования и использования шаблона запроса

Снова обратимся к таблице товаров wares, с которой мы работали в предыдущих статьях. Её структура остаётся неизменной:

Рассмотрим следующий код, в котором демонстрируется практическое применение шаблона запроса с параметрами:

Принцип использования шаблона запроса прост: сначала формируется строка запроса, содержащая формальные параметры, затем с помощью функции parse() этот шаблон запроса активизируется. После этого вы можете многократно обращаться к данному шаблону, вызывая любой метод класса Query и передавая в него требуемые параметры. В данном примере применялся метод Query::execute().

1.2. Настройка элементов шаблона запроса

Как было показано в приведённом выше примере, при формировании строки шаблона запроса в объекте типа Query используются пронумерованные элементы шаблона, размещаемые в тех позициях строки, где в дальнейшем будут выполняться подстановки фактических параметров. Вызываемая после создания шаблона функция parse() сообщает Query-объекту о том, что переданная ему строка является шаблоном и требует соответствующей обработки:

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

Обязательными являются только символ % (процент) и номер элемента NNN (может содержать до трёх цифр). Нумерация элементов начинается с нуля. Порядок следования параметров передаётся в объект SQLQueryParms.

  • % — собственно символ «процент»;
  • «» — не заключать в кавычки и не экранировать содержимое фактического параметра;
  • q — выполнять экранирование спец.символов фактического параметра с помощью MySQL C API-функции mysql_escape_string() и заключить фактический параметр в одиночные кавычки, если это необходимо, в зависимости от типа используемого значения;
  • Q — Заключить содержимое фактического параметра в кавычки, но не выполнять экранирование. Иногда это позволяет сэкономить немного времени на обработку, если точно известно, что строка не содержит символов, требующих экранирования.

Для любого элемента можно определить «:имя», которое будет использоваться в объекте SQLQueryParms. Имя может содержать алфавитно-цифровые символы и символ подчёркивания. Для того, чтобы явно обозначить окончание имени, можно использовать необязательный символ «двоеточие» (например, «%2:field1:»). Если после имени должно располагаться двоеточие, то необходимо записать два «хвостовых» двоеточия подряд — «%3:field2::». В этом случае первое «хвостовое» двоеточие будет интерпретировано, как окончание имени, а второе останется «как есть», без изменений.

1.3. Передача фактических параметров во время выполнения

Для того, чтобы передать фактические значения параметров для подстановки их в строку запроса, необходимо вызвать метод Query::store( const SQLString &parameter0 [, . const SQLString &parameterN] ). Кроме того, соответствующим образом перегружаемыми являются и другие методы выполнения запросов Query::storein(), Query::use() и Query::execute(). В списке аргументов parameter0 соответствует первому передаваемому фактическому параметру и т.д. Всего можно задать до 25 передаваемых параметров. Для определённого в предыдущем подразделе шаблона запроса передача фактических значений параметров может выглядеть следующим образом:

после чего строка запроса должна принять такой вид:

У читателя может возникнуть вопрос: почему в строке шаблона запроса так нелогично пронумерованы формальные параметры — не в порядке их естественного следования? Ответ — в следующем подразделе.

1.4. Значения параметров, принимаемые по умолчанию

Механизм формирования шаблонов запросов позволяет определять значения параметров по умолчанию. Значение, устанавливаемое по умолчанию, присваивается элементу массива Query::template_defaults с соответствующим индексом. Вы можете выполнять присваивание, обращаясь с нужному элементу по его номеру (позиции) или по имени (если оно было определено в шаблоне запроса), например:

или (с тем же результатом)

Здесь обнаруживается большое сходство с механизмом определения параметров по умолчанию в функциях языка C++: если параметры с присвоенными им значениями по умолчанию расположены в конце списка, то при вызове методов выполнения запросов класса Query не обязательно явно указывать все передаваемые значения. Если запрос принимает четыре параметра, а для двух последних (по порядку номеров) вы установили значения по умолчанию, то при вызове метода выполнения запроса в него могут быть переданы как минимум два явных фактических параметра.

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

В результате для res1 запрос будет выглядеть так:

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

2. Создание таблиц БД

Здесь мы приступаем к рассмотрению специализированных структур SSQLS (Specialized SQL Structures), которые позволяют определять структуры языка C++, соответствующие формату SQL-таблиц. Любая SSQLS-структура содержит члены-переменные, соответствующие отдельным полям SQL-таблицы. Но кроме этого в подобной структуре имеются методы, операторы и члены-данные, используемые для обеспечения внутренней функциональности MySQL++.

SSQLS-структуры создаются при помощи макросов, определённых в файле ssqls.h. Это специализированный заголовочный файл библиотеки MySQL++, который не включается автоматически через заголовочный файл mysql++.h. Если вы хотите воспользоваться функциональными возможностями SSQLS-структур, то должны явно включить файл ssqls.h в свой исходный код.

2.1. Процедура создания таблицы базы данных

Если для создания таблицы требуется выполнение запроса:

то в терминах языка C++ соответствующая структура может быть определена следующим образом (разумеется, при условии использования библиотеки MySQL++):

Эта макрокоманда объявляет структуру wares, в которой содержатся имена всех полей SQL-таблицы с указанием соответствующего типа данных. В библиотеке MySQL++ определены C++-типы практически для всех MySQL-типов данных в форме sql_*.

Обобщённый синтаксис макрокоманды для создания SSQLS-структуры выглядит так:

Здесь N — количество полей в таблице и соответственно количество членов-переменных структуры, «имя» — имя структуры (имя таблицы), «тип#» — тип данных члена-переменной, а «поле#» — имя этого члена-переменной (совпадает с именем поля таблицы).

Второй и третий параметры требуют дополнительных разъяснений. Макрокоманда sql_create_N добавляет члены-функции и операторы в каждую SSQLS-структуру, чтобы обеспечить сравнение одного экземпляра такой структуры с другим. Эти функции сравнивают первые «comp_count» полей (членов-переменных) в данной структуре. В нашем примере создания структуры wares значение comp_count равно 1, поэтому при сравнении двух структур типа wares будут сравниваться значения только одного поля name.

Это свойство наиболее эффективно, когда ключевые поля таблицы занимают первые позиции в струкуре SSQLS, а значение параметра comp_count равно количеству этих ключевых полей.

Значение comp_count не должно быть меньше 1. Это требование текущей реализации SSQLS-структур в библиотеке MySQL++.

К SSQLS-структуре, например, к объявленной выше структуре wares можно применять алгоритмы стандартной библиотеки STL и методы стандартных контейнеров:

Этот фрагмент кода выводит самое первое найденное наименование товара в наборе результатов, которое начинается с цепочки символов «Стол».


Третий параметр макрокоманды sql_create_N — числовое значение set_count. Если оно не равно нулю, то в структуру добавляется член-метод set() для установки значений того количества полей этой структуры, которое соответствует значению set_count. Так например, в рассматриваемой нами структуре метод set() будет выполнять установку значений всех трёх полей: name, num и price.

3. Извлечение, добавление и модификация данных

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

3.1. Извлечение данных

Разумеется, для извлечения данных из таблицы мы будем использовать SSQLS-структуру.

Обратите внимание на использование контейнера vector из стандартной библиотеки для хранения результатов запроса.

3.2. Добавление данных в таблицу

3.3. Изменение существующих данных

Операция редактирования любого поля данных выполняется почти так же просто, как и добавление строк данных.

4. Заключение

Итак, мы убедились, что с помощью библиотеки MySQL++ можно без затруднений формировать шаблоны запросов с подставляемыми параметрами и многократно использовать эти шаблоны в исходном коде приложения, а специальные структуры SSQLS (Specialized SQL Structures) являются удобным инструментом во многих случаях, когда требуется извлечение, добавление и модификация данных в таблицах.

В данной статье рассматривались специализированные формы запросов. В заключительной, седьмой статье цикла будет продемонстрировано практическое применение библиотеки MySQL++ в многопоточных приложениях.

Интересные и полезные запросы MySQL

Ни для кого не секрет, что одним из популярных языков запросов для баз данных является MySQL. Эта свободная реляционная система управления базами данных, разработанная Oracle. Здесь не буду описывать все преимущества или недостатки данной СУБД (при желании прочтете самостоятельно в сети Интернет).

Сегодня поговорим об интересных и полезных запросах в MySQL.

Получение данных объединенных полей.

SELECT CONCAT(fio,’ — ‘,phone) AS contact FROM `table` WHERE `

В результате выполнения запроса мы получим информацию в виде нового поля contact, которое является объединением двух полей: fio и phone. Для удобства эти поля разделены дефисом.

Удаление дубликатов в таблице.

ALTER IGNORE TABLE `table` ADD UNIQUE (`fio`, `email`);

В результате выполнения запроса будут автоматически удалены все дубликаты записей (будет создан уникальный ключ для полей fio и email).

Преобразование строки в число.

Здесь приведено сразу 4 математических операции. В результате выполнения любого из этих запросов происходит преобразование строки в число. Фактически, учитывается только первый символ в подстроке. Далее, в результате математической операции строка преобразуется в число. Данные запросы для общего понимания.

А вот и сами результаты запросов:

4
-2
3
0,3333333333333333

Выбор записей, которые повторяются определенное количество раз.

SELECT `fio`, `country` FROM `table` GROUP BY `country` HAVING COUNT(*) = 2;

В результате выполнения данного запроса будут выведены все записи с полями fio и country, для которых поле country встречается 2 раза. Таким образом легко получить повторяющиеся значения (значения, встречающиеся n-раз).

Событие для удаления записей таблицы каждый час.

Здесь самой первой строчкой включаем планировщик событий. Далее — создается событие с именем hourly_event, которое содержит запрос на удаление всех данных из таблицы table. Указанное событие выполняется каждый час.

Просмотр активных событий в планировщике.

SHOW EVENTS WHERE STATUS=’ENABLED’

Удалить неактивные учетные записи, которым свыше трех дней.

Кстати, если захотите изменить временной интервал для данного события, выполните следующий запрос:

ALTER EVENT `not_active_users` ON SCHEDULE EVERY 8 HOUR;

Этот запрос изменит интервал выполнения события not_active_users на каждые 8 часов.

Архивирование таблицы с помощью планировщика событий.

В начале создается процедура с именем archive_table. В указанной процедуре создается временная таблица (имя таблицы с определенным форматом), в которую копируются данные. После, исходная таблица table с данными очищается. Затем создается процедура archive_event. Эта процедура будет выполняться 1 раз в неделю, начиная с текущего момента времени.

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

Получить название поля, которое является первичным ключом в таблице.

SELECT `COLUMN_NAME` FROM `information_schema`.`COLUMNS` WHERE `TABLE_NAME` = ‘table’ AND `COLUMN_KEY` = ‘PRI’;

В моем случае в результате выполнения запроса было возвращено значение: id.

Получить размер базы данных MySQL.

Получение размера базы данных с именем test.

Определить количество слов в столбце.

SELECT LENGTH(`fio`) — LENGTH(REPLACE(`fio`, ‘ ‘, »)) + 1 AS `words_count` FROM `table`;

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

Спасибо за внимание.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Запросы в MySQL

Базы данных являются ключевым компонентом многих веб-сайтов и приложений и лежат в основе хранения и обмена данными в Интернете. Одним из наиболее важных аспектов управления базой данных является процедура извлечения данных из БД, будь то разовое обращение или часть процесса, закодированного в приложении. Существует несколько способов извлечения информации из базы данных, но один из наиболее часто используемых методов – это отправка запросов через командную строку.

В системах управления реляционными базами данных запрос – это любая команда, используемая для извлечения данных из таблицы. В языке структурированных запросов (SQL) запросы почти всегда выполняются с помощью оператора SELECT.

В этом мануале мы обсудим основной синтаксис SQL-запросов, а также некоторые из наиболее часто используемых функций и операторов. Мы также попрактикуемся в создании запросов SQL на тестовых данных в БД MySQL.

MySQL – это реляционная система управления базами данных с открытым исходным кодом. MySQL – одна из наиболее распространенных баз данных SQL, среди ее приоритетов скорость, надежность и удобство использования. Как правило, она соответствует стандарту ANSI SQL, хотя в некоторых случаях MySQL выполняет операции не по признанному стандарту.

Требования

В общем, команды и понятия, представленные в этом мануале, могут использоваться в любой операционной системе на базе Linux и в любом программном обеспечении SQL. Однако мануал был написан специально для сервера Ubuntu 18.04 и MySQL. Для работы вам понадобится:

  • Сервер Ubuntu 18.04 с пользователем sudo. Начальная настройка сервера описана здесь.
  • Предварительно установленная система MySQL. Инструкции по установке можно найти в мануале Установка MySQL в Ubuntu 18.04.

Создание тестовой базы данных

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

В качестве БД, которую мы будем использовать в этом руководстве, мы предлагаем следующий сценарий.

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

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

Для начала откройте командную строку MySQL как пользователь root:

Примечание: Если вы полностью выполнили мануал по установке MySQL в Ubuntu 18.04, вероятно, вы настроили парольную аутентификацию для пользователя root. В этом случае вы можете подключиться к командной строке с помощью следующей команды:

CREATE DATABASE `birthdays`;

Выберите эту БД:

Затем создайте в этой базе данных две таблицы. Первую таблицу можно использовать, чтобы отслеживать результаты в боулинге. Следующая команда создаст таблицу под названием tourneys. В ней будут столбцы с именами подруг (name), количество выигранных ими турниров (wins), их лучшие результаты за все время (best) и размер ботинок для боулинга, которые они носят (size):

CREATE TABLE tourneys (
name varchar(30),
wins real,
best real,
size real
);

Запустив эту команду и указав заголовки столбцов, вы увидите такой вывод:

Query OK, 0 rows affected (0.00 sec)

Теперь добавьте в таблицу какие-нибудь данные:

INSERT INTO tourneys (name, wins, best, size)
VALUES (‘Dolly’, ‘7’, ‘245’, ‘8.5’),
(‘Etta’, ‘4’, ‘283’, ‘9’),
(‘Irma’, ‘9’, ‘266’, ‘7’),
(‘Barbara’, ‘2’, ‘197’, ‘7.5’),
(‘Gladys’, ’13’, ‘273’, ‘8’);

Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0

После этого создайте еще одну таблицу в той же базе данных. Ее можно использовать для хранения информации о любимых блюдах подруг на день рождения. Следующая команда создает таблицу dinners, где будут столбцы с именами подруг, их датой рождения (birthdate), их любимым блюдом (entree), гарниром (side) и десертом (dessert):

CREATE TABLE dinners (
name varchar(30),
birthdate date,
ntree varchar(30),
side varchar(30),
dessert varchar(30)
);

После запуска команда выведет:

Query OK, 0 rows affected (0.01 sec)

Теперь заполните таблицу данными:

INSERT INTO dinners (name, birthdate, entree, side, dessert)
VALUES (‘Dolly’, ‘1946-01-19’, ‘steak’, ‘salad’, ‘cake’),
(‘Etta’, ‘1938-01-25’, ‘chicken’, ‘fries’, ‘ice cream’),
(‘Irma’, ‘1941-02-18’, ‘tofu’, ‘fries’, ‘cake’),
(‘Barbara’, ‘1948-12-25’, ‘tofu’, ‘salad’, ‘ice cream’),
(‘Gladys’, ‘1944-05-28’, ‘steak’, ‘fries’, ‘ice cream’);
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0

Теперь у вас есть данные, на которых можно потренироваться.

Оператор SELECT

Как упоминалось в начале статьи, SQL-запросы почти всегда начинаются с оператора SELECT. SELECT в запросах указывает, какие столбцы из таблицы должны нужно вернуть в наборе результатов. Запросы также почти всегда включают оператор FROM, который используется для указания таблицы, к которой нужно обратиться.

В общем SQL-запросы следуют такому синтаксису:

SELECT column_to_select FROM table_to_select WHERE certain_conditions_apply;

Например, чтобы извлечь столбец name из таблицы dinners, нужен такой запрос:

SELECT name FROM dinners;
+———+
| name |
+———+
| Dolly |
| Etta |
| Irma |
| Barbara |
| Gladys |
+———+
5 rows in set (0.00 sec)

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


SELECT name, birthdate FROM dinners;
+———+————+
| name | birthdate |
+———+————+
| Dolly | 1946-01-19 |
| Etta | 1938-01-25 |
| Irma | 1941-02-18 |
| Barbara | 1948-12-25 |
| Gladys | 1944-05-28 |
+———+————+
5 rows in set (0.00 sec)

Вместо того чтобы называть конкретный столбец или набор столбцов, вы можете использовать оператор SELECT со звездочкой (*) – она служит заполнителем, представляющим все столбцы в таблице. Следующая команда отобразит все столбцы таблицы tourneys:

SELECT * FROM tourneys;
+———+——+——+——+
| name | wins | best | size |
+———+——+——+——+
| Dolly | 7 | 245 | 8.5 |
| Etta | 4 | 283 | 9 |
| Irma | 9 | 266 | 7 |
| Barbara | 2 | 197 | 7.5 |
| Gladys | 13 | 273 | 8 |
+———+——+——+——+
5 rows in set (0.00 sec)

WHERE используется в запросах для фильтрации записей, которые удовлетворяют указанному условию. Все строки, которые не удовлетворяют этому условию, исключаются из результата. Оператор WHERE обычно использует следующий синтаксис:

. . . WHERE column_name comparison_operator value

Оператор сравнения в выражении WHERE определяет способ сравнения указанного столбца со значением. Вот некоторые распространенные операторы сравнения SQL:

Оператор Действие
= Равно
!= Не равно
Больше, чем
= Больше или равно
BETWEEN проверяет, находится ли значение в заданном диапазоне
IN проверяет, содержится ли значение строки в наборе указанных значений
EXISTS проверяет, существуют ли строки при заданных условиях
LIKE проверяет, соответствует ли значение указанной строке
IS NULL Проверяет значения NULL
IS NOT NULL Проверяет все значения, кроме NULL

Например, если вы хотите узнать размер обуви Ирмы, вы можете использовать следующий запрос:

SELECT size FROM tourneys WHERE name = ‘Irma’;
+——+
| size |
+——+
| 7 |
+——+
1 row in set (0.00 sec)

SQL позволяет использовать подстановочных знаков, и это особенно удобно при работе с выражениями WHERE. Знак процента (%) представляют ноль или более неизвестных символов, а подчеркивания (_) представляют один неизвестный символ. Они полезны, если вы пытаетесь найти конкретную запись в таблице, но не знаете точно, что это за запись. Чтобы проиллюстрировать это, предположим, что вы забыли любимое блюдо нескольких своих подруг, но вы уверены, что это блюдо начинается на t. Вы можете найти его название с помощью запроса:

SELECT entree FROM dinners WHERE entree LIKE ‘t%’;
+———+
| entree |
+———+
| tofu |
| tofu |
+———+
2 rows in set (0.00 sec)

Исходя из вышеприведенного вывода, это tofu.

Иногда приходится работать с базами данных, в которых есть столбцы или таблицы с относительно длинными или трудно читаемыми названиями. В этих случаях вы можете сделать эти имена более читабельными, создав псевдонимы – для этого есть ключевое слово AS. Псевдонимы, созданные с помощью AS, являются временными (они существуют только на время запроса, для которого они созданы):

SELECT name AS n, birthdate AS b, dessert AS d FROM dinners;
+———+————+————+
| n | b | d |
+———+————+————+
| Dolly | 1946-01-19 | cake |
| Etta | 1938-01-25 | ice cream |
| Irma | 1941-02-18 | cake |
| Barbara | 1948-12-25 | ice cream |
| Gladys | 1944-05-28 | ice cream |
+———+————+————+
5 rows in set (0.00 sec)

Как видите, теперь SQL отображает столбец name как n, столбец birthdate как b и dessert как d.

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

Агрегатные функции

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

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

SELECT COUNT(entree) FROM dinners WHERE entree = ‘tofu’;
+—————+
| COUNT(entree) |
+—————+
| 2 |
+—————+
1 row in set (0.00 sec)

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

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

Обратите внимание, функции AVG и SUM работают правильно только с числовыми данными. Если вы попытаетесь использовать их для нечисловых данных, это приведет к ошибке или к 0, в зависимости от того, какую СУБД вы используете.

SELECT SUM(entree) FROM dinners;
+————-+
| SUM(entree) |
+————-+
| 0 |
+————-+
1 row in set, 5 warnings (0.00 sec)

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

Точно так же используется MAX – только эта функция ищет наибольшее числовое значение в данном столбце. Следующий запрос покажет лучший результат в турнирах за все годы:

В отличие от SUM и AVG, функции MIN и MAX могут использоваться как для числовых, так и для буквенных типов данных. При запуске в столбце со строковыми значениями функция MIN отображает первое значение в алфавитном порядке:

SELECT MIN(name) FROM dinners;
+————+
| MIN(name) |
+————+
| Barbara |
+————+
1 row in set (0.00 sec)

Аналогично MAX покажет последнее значение в алфавитном порядке:

Агрегатные функции широко применяются в СУБД. Они особенно полезны в выражениях GROUP BY, которые мы рассмотрим в следующем разделе вместе с несколькими другими операторами сортировки наборов результатов.

Управление выводом запроса

В дополнение к FROM и WHERE есть несколько других операторов, которые используются для управления результатами запроса SELECT. В этом разделе мы объясним некоторые из наиболее часто используемых операторов и рассмотрим их на примерах.

Одним из наиболее часто используемых операторов, кроме FROM и WHERE, является GROUP BY. Обычно он используется, когда вы выполняете агрегатную функцию для одного столбца, но в отношении сопоставления значений в другом.

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

SELECT COUNT(name), entree FROM dinners GROUP BY entree;
+————-+———+
| COUNT(name) | entree |
+————-+———+
| 1 | chicken |
| 2 | steak |
| 2 | tofu |
+————-+———+
3 rows in set (0.00 sec)

Оператор ORDER BY используется для сортировки результатов запроса. По умолчанию числовые значения сортируются в порядке возрастания, а текстовые значения сортируются в алфавитном порядке. Для примера в следующем запросе перечислены имена и даты рождения, результаты отсортированы по дате рождения:

SELECT name, birthdate FROM dinners ORDER BY birthdate;
+———+————+
| name | birthdate |
+———+————+
| Etta | 1938-01-25 |
| Irma | 1941-02-18 |
| Gladys | 1944-05-28 |
| Dolly | 1946-01-19 |
| Barbara | 1948-12-25 |
+———+————+
5 rows in set (0.00 sec)

По умолчанию ORDER BY сортирует результаты в порядке возрастания. Чтобы отсортировать их в обратном порядке, добавьте DESC:

SELECT name, birthdate FROM dinners ORDER BY birthdate DESC;
+———+————+
| name | birthdate |
+———+————+
| Barbara | 1948-12-25 |
| Dolly | 1946-01-19 |
| Gladys | 1944-05-28 |
| Irma | 1941-02-18 |
| Etta | 1938-01-25 |
+———+————+
5 rows in set (0.00 sec)

Как упоминалось ранее, WHERE используется для фильтрации результатов на основе определенных условий. Однако если вы используете WHERE с агрегатной функцией, он вернет ошибку. Для примера попробуем выяснить, какой гарнир нравится как минимум трем подругам:

SELECT COUNT(name), side FROM dinners WHERE COUNT(name) >= 3;
ERROR 1111 (HY000): Invalid use of group function

Оператор HAVING добавлен в SQL для выполнения функций, аналогичных WHERE, но совместимых с агрегатными функциями. Разница между этими двумя операторами в том, что WHERE применяется к отдельным записям, а HAVING – к групповым. Для этого при каждом выполнении HAVING также должен присутствовать оператор GROUP BY.

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

SELECT COUNT(name), side FROM dinners GROUP BY side HAVING COUNT(name) >= 3;
+————-+——-+
| COUNT(name) | side |
+————-+——-+
| 3 | fries |
+————-+——-+
1 row in set (0.00 sec)

Агрегатные функции полезны для суммирования результатов определенного столбца в данной таблице. Однако во многих случаях необходимо запросить содержимое сразу нескольких таблиц. Мы рассмотрим несколько способов сделать это в следующем разделе.

Запрос данных из нескольких таблиц

Чаще всего база данных содержит несколько таблиц, каждая из которых содержит разные наборы данных. SQL предоставляет несколько способов выполнения одного запроса для нескольких таблиц.

Оператор JOIN можно использовать для объединения строк из двух или более таблиц в результате запроса. Это достигается путем нахождения одинакового столбца между таблицами и соответствующей сортировки результатов в выходных данных.

Выражение SELECT с оператором JOIN, как правило, работает по такому синтаксису:

SELECT table1.column1, table2.column2
FROM table1
JOIN table2 ON table1.related_column=table2.related_column;

Обратите внимание, поскольку оператор JOIN сравнивает содержимое нескольких таблиц, в предыдущем выражении указывается, из какой таблицы нужно выбрать каждый столбец: сначала указывается название таблицы, а через точку – название столбца. Вы можете указать, из какой таблицы должен быть выбран столбец, хотя это не обязательно при выборе из одной таблицы. Давайте рассмотрим пример.

Представьте, что вы хотите купить каждой подруге пару ботинок для боулинга в качестве подарка на день рождения. Поскольку информация о датах рождения и размерах обуви хранится в разных таблицах, вы можете запросить обе таблицы по отдельности, а затем сравнить результаты для каждой из них. Однако с помощью предложения JOIN вы можете найти всю необходимую информацию в рамках одного запроса:

SELECT tourneys.name, tourneys.size, dinners.birthdate
FROM tourneys
JOIN dinners ON tourneys.name=dinners.name;
+———+——+————+
| name | size | birthdate |
+———+——+————+
| Dolly | 8.5 | 1946-01-19 |
| Etta | 9 | 1938-01-25 |
| Irma | 7 | 1941-02-18 |
| Barbara | 7.5 | 1948-12-25 |
| Gladys | 8 | 1944-05-28 |
+———+——+————+
5 rows in set (0.00 sec)

Оператор JOIN, используемый в этом примере без каких-либо других аргументов, является внутренним JOIN. Это означает, что он выбирает в обеих таблицах все записи, у которых есть общее значение (в данном случае – имя), и выводит их в наборе результатов, в то время как все остальные записи исключаются. Чтобы проиллюстрировать эту функцию, давайте добавим в каждую таблицу новые строки, у которых не будет общего значения:

INSERT INTO tourneys (name, wins, best, size)
VALUES (‘Bettye’, ‘0’, ‘193’, ‘9’);
INSERT INTO dinners (name, birthdate, entree, side, dessert)
VALUES (‘Lesley’, ‘1946-05-02’, ‘steak’, ‘salad’, ‘ice cream’);

А теперь повторите запрос:

SELECT tourneys.name, tourneys.size, dinners.birthdate
FROM tourneys
JOIN dinners ON tourneys.name=dinners.name;
+———+——+————+
| name | size | birthdate |
+———+——+————+
| Dolly | 8.5 | 1946-01-19 |
| Etta | 9 | 1938-01-25 |
| Irma | 7 | 1941-02-18 |
| Barbara | 7.5 | 1948-12-25 |
| Gladys | 8 | 1944-05-28 |
+———+——+————+
5 rows in set (0.00 sec)

Обратите внимание, что, поскольку в таблице tourneys нет записи для Lesley, а в таблице dinners нет записи для Bettye, эти записи отсутствуют в выходных данных.

Однако возможно вернуть все записи из одной из таблиц, используя внешнее соединение JOIN. Внешние JOIN записываются как LEFT JOIN и RIGHT JOIN.

Предложение LEFT JOIN возвращает все записи из левой таблицы и только совпадающие записи из правой таблицы. В контексте внешнего соединения левая таблица – это таблица, на которую ссылается FROM, а правая – любая другая таблица, на которую есть ссылка после оператора JOIN.

Выполните предыдущий запрос еще раз, но на этот раз используйте LEFT JOIN:

SELECT tourneys.name, tourneys.size, dinners.birthdate
FROM tourneys
LEFT JOIN dinners ON tourneys.name=dinners.name;

Эта команда выведет каждую запись из левой таблицы (в данном случае tourneys), даже если в правой таблице нет совпадающей записи. Каждый раз, когда в правой таблице нет подходящей записи, она возвращается как пустое значение или NULL, в зависимости от СУБД.

+———+——+————+
| name | size | birthdate |
+———+——+————+
| Dolly | 8.5 | 1946-01-19 |
| Etta | 9 | 1938-01-25 |
| Irma | 7 | 1941-02-18 |
| Barbara | 7.5 | 1948-12-25 |
| Gladys | 8 | 1944-05-28 |
| Bettye | 9 | NULL |
+———+——+————+
6 rows in set (0.00 sec)

Повторите запрос с оператором RIGHT JOIN:

SELECT tourneys.name, tourneys.size, dinners.birthdate
FROM tourneys
RIGHT JOIN dinners ON tourneys.name=dinners.name;

Это вернет все записи из правой таблицы (dinners). Поскольку дата рождения Лесли записана в правой таблице, но для нее нет соответствующей строки в левой таблице, в столбцах name и size в этой строке будут значения NULL:

+———+——+————+
| name | size | birthdate |
+———+——+————+
| Dolly | 8.5 | 1946-01-19 |
| Etta | 9 | 1938-01-25 |
| Irma | 7 | 1941-02-18 |
| Barbara | 7.5 | 1948-12-25 |
| Gladys | 8 | 1944-05-28 |
| NULL | NULL | 1946-05-02 |
+———+——+————+
6 rows in set (0.00 sec)

Обратите внимание, что левые и правые соединения могут быть записаны как LEFT OUTER JOIN или RIGHT OUTER JOIN, хотя OUTER и так подразумевается. Аналогично, INNER JOIN дает тот же результат, что и простой JOIN.

В качестве альтернативы JOIN для запроса записей из нескольких таблиц вы можете использовать оператор UNION.

Оператор UNION работает немного иначе, чем JOIN: вместо вывода результатов из нескольких таблиц в виде уникальных столбцов с помощью одного оператора SELECT он объединяет результаты двух операторов SELECT в один столбец.

Рассмотрим такой запрос:

SELECT name FROM tourneys UNION SELECT name FROM dinners;

Он удалит все дублируемые записи, так как это поведение UNION по умолчанию.

+———+
| name |
+———+
| Dolly |
| Etta |
| Irma |
| Barbara |
| Gladys |
| Bettye |
| Lesley |
+———+
7 rows in set (0.00 sec)

Чтобы вывести все записи, включая повторы, используйте UNION ALL.

SELECT name FROM tourneys UNION ALL SELECT name FROM dinners;
+———+
| name |
+———+
| Dolly |
| Etta |
| Irma |
| Barbara |
| Gladys |
| Bettye |
| Dolly |
| Etta |
| Irma |
| Barbara |
| Gladys |
| Lesley |
+———+
12 rows in set (0.00 sec)

Значения и количество столбцов в результате отражают имя и количество столбцов, запрошенных первым оператором SELECT. Обратите внимание, что при использовании UNION для запроса нескольких столбцов из более, чем одной таблицы каждый оператор SELECT должен запрашивать одинаковое количество столбцов, соответствующие столбцы должны иметь одинаковые типы данных, а также идти в одном порядке в каждом операторе SELECT. В следующем примере показано, что может произойти, если вы используете предложение UNION для двух операторов SELECT, которые запрашивают разное количество столбцов:

SELECT name FROM dinners UNION SELECT name, wins FROM tourneys;
ERROR 1222 (21000): The used SELECT statements have a different number of columns

Другой способ сделать запрос к нескольким таблицам – это подзапросы. Подзапросы (также называемые внутренними или вложенными запросами) – это запросы, заключенные в другой запрос. Они полезны в тех случаях, когда вы пытаетесь отфильтровать результаты запроса по сравнению с результатами отдельной агрегатной функции.

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

SELECT name, wins FROM tourneys
WHERE wins > (
SELECT wins FROM tourneys WHERE name = ‘Barbara’
);
+———+——+
| name | wins |
+———+——+
| Dolly | 7 |
| Etta | 4 |
| Irma | 9 |
| Gladys | 13 |
+———+——+
4 rows in set (0.00 sec)

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

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

SELECT name, size FROM tourneys AS t
WHERE wins > (
SELECT AVG(wins) FROM tourneys WHERE size = t.size
);

Чтобы обработать запрос, СУБД должна сначала собрать столбцы name и size из внешнего запроса. Затем она сравнивает каждую строку из этого набора результатов с результатами внутреннего запроса, который определяет среднее количество побед для людей с одинаковым размером обуви. Поскольку у вас есть только две подруги с одинаковым размером обуви, в наборе результатов получится только одна строка:

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

SELECT name, entree, side, dessert
FROM dinners
WHERE name = (SELECT name FROM tourneys
WHERE wins = (SELECT MAX(wins) FROM tourneys));
+———+———+——-+————+
| name | entree | side | dessert |
+———+———+——-+————+
| Gladys | steak | fries | ice cream |
+———+———+——-+————+
1 row in set (0.00 sec)

Обратите внимание: этот запрос не только содержит подзапрос, но также еще один подзапрос внутри него.


Заключение

Запросы являются одной из наиболее часто выполняемых задач в области управления базами данных. Существует ряд инструментов администрирования баз данных (таких как phpMyAdmin и pgAdmin), которые позволяют выполнять запросы и визуализировать результаты, но выдача операторов SELECT из командной строки по-прежнему является широко распространенным рабочим процессом, который также может предоставить вам больший контроль над своими данными.

Если вы новичок в SQL, мы рекомендуем вам ознакомиться с нашим мануалом Краткий справочник по управлению базой данных SQL и с официальной документацией MySQL. Кроме того, если вы хотите больше узнать о SQL и реляционных базах данных, вам могут быть интересны следующие мануалы:

Как составить mysql запрос?

Добрый день, требуется помощь по созданию sql запроса.
Суть:

В БД имеются 2 таблицы, с постами и аккаунтами.
Условно, структура таблицы с постами выглядит так:

Таблица с аккаунтами:

Требуется вывести список самых активных пользователей за неделю.
То есть, как я себе это представляю: нужно посчитать кол-во постов для каждого пользователя userid учитывая дату, то есть чтобы она была >CURRENT_TIMESTAMP() — 86400*7, потом уже вывести логины пользователей из таблицы users

Работа с БД MySQL

Приветствую. В последнее время у новичков, только начинающих изучать mysql и php стали возникать вопросы «Как работать с mysql в php» и вопросы об ошибках, в которых на самом деле четко и ясно описывается где и в чем ошибка. Я лично (да и не только я) не советую использовать расширение mysql для работы с БД MySQL — лучше использовать PDO (лучший вариант на мой взгляд) ну или хотя бы mysql i — mysql уже давно объявлена как устаревшая, и ее не убирают только из-за частого использования новичками. Я попробую немного раскрыть эту тему, чтобы вам было от чего отталкиваться.
Итак, начнем.

Коротко о главном. Расширение mysql уже давно считается устаревшим и не рекомендуется к использованию. На оффициальном сайте http://php.net уже давно грозятся убрать это расширение. Этого до сих пор еще не сделали только по той причине, что многие его до сих пор используют. Я рекомендую использовать для работы с БД MySQL расширение mysqli, или, что еще лучше на мой взгляд — PDO. Но до сих пор у многих возникают вопросы по поводу работы с базами данных через расширение mysql. Поэтому я решил несколько раскрыть основы работы в php и с расширением mysql, и с расширением mysql i

Для начала работы с mysql необходимо подключиться к этому самому серверу БД MySQL. Делается это следующей командой:

где соответственно host — имя хоста (по умолчанию localhost ), user — имя пользователя (по умолчанию root ) и pass — пароль (по умолчанию пустая строка — » ).

Выбор базы данных для работы
Далее необходимо выбрать собственно саму базу, с которой мы будем работать, это делается функцией

Где мы указываем нашу базу соответственно.

Далее, для правильной кодировки при работе с данными — чтобы не выводились «кракозябры» вместо русских букв нужно установить кодировку для соединения и работы:
В старых версиях mysql (если память не изменяет, до MySQL 5.0) вместо этого писалось

я советую использовать кодировку utf8 (collation-сравнение в базе выбирать utf8_general_ci).

Внимание, важный момент! Все скрипты, таблицы, и сама база должны быть в одной кодировке.
Иначе вы получите головную боль при использовании русских символов!

Идем дальше. Мы соединились с сервером, выбрали базу данных для работы, установили нужную нам кодировку.
Теперь нам необходимо произвести необходимые нам в данном случае операции с данными, которые у нас хранятся в нашей базе данных.
Запросы выполяются с помощью функции mysql_query():

Основные и самые часто используемые запросы — это SELECT (выбор), INSERT (вставка) и UPDATE (обновление). Теперь несколько подробнее разберем каждый.

допустим, у нас есть таблица фрукты (fruit). Выберем все записи из этой таблицы. SQL-запрос будет выглядеть так:

И по аналогии AND

Также существует возможность использовать лимит (предел). Ключевое слово — LIMIT. После него ставятся либо одна цифра, либо две через запятую. Разберем каждый вариант.
1. Одна цифра:

— выберет записи с 5 по 15 включительно.

Идем далее. INSERT (вставка данных). Существует два варианта записи, мы разберем только один:

Ну больше тут особо нечего рассказать, идем дальше.

UPDATE (обновление данных).

Дословно: «ОБНОВИТЬ ` имя_таблицы ` УСТАНОВИТЬ `поле1`=’ значение1 ‘,`поле2`=’ значение2 ‘,`поле3`=’ значение3 ‘»
Но! Мы не указали критерий какую именно запись(строку) обновлять. И в результате у нас обновятся ВСЕ записи в таблице.
Нужно указать критерий, используя уже знакомое ключевое слово WHERE. Думаю, с этим проблем не должно возникнуть, не будем останавливаться на этом и перейдем собственно, к самому php.

Итак, как же все таки работать в PHP с БД MySQL? Давайте разберем с вами это на примерах

как я уже говорил, запросы выполняются с помощью функции mysql_query(). То есть выглядит это так:

Разберем чуть подробнее саму функцию mysql_query() и что она возвращает.
Вы спросите, зачем я писал $link после запроса. Это указатель на нужное соединение. Он не обязательный, если его не указать, то функция будет пытаться использовать последнее открытое соединение.

Теперь о возвращаемых значениях. Для запросов SELECT, SHOW, EXPLAIN и DESCRIBE функция возвращает указатель на результат запроса при успехе, при неудаче — возвращает FALSE. Для всех остальных запросов (INSERT,UPDATE, и т.д.) функция возвращает TRUE в случае успеха и FALSE в случае ошибки.

Для вывода полученных данных при запросе SELECT, SHOW, EXPLAIN или DESCRIBE необходимо обработать этот самый указатель
для этого используют fetch-функции. Две самые распространенные из них — это mysql_fetch_assoc() и mysql_fetch_array().
Первая возвращает ассоциативный массив, вторая несколько массивов сразу (если не нужны числовые индексы и т.п., то рекомендую использовать первую).

mysql_fetch_array() по умолчанию возвращает несколько массивов сразу, как числовой, так и ассоциативный. Можно указать какой именно нужен
всего есть три типа:

MYSQL_NUM возвращается массив с числовыми индексами
MYSQL_ASSOC возвращается ассоциативный массив (со строковыми индексами)
MYSQL_BOTH возвращаются оба массива — по умолчанию

Если у нас результат запроса указывает только на одну запись, то достаточно просто

и здесь на каждой итерации цикла (на каждом новом проходе цикла) переменной $row будет присваиваться массив с новыми значениями.

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

Теперь немного поговорим по поводу ошибок. Вспомним, что возвращает в случае неудачи mysql_query() и подойдем к, наверное, самой распространенной ошибке. Выглядит она так:

Часть 6. Специализированные формы запросов

Серия контента:

Этот контент является частью # из серии # статей: Практическое использование MySQL++

Этот контент является частью серии: Практическое использование MySQL++

Следите за выходом новых статей этой серии.

Запросы с параметрами или шаблоны запросов (template queries) представляют особый интерес в тех случаях, когда приходится выполнять множество почти одинаковых по форме команд SQL, отличающихся лишь фактическими параметрами в условиях отбора данных. С них мы и начнём, а затем рассмотрим некоторые другие специализированные запросы: команды создания таблиц в базе данных и процедуры извлечения, добавления и изменения данных при помощи специализированных структур SSQLS (Specialized SQL Structures).

1. Параметризованные запросы

Библиотека MySQL++ предоставляет возможность формирования и использования так называемых шаблонов запросов (template queries), то есть, запросов, в которых конкретные элементы условий выбора строк данных из таблиц заменены формальными параметрами. Можно провести некоторую аналогию с форматом функции printf(), широко применяемой в языке программирования C: вы передаёте MySQL++ строку, содержащую постоянные части запроса и форматные шаблоны (placeholdres) для переменных элементов, которые впоследствии будут заменяться соответствующими значениями.

1.1. Пример формирования и использования шаблона запроса

Снова обратимся к таблице товаров wares, с которой мы работали в предыдущих статьях. Её структура остаётся неизменной:

Рассмотрим следующий код, в котором демонстрируется практическое применение шаблона запроса с параметрами:

Принцип использования шаблона запроса прост: сначала формируется строка запроса, содержащая формальные параметры, затем с помощью функции parse() этот шаблон запроса активизируется. После этого вы можете многократно обращаться к данному шаблону, вызывая любой метод класса Query и передавая в него требуемые параметры. В данном примере применялся метод Query::execute().

1.2. Настройка элементов шаблона запроса

Как было показано в приведённом выше примере, при формировании строки шаблона запроса в объекте типа Query используются пронумерованные элементы шаблона, размещаемые в тех позициях строки, где в дальнейшем будут выполняться подстановки фактических параметров. Вызываемая после создания шаблона функция parse() сообщает Query-объекту о том, что переданная ему строка является шаблоном и требует соответствующей обработки:

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

Обязательными являются только символ % (процент) и номер элемента NNN (может содержать до трёх цифр). Нумерация элементов начинается с нуля. Порядок следования параметров передаётся в объект SQLQueryParms.

  • % — собственно символ «процент»;
  • «» — не заключать в кавычки и не экранировать содержимое фактического параметра;
  • q — выполнять экранирование спец.символов фактического параметра с помощью MySQL C API-функции mysql_escape_string() и заключить фактический параметр в одиночные кавычки, если это необходимо, в зависимости от типа используемого значения;
  • Q — Заключить содержимое фактического параметра в кавычки, но не выполнять экранирование. Иногда это позволяет сэкономить немного времени на обработку, если точно известно, что строка не содержит символов, требующих экранирования.

Для любого элемента можно определить «:имя», которое будет использоваться в объекте SQLQueryParms. Имя может содержать алфавитно-цифровые символы и символ подчёркивания. Для того, чтобы явно обозначить окончание имени, можно использовать необязательный символ «двоеточие» (например, «%2:field1:»). Если после имени должно располагаться двоеточие, то необходимо записать два «хвостовых» двоеточия подряд — «%3:field2::». В этом случае первое «хвостовое» двоеточие будет интерпретировано, как окончание имени, а второе останется «как есть», без изменений.

1.3. Передача фактических параметров во время выполнения

Для того, чтобы передать фактические значения параметров для подстановки их в строку запроса, необходимо вызвать метод Query::store( const SQLString &parameter0 [, . const SQLString &parameterN] ). Кроме того, соответствующим образом перегружаемыми являются и другие методы выполнения запросов Query::storein(), Query::use() и Query::execute(). В списке аргументов parameter0 соответствует первому передаваемому фактическому параметру и т.д. Всего можно задать до 25 передаваемых параметров. Для определённого в предыдущем подразделе шаблона запроса передача фактических значений параметров может выглядеть следующим образом:

после чего строка запроса должна принять такой вид:

У читателя может возникнуть вопрос: почему в строке шаблона запроса так нелогично пронумерованы формальные параметры — не в порядке их естественного следования? Ответ — в следующем подразделе.

1.4. Значения параметров, принимаемые по умолчанию

Механизм формирования шаблонов запросов позволяет определять значения параметров по умолчанию. Значение, устанавливаемое по умолчанию, присваивается элементу массива Query::template_defaults с соответствующим индексом. Вы можете выполнять присваивание, обращаясь с нужному элементу по его номеру (позиции) или по имени (если оно было определено в шаблоне запроса), например:

или (с тем же результатом)

Здесь обнаруживается большое сходство с механизмом определения параметров по умолчанию в функциях языка C++: если параметры с присвоенными им значениями по умолчанию расположены в конце списка, то при вызове методов выполнения запросов класса Query не обязательно явно указывать все передаваемые значения. Если запрос принимает четыре параметра, а для двух последних (по порядку номеров) вы установили значения по умолчанию, то при вызове метода выполнения запроса в него могут быть переданы как минимум два явных фактических параметра.

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

В результате для res1 запрос будет выглядеть так:

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

2. Создание таблиц БД

Здесь мы приступаем к рассмотрению специализированных структур SSQLS (Specialized SQL Structures), которые позволяют определять структуры языка C++, соответствующие формату SQL-таблиц. Любая SSQLS-структура содержит члены-переменные, соответствующие отдельным полям SQL-таблицы. Но кроме этого в подобной структуре имеются методы, операторы и члены-данные, используемые для обеспечения внутренней функциональности MySQL++.

SSQLS-структуры создаются при помощи макросов, определённых в файле ssqls.h. Это специализированный заголовочный файл библиотеки MySQL++, который не включается автоматически через заголовочный файл mysql++.h. Если вы хотите воспользоваться функциональными возможностями SSQLS-структур, то должны явно включить файл ssqls.h в свой исходный код.

2.1. Процедура создания таблицы базы данных

Если для создания таблицы требуется выполнение запроса:

то в терминах языка C++ соответствующая структура может быть определена следующим образом (разумеется, при условии использования библиотеки MySQL++):

Эта макрокоманда объявляет структуру wares, в которой содержатся имена всех полей SQL-таблицы с указанием соответствующего типа данных. В библиотеке MySQL++ определены C++-типы практически для всех MySQL-типов данных в форме sql_*.

Обобщённый синтаксис макрокоманды для создания SSQLS-структуры выглядит так:

Здесь N — количество полей в таблице и соответственно количество членов-переменных структуры, «имя» — имя структуры (имя таблицы), «тип#» — тип данных члена-переменной, а «поле#» — имя этого члена-переменной (совпадает с именем поля таблицы).

Второй и третий параметры требуют дополнительных разъяснений. Макрокоманда sql_create_N добавляет члены-функции и операторы в каждую SSQLS-структуру, чтобы обеспечить сравнение одного экземпляра такой структуры с другим. Эти функции сравнивают первые «comp_count» полей (членов-переменных) в данной структуре. В нашем примере создания структуры wares значение comp_count равно 1, поэтому при сравнении двух структур типа wares будут сравниваться значения только одного поля name.

Это свойство наиболее эффективно, когда ключевые поля таблицы занимают первые позиции в струкуре SSQLS, а значение параметра comp_count равно количеству этих ключевых полей.

Значение comp_count не должно быть меньше 1. Это требование текущей реализации SSQLS-структур в библиотеке MySQL++.

К SSQLS-структуре, например, к объявленной выше структуре wares можно применять алгоритмы стандартной библиотеки STL и методы стандартных контейнеров:

Этот фрагмент кода выводит самое первое найденное наименование товара в наборе результатов, которое начинается с цепочки символов «Стол».

Третий параметр макрокоманды sql_create_N — числовое значение set_count. Если оно не равно нулю, то в структуру добавляется член-метод set() для установки значений того количества полей этой структуры, которое соответствует значению set_count. Так например, в рассматриваемой нами структуре метод set() будет выполнять установку значений всех трёх полей: name, num и price.

3. Извлечение, добавление и модификация данных

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

3.1. Извлечение данных

Разумеется, для извлечения данных из таблицы мы будем использовать SSQLS-структуру.

Обратите внимание на использование контейнера vector из стандартной библиотеки для хранения результатов запроса.

3.2. Добавление данных в таблицу

3.3. Изменение существующих данных

Операция редактирования любого поля данных выполняется почти так же просто, как и добавление строк данных.

4. Заключение

Итак, мы убедились, что с помощью библиотеки MySQL++ можно без затруднений формировать шаблоны запросов с подставляемыми параметрами и многократно использовать эти шаблоны в исходном коде приложения, а специальные структуры SSQLS (Specialized SQL Structures) являются удобным инструментом во многих случаях, когда требуется извлечение, добавление и модификация данных в таблицах.

В данной статье рассматривались специализированные формы запросов. В заключительной, седьмой статье цикла будет продемонстрировано практическое применение библиотеки MySQL++ в многопоточных приложениях.

Цукерберг рекомендует:  Sql mssql - MSSQL Запрос
Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих