Практическая работа №1 Создание таблиц базы данных и их заполнение. 1. Создаем таблицу Доставка со следующими параметрами Где поле КодДоставки является ключевым,а поле Название является обязательным для заполнения. 2. Создаем таблицу Заказано 1 Ключевое поле КодТовара с параметрами: В строке «Источник строк» вводим запрос: SELECT КодТовара, Марка FROM Товары ORDER BY [Марка]; Это значит, что мы выбираем для подстановки в поле КодЗаказа таблицы Заказано поля КодТовара и Марка из таблицы Товары и сортируем по полю Марка. Для задания двух ключей нажимаем на кнопку «Индексы» и задаем их как показано на рисунке: 2 Поле Цена с параметрами: Поле Количество с параметрами: Поле Скидка: 3 3. Создаем таблицу Клиенты Поле Название: Поле Должность: 4 Поле Адрес: Поле Индекс: Поле Город: Поле Страна: Аналогично делаем поля Телефон и Факс. 4. Создаем таблицу Поставщики 5 Поле Название: Поля Должность, Адрес, Город, Страна, Телефон, Факс по аналогии с предыдущими таблицами. Поле Индекс: Поле ДомашняяСтраница 5. Создаем таблицу Товары 6 Поле Марка: Поле КодПоставщика: В поле КодПоставщика в Источнике строк вводим: SELECT КодПоставщика, Название FROM Поставщики ORDER BY [Название]; Что значит: для подстановки в поле КодПоставщика таблицы Товары выбираем поля КодПоставщика и Название из таблицы Поставщики и сортируем по полю Название. Поле ЕдиницаИзмерения: Поле Цена: 7 Поле НаСкладе: Поле Ожидается Поле МинимальныйЗапас: Поле ПоставкиПрекращены: 6. Создаем таблицу Заказы 8 Поле КодКлиента: В источнике строк запрос: SELECT КодКлиента, Название FROM Клиенты ORDER BY [Название]; Это значит, что мы выбираем для подстановки в поле КодКлиента таблицы Заказы поля КодКлиента и Название из таблицы Клиенты, сортируя по полю Название. Поле КодСотрудника: 9 Запрос: SELECT Сотрудники.КодСотрудника, [Фамилия] & ", " & [Имя] AS ФИО FROM Сотрудники ORDER BY Сотрудники.Фамилия, Сотрудники.Имя; Что значит: для постановки в поле КодСотрудника таблицы Заказы выбираем поля КодСотрудника, Фамилия, Имя из таблицы Сотрудники и представляем данные из Фамилия и Имя в одном поле ФИО через запятую как единый объект и сортируем по фамилии и имени таблицы Сотрудники. Поле ДатаРазмещения Поле ДатаНазначения ДатаИсполнения аналогична полю ДатаНазначения. 10 Поле Доставка: В источнике строк вводим запрос: SELECT КодДоставки, Название FROM Доставка ORDER BY [Название]; Это значит: для подстановки в поле Доставка таблицы Заказы выбираем поля КодДоставки и Название из таблицы Доставка и сортируем по полю Название. Поле СтоимостьДоставки: Остальные поля НазваниеПолучателя, АдресПолучателя, ГородПолучателя, ИндексПолучателя (допускаются совпадения), СтранаПолучателя делаются по умолчанию. 11 7. Создаем таблицу Сотрудники Поле ДатаРождения: Остальные поля стандартны, но не забудьте их подписывать. 8. Создаем логические связи между полями таблиц как показано на схеме: 12 Для этого в верхнем меню выбираем пункт Связи – Изменить связь. Или просто перетаскиваем нужное поле одной таблицы на другое, с которым хотите соединить. Далее выбираем Новое (только если вы образуете связь через меню) и выбором левой и правой таблиц и ключевых полей устанавливаем логические связи между таблицами. 13 На рисунке показана созданная с помощью перетаскивания мыши связь между полями КодКлиента таблиц Клиенты и Заказы: 9. Заполняем таблицы базы данных Из-за их связанности таблицы нужно заполнять не в любом порядке, а следующем: 1.Доставка 2. Клиенты 3. Сотрудники 4. Поставщики 5. Товары 6. Заказы 7. Заказано (Код товара должен соответствовать коду этого же товара в т. Товары) Таблица Доставка: 14 Таблица Заказано: Таблица Клиенты: Продолжение таблицы 15 Таблица Поставщики: Таблица Товары: 16 Таблица Заказы: Таблица Сотрудники: 17 Практическая работа № 2 Работа с диаграммами и формами ФОРМЫ Существует три способа ввода информации в Access: посредством таблицы, с помощью формы и с использованием страницы доступа к данным. Выбрать тот или иной способ можно, основываясь на следующем простом правиле. Если данные в таблице изменяются редко или в нее редко добавляются новые записи, то для ввода, изменения и индикации данных следует использовать таблицу. Кроме того, режим таблицы рекомендуется использовать тогда, когда необходимо получить наиболее полный обзор данных. Но если данные часто меняются или база постоянно пополняется новыми записями, следует пользоваться формой, так как в режиме формы можно сконцентрировать внимание на данных, относящихся к определенной записи, например к определенному клиенту. Страницы доступа к данным представляют специальный тип веб-страниц, предназначенный для просмотра и работы через Интернет или интрасеть с данными, хранящимися в БД Microsoft Access. Использование страниц доступа к данным для ввода данных аналогично использованию форм ввода данных: пользователь имеет возможность просматривать, вводить, редактировать и удалять данные в БД. Однако страницу можно использовать за пределами БД Microsoft Access, предоставляя пользователям возможность обновлять или просматривать данные через Интернет или Интранет. Страницы доступа к данным разрабатываются в режиме конструктора в Microsoft Access. Страница представляет собой отдельный файл, хранящийся за пределами Access; однако при создании этого файла Microsoft Access автоматически добавляет ярлык к нему в окно БД. Любая форма строится на основе Access-таблицы. Вся информация формы содержится в управляющих элементах (полях) этой формы, некоторые из них напрямую связаны с полями базовой таблицы. В таких элементах можно показать содержимое соответствующих полей таблицы и внести в них изменения. Другие элементы формы служат для оформления, например надписи, позволяющие обозначить те или иные объекты в форме, линии и прямоугольники, чтобы структурировать форму и обозначить группы данных. Access позволяет создавать 6 основных типов форм. В один столбец. Значения полей каждой записи отображаются в одной колонке друг под другом. Каждое поле располагается в собственной строке. Ленточная. Значения полей каждой записи отображаются в одной строке. Количество строк соответствует количеству записей. Составная форма. Составная форма удобна при работе со связанными таблицами. Данные главной формы (взятые из родительской таблицы) будут представлены в отдельной области; данные подчиненной формы (взятые из дочерней таблицы) отобразятся в форме таблицы. Для каждой записи главной формы в подчиненной форме появляется одна или несколько записей. Табличная форма. Табличная форма по внешнему виду не отличается от самой таблицы. Данные размещаются в ней в строках и столбцах. Одновременно индицируются несколько записей. Поля наименований служат в качестве заголовков столбцов; каждая запись располагается в отдельной строке. Сводная таблица и сводная диаграмма. 18 В Microsoft Access имеется возможность многие объекты, в том диаграммы. Используя эти возможности, можно представлять данные в компактной и удобной для анализа и понимания форме. Кроме вышеперечисленных форм, следует выделить диаграммную форму, которая содержит диаграмму и может встраиваться в другие формы и отчеты. Форму можно подготовить автоматически (с помощью команды Автоформа), автоматизированным способом (с помощью мастера форм) или «вручную» (используя инструментальные средства конструктора форм). Автоформа позволяет быстро получить простую форму, что не всегда устраивает пользователя. Мастер форм ускоряет и облегчает процесс создания форм (для каждого типа форм имеется свой мастер форм), так как выполняет за пользователя большую часть основной проектной работы. Проектирование диаграммной формы Для начала создадим диаграммную форму. Грамотно спроектированная иллюстрация или диаграмма зачастую говорит больше, чем сотня слов и тысяча голых цифр. Чтобы приступить к проектированию формы, щелкните в окне БД на закладке Формы, затем на кнопке Создать. Access откроет диалоговое окно создания формы: В этом диалоговом окне следует выбрать таблицу, на которой будет базироваться диаграммная форма. Откройте список и выделите таблицу Заказы. Далее выберите строку Диаграмма и щелкните на кнопке ОК. Если в форме должны появиться все поля таблицы, следует просто выполнить щелчок на кнопке с двойной стрелкой (>>), которая находится между списками полей, и Access будет использовать в форме все поля в той же последовательности, в которой они были определены при проектировании таблицы. Если в форму необходимо включить не все, а только некоторые (избранные) поля, то каждое такое поле следует выделить в левом списке с последующим нажатием кнопки переноса (>). При этом необходимо соблюдать порядок выделения, он должен соответствовать требуемому порядку включения полей в форму. Если поле было внесено в форму по ошибке, то для удаления из формы его достаточно выделения в правом списке и выполнить щелчок на кнопке со стрелкой влево (<). 19 В качестве примера выберем два поля из таблицы: СтоимостьДоставки и СтранаПолучателя. Так мы увидим зависимость стоимости доставки товара от страны, в которую он доставляется. Выбираем наиболее удобный вид диаграммы. (Круговая) 20 Типы диаграмм Теперь разберем какие бывают диаграммы. Круговая диаграмма относится к одномерным и позволяет отображать только один числовой ряд (в преобразованном виде). Круговая диаграмма наиболее наглядно показывает «части пирога». Она лучше всего подходит для представления частей целого, например распределения оборота по категориям товара, распределения клиентов по месту жительства, распределения голосов между кандидатами на выборах и т. д. Точечная диаграмма позволяет наглядно отобразить последовательности измеренных (рассчитанных) величин. По точкам измерения (расчета) можно сделать некоторые выводы о характере изменения отдельных величин и их взаимосвязи. С помощью ленточной диаграммы удобно демонстрировать динамику соотношений нескольких параметров, составляющих общую сводную величину, например соотношение объемов продаж пирожков, пончиков и бубликов по месяцам в течение года с общим объемом продаж. Линейная и столбиковая (гистограмма) диаграммы подходят для представления соотношений нескольких параметров в различные моменты времени и по различным категориям. Например, для представления дневной температуры, влажности и скорости ветра за месяц наблюдений или для представления цены, мощности двигателя и расхода горючего по определенным моделям автомобилей. Также существуют и другие типы диаграмм, на которых мы не будем останавливаться подробно. В итоге у нас должна получиться диаграмма следующего вида: Для дальнейшей работы нам нужно создать запрос на выборку на основе таблиц Заказано и Товары с помощью конструктора. Как делается запрос, мы проходили в четвертой работе. 21 Вид запроса. При выборе поля в запросе первое – имя таблицы, а через точку – название поля. Если стоит * - выбираются все поля таблицы. После создания запроса закройте его и сохраните под именем Сведения о заказах. Далее создадим Сводную таблицу на основе запроса Сведения о заказах. Выбираем вкладку Формы и нажимаем кнопку Создать. В меню выбираем Сводная таблица, в качестве источника данных – созданный запрос Сведения о заказах. После выбора полей появится макет таблицы, в который нужно добавить в определенном порядке все выбранные поля и посчитать суммы всех возможных полей. Сохраните сводную таблицу как Итоги заказов. 22 Практическая работа №3 Знакомство с MySQL Важно. В большинстве случаев все команды и запросы в командной строке и консоли MySQL не чувствительны к регистру и пробелу, так что не имеет значения заглавные буквы или нет вы вводите. При введении параметров (-u, -p, -P) регистр важен. Все, что указано в [ ] является необязательными параметрами и в тексте программы не используются. Знак | указывает на то, что в команде может быть использован лишь один из элементов слева или справа от нее. В тексте программы не используется. {} все, что стоит внутри фигурных скобок, рассматривается как один неделимый синтаксический элемент языка SQL. Могут быть использованы в тексте программы. () используются в том числе для указания размера полей данных, в формулах и условиях. Необходимы в тексте программы. […] все, что стоит перед этим – может использоваться многократно. Все элементы списка разделяются через запятую. 1. Соединение с сервером и вход пользователя. Запустите менеджер запросов MySQL Query Browser с рабочего стола. Перед вами откроется окно соединения. В нем: Stored Connection – сохраненные параметры соединения. Server Host и Port – адрес сервера (ip) где запущен MySQL сервер (localhost) и порт (3306) Username – имя пользователя, существующего на сервере. Password – пароль этого пользователя. Может быть пустым, если не задан. Default Schema – база данных по умолчанию, к которой подключится пользователь при соединении. (База данных в MySQL называется schema, а перечень БД- schemata) Общий вид команды соединения с сервером, если используется командная строка: shell> mysql [-h имя_сервера] [-u имя_пользователя] [-p] 23 где в квадратных скобках указаны необязательные парметры, причем сервер может задаваться как до имени пользователя, так и после. Кроме нескольких случаев, пробел не имеет значения для выполнения запросов и употребляется исключительно для удобства представления. Перед вами откроется окно программы: Область баз данных (Schemata) будет пустой, если вам не предоставлена привилегия SHOW DATABASES, о чем будет сообщено при загрузке программы. Небольшое поле ввода вверху окна – консоль, куда вводятся команды SQL, может быть расширена на весь экран. Кнопка Execute или сочетание CTRL+ENTER выполнит введенный запрос. Кнопка Explain, нажатая после выполнения запроса выведет внизу экрана объяснение ошибки, если таковая присутствует. Кнопка Compare позволяет сравнить два одинаковых результата запросов, если используются две разных версии одинаковых таблиц, например. В нижнем правом углу расположены четыре вкладки: Syntax – перечислены группы команд и команды по манипулированию данными, определению данных, утилиты MySQL, транзакции и блокирование. Functions – перечислены функции и операторы. Params – динамические параметры, включаемые в запрос. Trx (Transaction Browser) – в нем перечислены все запросы с начала транзакции. Чтобы объявить начало транзакции, нужно нажать кнопку Transaction. По двойному щелчку на любой команде/функции будет выдана онлайн-справка по синтаксису и использованию данного элемента. 2. Демонстрация представления таблиц в MySQL. Для демонстрации представления таблиц в MySQL введем простую команду, выводящую текущую дату и время: SELECT NOW(), Важно: все команды запросов в MySQL должны заканчиваться точкой с запятой , либо \g кроме запуска утилит и самого клиента. 24 Вот как будет выглядеть экран консоли при выводе таблицы из одного столбца и строки с текущей датой и временем: Обратите внимание на левый нижний угол экрана – там вы видите надпись: 1 row fetched in 0,0008 s. Она означает, что по запросу выбрана одна строка (row) за такое-то время. При выполнении запросов обращайте внимание на эти надписи. 3. Создание базы данных. В СУБД MySQL создание базы данных сводится к созданию подкаталога в каталоге, куда установлена программа, например: C:\MySQL\data. Создание БД средствами SQL осуществляется оператором CREATE DATABASE имя_базы, Пример: Mysql>CREATE DATABASE IF NOT EXISTS wet, Здесь конструкция IF NOT EXISTS служит для предотвращения выдачи ошибки, если база с таким именем уже существует. Создайте базу со своим именем (имя базы, таблицы, столбца может начинаться и содержать цифры, но не должно состоять только из цифр и должно содержать не более 64 символов). Переименовать базу можно только переименовав одноименную папку на сервере в директории Mysql\data но только при остановленном сервере. Также при создании базы данных можно указать кодировку, которая будет назначаться таблицам и столбцам по умолчанию. Для этого после имени базы данных следует указать ключевое слово DEFAULT CHARACTER SET charset_name, где последнее – имя кодировки (cp1251, utf8, koi8r, cp866). 6. Удаление базы данных. Удаление базы данных производится с помощью команды DROP DATABASE имя_базы, В команду можно добавить конструкцию IF EXISTS чтобы не выдавалась ошибка, что такой базы не существует. Удалите только что созданную БД. Пример: Mysql>DROP DATABASE IF EXISTS wet, Если у пользователя нет привилегии DROP на вашу БД, удалить вы ее не сможете. После предоставления привилегии удалите базу. 7. Создание таблиц. Создайте снова базу данных с названием в виде вашей фамилии в кодировке cp1251. Перед созданием таблицы, в клиентской программе нужно выбрать базу данных, с которой будет производиться работа. Выбор базы данных осуществляется командой USE имя_базы, Для создания таблицы используется оператор в общем виде: CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)] 25 [table_options] [select_statement] Создайте таблицу tbl в вашей БД командой: CREATE TABLE tbl (number INT, name TEXT), В круглых скобках через запятую указываются имена столбцов и их тип. Созданная таблица имеет два поля: number, куда можно помещать целочисленные значения (INT) и поле name, в котором размещаются строки (TEXT). Проконтролировать вновь созданную таблицу можно оператором SHOW TABLES, который возвращает список таблиц текущей БД. Для просмотра содержимого другой БД, ее сначала нужно выбрать оператором USE. 8. Удаление таблиц. Удаление таблиц производится оператором DROP TABLE таблица, Пример: DROP TABLE tbl, если у вас есть право удаления, вы выбрали текущую БД и в ней есть таблица с таким именем. 26 Практическая работа №4 Создание структуры базы данных shop В этой работе мы создадим базу данных компьютерного магазина. Она будет состоять из четырех таблиц: catalogs – список торговых групп, products – товары, users – список зарегистрированных пользователей магазина, orders – список осуществленных сделок. Таблица catalogs предназначена для хранения торговых групп, таких как «Материнские платы», «Процессоры», «Видеокарты» и т.п. Таблица состоит из двух полей: id_catalog – уникальный номер, name – имя раздела. Оба поля имеют атрибут NOT NULL, т.к. неопределенное значение для них недопустимо. Для начала создадим базу данных. Т.к. базы хранятся на сервере и не могут иметь одинаковое имя, создайте каждый свою базу с именами типа shop#, где # - номер компьютера. CREATE DATABASE shop1, Далее создадим таблицы для нашей базы данных: CREATE TABLE catalogs (id_catalog INT(11) NOT NULL, name TINYTEXT NOT NULL) , Для показа структуры таблицы введите оператор DESCRIBE таблица, Таблица products содержит конкретные товары, такие как «Celeron 2.0 GHz», «Intel Pentium 4 3.2 GHz» и т.п. Таблица состоит из семи полей: id_product – уникальный номер товара, name – название товара, price – цена, count – количество единиц товара на складе, mark – относительная оценка товара, description – описание товара, id_catalog – номер торговой группы из таблицы id_catalog, которой принадлежит товар. 27 CREATE TABLE products ( id_product INT(11) NOT NULL, name TINYTEXT NOT NULL, price DECIMAL(7,2) NULL default '0.00', count INT(11) NULL default '0', mark FLOAT(4,1) NOT NULL default '0.0', description TEXT NULL, id_catalog INT(11) NOT NULL ), Цена товара price, количество товара на складе count и описание description снабжены атрибутом NULL. Несмотря на то, что в момент привоза зачастую бывает неизвестно количество товара на складе и его текущая цена, отразить факт наличия товара в прайс-листе необходимо. Точно также и описание может быть неизвестно из-за того, что товар слишком новый и имеет противоречивое описание в источниках. Поле id_catalog устанавливает связь между таблицами catalog и products. Зная уникальный номер каталога id_catalog, всегда можно узнать, какие товары принадлежат данной товарной группе и наоборот. MySQL позволяет сделать это при помощи несложных SQL-запросов. Таблица users содержит записи с информацией о зарегистрированных покупателях и состоит из восьми полей: id_user – уникальный номер покупателя, surname – фамилия покупателя, patronymic – отчество покупателя, name – имя покупателя, phone – телефон покупателя (если есть), email – эл.почта покупателя (если есть), url – домашняя страница покупателя (если есть), userstatus – статус покупателя, поле типа ENUM, которое может принимать одно из четырех значений: 28 o active – авторизованный покупатель, который может осуществлять покупки через Интернет, o passive – неавторизованный покупатель (значение по умолчанию), который осуществил процедуру регистрации, но не подтвердил ее и пока не может покупать в магазине через Интернет, но ему доступны каталоги для просмотра, o lock – заблокированный покупатель, не может осуществлять покупки и просматривать каталоги магазина, o gold – активный покупатель с хорошей кредитной историей, которому предоставляется скидка при следующих покупках в магазине. CREATE TABLE users ( id_user INT (11) NOT NULL, surname TINYTEXT, patronymic TINYTEXT, name TINYTEXT, phone VARCHAR(12) NULL, email TINYTEXT NULL, url TINYTEXT NULL, userstatus ENUM ('active','passive','lock','gold') DEFAULT 'passive' ), Как видите, поля phone, email, url снабжены атрибутом NULL, т.к. посетитель имеет право не указывать эту информацию. Если эта информация не указана, то она носит неопределенный характер: телефона, е-мейла и домашней страницы у покупателя может просто не быть, с другой стороны, он мог не захотеть их указывать. Поэтому, чтобы указать неопределенность этой информации, в поле следует поместить значение NULL. Все остальные поля получают атрибут NOT NULL, даже если он не указывается. Таблица orders содержит информацию о покупках, совершенных в магазине и состоит из пяти полей: id_order – уникальный номер сделки, id_user – номер пользователя из таблицы users, 29 ordertime – время совершения покупки, number – число приобретенных товаров, id_product – номер товара из таблицы products. CREATE TABLE orders ( id_order INT(11) NOT NULL, id_user INT(11) NOT NULL, ordertime DATETIME NOT NULL, number INT(11) NOT NULL, id_product INT(11) NOT NULL ), Все столбцы таблицы orders снабжены атрибутом NOT NULL, т.к. при совершении покупки вся информация должна быть доступна и занесена в таблицу. В таблице orders устанавливается связь сразу с двумя таблицами: users – за счет поля id_user, и products – за счет поля id_product. Это позволит для каждой покупки восстановить покупателя и приобретенный товар. Также можно узнать число покупок, совершенных каждым из покупателей, а также частоту покупки того или иного товара, что позволит увеличить или уменьшить закупки товара и тем самым произвести оптимизацию работы магазина. Посмотрите наличие созданных таблиц командой SHOW TABLES, 30 Индексы играют большую роль в базах данных, т.к. это основной способ ускорения их работы. Обычно записи в таблице располагаются в хаотическом порядке. Для того, чтобы найти нужную запись, необходимо сканировать всю таблицу, на что уходит большое количество времени. Идея индексов состоит в том, чтобы создать для столбца копию, которая постоянно будет поддерживаться в отсортированном состоянии. Это позволяет очень быстро осуществлять поиск по такому столбцу, т.к. заранее известно где необходимо искать значение. 1 2 3 4 5 6 7 8 9 10 11 12 12 2 1 6 10 4 7 11 5 8 9 3 Show Hide Show Show Show Hide Hide Show Show Show Hide Hide 11 12 12 11 11 13 11 13 12 13 12 13 Но добавление и удаление записи требует дополнительного времени на сортировку столбца и создание копии увеличивает объем памяти, необходимый для размещения таблицы на жестком диске. Существует несколько видов индексов. Первичный ключ – главный индекс таблицы. В таблице может быть только один первичный ключ, и все значения такого индекса должны отличаться друг от друга, т.е. быть уникальными. Обычный индекс – таких индексов может быть несколько. Уникальный индекс – уникальных индексов также может быть несколько, но значения индекса не должны повторяться. Полнотекстовый индекс – специальный вид индекса для столбцов типа TEXT, позволяющий производить полнотекстовый поиск. Индексы могут иметь как свои собственные имена, так имена индексируемых столбцов. Один индекс может охватывать один или несколько столбцов, причем тип столбца может быть любым, за исключением ENUM и SET. Первичный ключ является главным индексом таблицы и объявляется оператором PRIMARY KEY. Его значения не могут быть NULL. Для пометки поля в качестве первичного ключа достаточно поместить это ключевое слово в определение столбца. Чтобы не создавать уже существующие таблицы заново, воспользуемся командой изменения таблицы ALTER TABLE. Зададим первичный ключ в таблице catalogs: ALTER TABLE catalogs ADD PRIMARY KEY (id_catalog), Или если бы вы ее создавали заново: CREATE TABLE catalogs ( id_catalog INT(11) NOT NULL PRIMARY KEY, AUTO_INCREMENT, name TINYTEXT NOT NULL ), 31 Смотрим, появился ли атрибут первичного ключа в таблице catalogs: DESCRIBE catalogs, В качестве первичного ключа часто выступает столбец типа INT или BIGINT. В данной БД все поля, начинающиеся с id_ предназначены для первичного ключа. Такой выбор связан с тем, что целочисленные типы данных обрабатываются быстрее всех и занимают небольшой объем данных. Другой причиной выбора целочисленного столбца является то, что только данный тип столбца может быть снабжен атрибутом AUTO_INCREMENT, который обеспечивает автоматическое создание уникального индекса. Передача столбцу, снабженному этим атрибутом, значения NULL или 0 приводит к автоматическому присвоению ему максимального значения столбца плюс один. В качестве значения по умолчанию для столбца id_catalog выставлено NULL, однако само поле не может принимать значение NULL. Если в таблице нет ни одного значения, то первое уникальное значение будет равным 1. Как и первичный ключ, AUTO_INCREMENT в таблице может быть только одним. Добавим атрибут auto_increment к столбцу id_catalog, используя оператор MODIFY , который является расширением стандарта SQL от ORACLE для команды ALTER TABLE. ALTER TABLE shop.catalogs MODIFY id_catalog INT NOT NULL AUTO_INCREMENT, Просмотрите таблицу оператором DESCRIBE catalogs, В отличие от первичного ключа, таблица может содержать несколько обычных и уникальных индексов. Для их различения, индексы могут иметь собственные имена. Объявление индекса производится оператором INDEX или KEY. Для уникальных индексов, которые не позволяют добавлять в таблицу записи с уже существующими значениями, вводится дополнительное ключевое слово UNIQUE, т.е. пишется UNIQUE INDEX и UNIQUE KEY. Создание обычных индексов, в отличие от первичного ключа и уникального индекса, допустимо для столбцов с атрибутом NULL. Зададим индексы для таблицы orders: ALTER TABLE `shop`.`orders` MODIFY `id_order` INT NOT NULL AUTO_INCREMENT, MODIFY `id_user` INT NOT NULL DEFAULT '0', MODIFY `ordertime` DATETIME NOT NULL DEFAULT '000-00-00 00:00:00', MODIFY `number` INT NOT NULL DEFAULT '0', MODIFY `id_product` INT NOT NULL DEFAULT '0', ADD PRIMARY KEY(`id_order`), ADD INDEX `id_product`(`id_product`, `id_user`), Просмотрим структуру таблицы оператором DESCRIBE и увидим: 32 Как видно, столбцы, проиндексированные обычным индексом, отмечаются в поле KEY флагом MUL. Заметим, что оператор DESCRIBE считает проиндексированным только поле id_product, хотя на самом индекс задан и полю id_user. Примеры операторов с индексами: CREATE INDEX id_catalog_index ON products (id_catalog), - создает индекс с именем id_catalog_index в таблице products. DROP INDEX id_catalog_index ON products, - удаляет индекс CREATE INDEX name ON catalogs (name(10)), - создание текстового индекса на 10 символах столбца name. Изменим структуру таблицы products следующим образом: ALTER TABLE products MODIFY id_product int(11) NOT NULL AUTO_INCREMENT, MODIFY `name` tinytext NOT NULL, MODIFY price decimal(7,2) default '0.00', MODIFY count int(11) default '0', MODIFY mark float(4,1) NOT NULL default '0.0', MODIFY description text, MODIFY id_catalog int(11) NOT NULL default '0', ADD PRIMARY KEY (id_product), ADD KEY id_catalog (id_catalog), Получим следующую окончательную структуру таблицы products: 33 Также изменим структуру таблицы users: ALTER TABLE shop.users MODIFY id_user INT NOT NULL AUTO_INCREMENT, MODIFY phone VARCHAR(12) DEFAULT NULL, ADD PRIMARY KEY(`id_user`), 34 Практическая работа №5 Добавление данных в таблицы БД shop#. Существует три подхода к операции добавления данных: однострочный оператор INSERT – добавляе в таблицу данных новую запись, многострочный оператор INSERT – добавляет в таблицу несколько новых записей, пакетная загрузка данных – служит для добавления в таблицу данных из внешнего файла. Однострочный оператор INSERT может использоваться в нескольких формах. Синтаксис первой формы: INSERT [INTO] tbl [(col_name, . . .)] VALUES (expression, . . .), Данный оператор вставляет новую запись в таблицу tbl. Expression – значения записи(константы и выражения). col_name – порядок следования столбцов. Values – значения. Просмотр данных, занесенных в таблицу catalogs возможен командой SELECT * FROM catalogs, Где звездочка обозначает все записи. Добавить новую запись в таблицу catalogs можно запросом: INSERT catalogs VALUES (1, 'Процессоры'), Просмотрим данные в таблице catalogs: Строковые значения нужно помещать в кавычки или апострофы, а числовые значения можно не помещать. Список столбцов col_name, размещенный после имени таблицы, позволяет изменить прядок следования столбцов при добавлении. Изменим порядок занесения в столбцы: INSERT catalogs (name, id_catalog) VALUES ('Материнские платы', 2), Как видно, порядок следования столбцов был изменен, сначала было добавлено название раздела name и лишь затем первичный ключ таблицы id_catalog. Добавление уже существующего значения первичного ключа приведет к ошибке. 35 При добавлении новой записи с уникальными индексами выбор уникального значения может быть непростой задачей. Чтобы не выполнять дополнительный запрос на выявление максимального значения первичного ключа для генерации нового уникального значения, в MySQL введен механизм его автоматической генерации. Для этого достаточно снабдить первичный ключ атрибутом AUTO_INCREMENT, тогда при создании новой записи в качестве уникального значения достаточно передать NULL или 0 – поле автоматически получит новое уникальное значение. INSERT catalogs VALUES (NULL, 'Видеоадаптеры'), При вставке оператором INSERT не обязательно указывать все столбцы. Те столбцы, которые не указаны в списке, получат значения по умолчанию. INSERT catalogs (name) VALUES ('Жесткие диски'), Т.к. id_catalog по умолчанию принимает значение NULL, которое вызывает механизм AUTO_INCREMENT (автоприращение), то поле id_catalog автоматически получает значение 5. Допускается добавление полностью пустых строк: INSERT catalogs () VALUES (), Часто в прикладных программах требуется узнать значение, присвоенное столбцу и снабженное атрибутом 36 AUTO_INCREMENT. Это может потребоваться для использования сгенерированного значения первичного ключа в качестве вторичного в другой таблице или в других целях. Только что сгенерированное значение возвращает встроенная функция MySQL вместе с оператором выборки: SELECT LAST_INSERT_ID(), Данная функция возвращает последнее сгенерированное значение в рамках данного сеанса. Т.е. функция вернет значение только в том случае, если новое было сгенерировано непосредственно перед вызовом функции LAST_INSERT_ID(). Важно. Отличительной чертой MySQL является то, что при использовании функций пробелы между именем функции и круглыми скобками недопустимы. Вторая форма оператора INSERT является синтаксис с оператором SET: INSERT catalogs SET id_catalog=5, name='Оперативная память' Такая форма оператора позволяет более гибко добавлять записи. Если имя столбца после SET не встречается, полю присваивается значение по умолчанию. Если вы ошиблись и два раза ввели одну и ту же команду, и в таблице теперь две одинаковых записи с разными номерами – это можно исправить оператором REPLACE. Например: REPLACE catalogs SET id_catalog=5, name= 'Оперативная память' Это заменит всю строку на заданную. Многострочный оператор INSERT совпадает по форме с однострочным, только после VALUES добавляется несколько списков expression. Вместо ранее введенных поодиночке запросов, можно было ввести такой: INSERT catalogs VALUES (0, 'Процессоры'), (0, 'Материнские платы'), (0,'Видеоадаптеры'), (0,'Жесткие диски'), (0, 'Оперативная память'), Для пакетной загрузки данных из текстового файла в таблицу в MySQL предназначен оператор LOAD DATA. Данный оператор работает быстрее, чем оператор INSERT, т.к. СУБД не требуется дополнительного времени на анализ синтаксиса оператора. Синтаксис: LOAD DATA [LOCAL] INFILE 'filename' INTO TABLE tbl Если задано необязательно ключевое слово LOCAL, то файл читается с клиентского хоста. Если же LOCAL не указывается, то файл должен находиться на сервере, где запущен MySQL. Поля базы данных должны быть разделены символом табуляции. Тогда выполнение запроса приводит к заполнению базы данных таблицы catalogs: 37 LOAD DATA INFILE 'C:\\mysql\\bin\\catalogs.txt' INTO TABLE catalogs; При формировании пути к файлу в Windows обратные слэши \ необходимо экранировать еще одним обратным слэшем, либо использовать прямые слэши /, например: 'C:/mysql/bin/catalogs.txt' Перед конструкцией INTO TABLE можно разместить одно из двух ключевых слов, которые управляют обработкой ситуации, когда данные из текстового файла дублирую значения первичного или уникальных ключей: IGNORE – пропуск строк с дублирующими значениями, REPLACE – замена уже существующих записей новыми. Заполним данными остальные таблицы. Чтобы не запутаться в данных, нарисуйте себе схему структуры таблицы (или выведите ее на экран запросом). Таблица orders: INSERT orders VALUES (1,3,'2005-01-04 10:39:38',1,8), (2,6,'2005-02-10 09:40:29',2,10), (3,1,'2005-02-18 13:41:05',4,20), (4,3,'2005-03-10 18:20:00',1,20), (5,3,'2005-03-17 19:15:36',1,20), Проверим данные: SELECT * FROM orders, Таблица products: INSERT products VALUES (1,'Celeron 1.8','1595.00',10,3.6,'Процессор Celeron® 1.8GHz, 128kb, 478-PGA, 400Mhz, OEM 0.18',1), (2,'Celeron 2.0GHz','1969.00',2,3.7,'Процессор Celeron® 2.0GHz, 128KB, 478-PGA, 400MHz, OEM ',1), (3,'Celeron 2.4GHz','2109.00',4,3.9,'Процессор Celeron® 2.4GHz, 128kb, 478-PGA, 400Mhz, OEM ',1), (4,'Celeron D 320 2.4GHz','1962.00',1,4.1,'Процессор Celeron® D 320 2.4GHz, 256kb, 478PGA, 533Mhz, OEM',1), 38 (5,'Celeron D 325 2.53GHz','2747.00',6,4.1,'Процессор Celeron® D 325 2.53GHz, 256kb, 478PGA, 533Mhz, OEM ',1), (6,'Celeron D 315 2.26GHz','1880.00',6,4.1,'Процессор Celeron® D 315 2.26GHz, 256kb, 478PGA, 533Mhz, OEM ',1), (7,'Intel Pentium 4 3.2GHz','7259.00',5,4.5,'Процессор Intel® Pentium®4 3.2GHz, 1Mb, 478PGA, 800Mhz, Hyper-Threading, OEM ',1), (8,'Intel Pentium 4 3.0GHz','6147.00',1,4.6,'Процессор Intel® Pentium®4 3.0GHz, 512Kb, 478-PGA, 800Mhz, Hyper-Threading, OEM ',1), (9,'Intel Pentium 4 3.0GHz','5673.00',12,4.5,'Процессор Intel® Pentium®4 3.0GHz, 1Mb, 478PGA, 800Mhz, Hyper-Treading, OEM ',1), (10,'Gigabyte GA-8I848P-RS','1896.00',4,3.9,'Материнская плата SOCKET-478 Gigabyte GA-8I848P-RS i848, (800Mhz), DDR, AGP 8x, ATA100, SATA , Sound 6ch, USB2.0, ATX',2), (11,'Gigabyte GA-8IG1000','2420.00',2,3.8,'Материнская плата SOCKET-478 Gigabyte GA8IG1000 i865g,FSB800/533/400,2chDDR400/333/266(4слота),Video,AGP,5PCI,ATA-100,SATA',2), (12,'Gigabyte GA-8IPE1000G','2289.00',6,3.7,'Материнская плата Socket-478 Gigabyte GA8IPE1000G i865PE(800/533/400Mhz),2ch400/333/266DDR,PCI/AGP,U100,AC`97,Lan(1Gb),S-ATA,USB 2.0, ATX',2), (13,'Asustek P4C800-E Delux','5395.00',4,4.1,'Материнская плата Socket-478 Asustek P4C800-E Delux i875P,FSB800/533Mhz,2chDDR400/333,AGP,6PCI,iEEE1394, Raid, U133,S-ATA, AC`97, Lan(1000), ATX',2), (14,'Asustek P4P800-VM\\L i865G','2518.00',6,4.0,'Материнская плата Socket-478 Asustek P4P800-VM\\L i865G FSB800/533/400, 2chDDR400/333/266(4слота),AGP,video,3PCI,ATA100,S-ATA,lan ,M-ATX',2), (15,'Epox EP-4PDA3I','2289.00',5,4.0,'Материнская плата Socket-478 Epox EP-4PDA3I i865PE(800Mhz), 2chDDR, PCI/AGP, SATA, Lan, U-100, RAID, AC`97, LAN, ATX',2), (16,'ASUSTEK A9600XT/TD','5156.00',2,4.7,'Видеоадаптер ASUSTEK A9600XT/TD 128Mb DDR SDRAM, 2x400MHz DAC, AGP8x, ATI Radeon 9600XT, DVI, TV- out, BOX ',3), (17,'ASUSTEK V9520X','1602.00',6,4.0,'Видеоадаптер ASUSTEK V9520X 128Mb DDR SDRAM, 400MHz DAC, AGP 8x, GeForce FX 5200, TV- out, BOX ',3), (18,'SAPPHIRE 256MB RADEON 9550','2730.00',3,3.8,'ВИДЕОКАРТА SAPPHIRE 256MB RADEON 9550, TV-out, DVI, OEM ',3), (19,'GIGABYTE AGP GV-N59X128D','5886.00',6,3.6,'ВИДЕОКАРТА GIGABYTE AGP GV-N59X128D FX5900XT OEM ',3), (20,'Maxtor 6Y120P0','2456.00',6,4.5,'Винчестер 120 GB Maxtor 6Y120P0, UDMA-133, 7200rpm, 8MB ',4), (21,'Maxtor 6B200P0','3589.00',4,4.0,'Винчестер 200 GB Maxtor 6B200P0, UDMA-133, 7200rpm, 8Mb ',4), (22,'Samsung SP0812C','2093.00',5,4.0,'Винчестер 80 GB Samsung SP0812C, SATA, 7200rpm SpinPoint P80 SerialATA Буферная кэш-память 8 MB 7200об/мин Интерфейс Serial ATA 1.0',4), (23,'Seagate Barracuda ST3160023A','3139.00',3,4.1,'Винчестер 160 GB Seagate Barracuda ST3160023A, UDMA-100, 7200rpm, 8Mb ',4), (24,'Seagate ST3120026A','2468.00',8,4.2,'Винчестер 120 GB Seagate ST3120026A, UDMA100, 7200rpm, 8MB ',4), (25,'DDR-400 256MB Kingston','1085.00',20,4.8,'Оперативная память DDR-400 256MB Kingston ',5), (26,'DDR-400 256MB Hynix Original ','1179.00',15,4.6,'Оперативная память DDR-400 256MB Hynix Original ',5), (27,'DDR-400 256MB PQI','899.00',10,4.2,'Оперативная память DDR-400 256MB PQI ',5), 39 (28,'DDR-400 512MB Kingston','1932.00',20,4.8,'Оперативная память DDR-400 512MB Kingston ',5), (29,'DDR-400 512MB PQI','1690.00',12,4.2,'Оперативная память DDR-400 512MB PQI ',5), (30,'DDR-400 512MB Hynix','1717.00',8,4.5,'Оперативная память DDR-400 512MB Hynix ',5); Таблица users: INSERT users VALUES (1,'Иванов','Валерьевич','Александр','58-9878','ivanov@email.ru',NULL,'active'), (2,'Лосев','Иванович','Сергей','9057777777','losev@email.ru',NULL,'passive'), (3,'Симдянов','Вячеславович','Игорь','9056666100','simdyanov@softtime.ru','http://www.softti me.ru','active'), (4,'Кузнецов','Валерьевич','Максим',NULL,'kuznetsov@softtime.ru','http://www.softtime.ru','a ctive'), (5,'Нехорошев','Юрьевич','Анатолий',NULL,NULL,NULL,'lock'), (6,'Корнеев','Александрович','Александр','89-78-36','korneev@domen.ru',NULL,'gold'); 40 Практическая работа № 6 Выборка данных в MySQL Выборка данных из таблиц осуществляется оператором SELECT, имеющему упрощенный синтаксис: SELECT select_expr FROM tbl; Каждый запрос начинается с ключевого слова SELECT, после которого следует список полей select_expr, разделенных запятыми, которые будут возвращены в результате запроса. Результатом запроса SELECT всегда является таблица, которая ничем не отличается от таблицы, расположенной в БД и называется результирующей таблицей. Если результаты двух запросов к разным таблицам имеют одинаковый формат, их можно объединить в одну таблицу. Таблица, полученная в результате запроса, может стать предметом дальнейших запросов. 1. Изменение количества и порядка следования столбцов. Рассмотрим запросы на выборку данных на примере таблицы catalogs. Таблица имеет два поля: первичный ключ id_catalog и название каталога name. Выбрать все записи в таблице можно двумя способами: Перечислив поименно все столбцы в запросе: SELECT id_catalog, name FROM catalogs; Используя символ * , обозначающий все столбцы в данной таблице: SELECT * FROM catalogs; Результат одинаков: 41 К списку столбцов в операторе SELECT прибегают в том случае, если необходимо изменить порядок следования столбцов в результирующей таблице или выбрать только часть столбцов. Например: SELECT name, id_catalog FROM catalogs; Также с помощью оператора SELECT можно извлекать данные, которых в существующей таблице нет, но которые будут отображены в результирующей таблице. Например, константы. SELECT name, id_catalog,5,'comments' FROM catalogs; 42 2. Условия Ситуация, когда требуется изменить количество выводимых строк, встречается гораздо чаще, чем когда требуется изменить число и порядок выводимых столбцов. Для ввода в запрос такого рода ограничений в операторе SELECT предназначено специальное ключевое слово WHERE, после которого следует логическое условие. Если запись удовлетворяет такому условию, она попадет в результат выборки, в противном случае запись отбрасывается. Извлечем из таблицы catalogs записи, чей первичный ключ id_catalog больше (оператор >) 2. SELECT * FROM catalogs WHERE id_catalog > 2; Условие может быть составным и объединяться при помощи логических операторов. Используем составное условие: первичный ключ должен быть больше двух и меньше или равен 4. Для объединения этих двух условий используется оператор AND (И). Также может использоваться оператор OR (ИЛИ). SELECT * FROM catalogs WHERE id_catalog > 2 AND id_catalog <= 4; 43 Такого же эффекта можно добиться конструкцией BETWEEN min AND max, возвращающей значения столбца id_catalog которые лежат в интервале от min до max: SELECT * FROM catalogs WHERE id_catalog BETWEEN 3 AND 4; Существует конструкция, противоположная конструкция- NOT BETWEEN, возвращающая записи, не попадающие в интервал между min и max. SELECT * FROM catalogs WHERE id_catalog NOT BETWEEN 3 AND 4; Иногда требуется извлечь записи, удовлетворяющие не диапазону, а списку. Для этого предназначена конструкция IN. Записи выводятся всегда в порядке возрастания, даже если поменять порядок цифр в скобках. Также существует обратный оператор NOT IN. SELECT * FROM catalogs WHERE id_catalog IN (1,2,5); В конструкции WHERE могут использоваться не только числовые столбцы. Запрос текстовых данных от регистра не зависит. SELECT * FROM catalogs WHERE name = 'процессоры' ; 44 Работа с датой. Извлечем из таблицы orders записи, соответствующие сделкам, осуществленным за февраль 2005 г. SELECT * FROM orders WHERE ordertime >= '2005-02-01' AND ordertime < '2005-03-01' ; В качестве логических выражений могут выступать и константы. Любое число, отличное от нуля, считается истинным выражением, т.е. удовлетворяющим запросу, а ноль – ложью, т.е. не удовлетворяющим запросу. SELECT * FROM catalogs WHERE 1; Выберутся все непустые записи, т.е. отличные от 0. SELECT * FROM catalogs WHERE 0; 45 3. Сортировка Как видно, результат выборки представляет собой записи, которые располагаются в порядке, в котором они хранятся в базе данных. Однако часто требуется отсортировать значения по одному из столбцов. Это осуществляется с помощью оператора ORDER BY, который следует после оператора SELECT. После ORDER BY указывается столбец, по которому следует сортировать данные. SELECT * FROM catalogs ORDER BY id_catalog; SELECT * FROM catalogs ORDER BY name; Первый запрос сортирует результат выборки по полю id_catalog, а второй по полю name. Сортировку записей можно производить и по нескольким столбцам. Пусть требуется извлечь из таблицы products записи товаров, количество которых count на складе от 4 до 8 с сортировкой по полю count и полю mark. Для краткости выведем только столбцы count и mark (оценка товара). 46 SELECT count, mark FROM products WHERE count BETWEEN 4 AND 8 ORDER BY count, mark; Записи сортируются по полю count, и если встречается несколько записей с совпадающим полем count, сортируются по полю mark. По умолчанию, сортировка производится в прямом порядке (ASC), записи располагаются начиная с наименьшего значения и заканчивая наибольшим. Изменить порядок сортировки на обратный можно ключевым словом DESC (по убыванию). SELECT ordertime FROM orders ORDER BY ordertime DESC ; 4. Ограничение выборки 47 Результат выборки может содержать сотни и тысячи записей. Их вывод и обработка занимают значительное время и серьезно загружают сервер БД. Поэтому информацию разбивают на страницы и предоставляют ее пользователю порциями. Извлечение только части запроса требует меньше времени и вычислений, кроме того, пользователю часто достаточно просмотреть первые несколько записей (например, когда вы ищете в поисковике что-то – вам выдают постранично результаты и их бывает много тысяч, но просматриваете вы только первый десяток). Постраничная навигация используется при помощи ключевого слова LIMIT, за которым следует число выводимых записей. Извлечем первые пять записей и осуществим обратную сортировку по полю count. SELECT id_product, count FROM products ORDER BY count DESC LIMIT 5; Для извлечения следующих пяти записей, используется ключевое слово LIMIT с двумя цифрами. Первая указывает позицию, начиная с которой нужно вернуть результат, а вторая – это число извлекаемых записей. SELECT id_product, count FROM products ORDER BY count DESC LIMIT 5, 5; 48 5. Использование функций При выполнении выборки из БД часто требуется выполнять специфические задачи, для решения которых удобно воспользоваться встроенными функциями MySQL. Каждая функция имеет уникальное имя и может иметь или не иметь несколько аргументов, которые перечисляются через запятую в круглых скобках вслед за названием функции. Если аргументы функции отсутствуют, круглые скобки все равно следует указывать (например, NOW() ). Важно. Отличительной чертой MySQL является то, что в функциях пробелы между именем функции и круглыми скобками недопустимы. Часто функция принимает параметры, например, имена столбцов. Функция count() возвращает число записей в таблице и принимает в качестве аргумента имя столбца. Функция возвращает число строк в таблице, значения столбца которых отличны от NULL. SELECT COUNT(id_order) FROM orders; Одной из особенностей использования функций является то, что название столбца в результирующей таблице совпадает с названием функции и ее параметрами. Часто это неудобно, особенно в прикладных программах, где после выполнения запроса обращение к результату происходит по имени столбца. В SELECT-запросе столбцу можно назначить новое имя оператором AS. Присвоим результату функции count() новый псевдоним total. 49 SELECT COUNT(id_order) AS total FROM orders; Новое имя можно использовать в других частях запроса, в выражениях WHERE и ORDER BY. Данный примем часто используется при выполнении многотабличных запросов. Функции MIN() и MAX() возвращают минимальное и максимальное значение столбца, имя которого передано в качестве параметра. Важно. Использование этих функций в выражении WHERE приведет к ошибке. Извлечем запись с наименьшим значением поля id_catalog, а потом – с наибольшим. SELECT * FROM catalogs ORDER BY id_catalog LIMIT 1; SELECT * FROM catalogs ORDER BY id_catalog DESC LIMIT 1; 50 6. Группировка записей Пусть необходимо определить первичные ключи, соответствующие каталогам id_catalog, в которых есть хоть один товар. Для этого достаточно осуществить запрос к таблице products, который извлечет поле id_catalog. SELECT id_catalog FROM products ORDER BY id_catalog; Как видно из результата, он не совсем удобен для восприятия. Было бы лучше, если запрос вернет уникальные значения столбца id_catalog. Для этого перед именем столбца можно использовать ключевое слово DISTINCT (синоним – DISTINCTROW). SELECT DISTINCT id_catalog FROM products ORDER BY id_catalog; Использование ключевого слова DISTINCT допускается совместно с функцией COUNT(). SELECT count(id_catalog) FROM products; Возвращает общее число записей в таблице products SELECT count(DISTINCT id_catalog) FROM products; 51 Возвращает число уникальных значений id_catalog. Для ключевого слова DISTINCT имеется противоположное слово ALL, которое предписывает извлечение всех значений столбца, в том числе и повторяющихся. Поскольку такое поведение установлено по умолчанию, ключевое слово ALL часто опускают. Для извлечения уникальных записей чаще прибегают к конструкции GROUP BY, за которой указывается имя столбца, по которому группируется результат. Она располагается в запросе перед ORDER BY и LIMIT. SELECT id_catalog FROM products GROUP BY id_catalog ORDER BY id_catalog; В отличие от ключевого слова DISTINCT, использование функции COUNT() совместно с GROUP BY приводит не к подсчету уникальных значений id_catalog, а к выводу числа записей, соответствующих каждому из уникальных значений id_catalog. SELECT id_catalog, COUNT(id_catalog) FROM products GROUP BY id_catalog ORDER BY id_catalog; 52 Каталог с первичным ключом id_catalog=1 содержит 9 наименований товаров, с id_catalog=2 содержит 6 и т.д. При использовании GROUP BY можно использовать WHERE. SELECT id_catalog, COUNT(id_catalog) FROM products WHERE id_catalog > 2 GROUP BY id_catalog ORDER BY id_catalog; Чаще при составлении условий требуется ограничить выборку по результату функции, например, выбрать каталоги, где число товаров больше пяти. Использование для этих целей конструкции WHERE приводит к ошибке. Вместо нее используется конструкция HAVING, которое располагается вслед за GROUP BY. При его наличии сначала происходит группировка таблицы, а затем выборка с применением условия. Допускается использования HAVING без GROUP BY. SELECT id_catalog, COUNT(id_catalog) AS total FROM products GROUP BY id_catalog HAVING total > 5 ORDER BY id_catalog; 53 7. Объединение таблиц Если формат результирующих таблиц (число, порядок следования и тип столбцов) совпадает, то возможно объединение результатов выполнения двух операторов SELECT в одну результирующую таблицу с помощью оператора UNION. Пусть имеются два запроса: SELECT id_catalog FROM catalogs; SELECT id_order + 5 FROM orders; Объединить результаты из двух таблиц можно, соединив эти два запроса словом UNION. SELECT id_catalog FROM catalogs UNION SELECT id_order + 5 FROM orders; Во втором запросе к значению первичного ключа id_orders добавляется значение 5, таким образом, все значения в результирующей таблице становятся уникальными. Однако если результирующая таблица содержит повторяющиеся строки, MySQL автоматически отбрасывает дубликаты. Изменить поведение по умолчанию можно оператором ALL, которое идет после UNION. Использование UNION ALL возвращает все строки из обеих результирующих таблиц. SELECT id_catalog FROM catalogs UNION ALL SELECT id_order FROM orders; 54 8. Сохранение результатов во внешний файл Результирующую таблицу можно сохранить в текстовый файл. Это позволяет более внимательно изучить результаты, подвергнуть их дальнейшей обработке при помощи внешней программы или вставить их в таблицу при помощи оператора LOAD DATA INFILE. Оператор LOAD DATA является дополнительным к оператору SELECT … INTO OUTFILE, который решает обратную задачу – формирование на основе таблицы текстового файла с данными. Синтаксис: SELECT….INTO OUTFILE 'имя_файла '. SELECT * INTO OUTFILE 'text.sql' FROM catalogs; сохранит таблицу catalogs в папку текущей БД в текстовом файле text.sql Важно: чтение и запись данных в файл на сервере обеспечивает глобальная привилегия FILE. Вот как будет выглядеть такой файл: Открытие данного файла в блокноте приведет к тому, что перевод строк не производится, а вместо символа перевода строки присутствует квадратик, которым обозначаются нечитаемые символы. Это из-за того, что в операторе принят unix-формат записи и перевод строк осуществляется только символом перевода строки \n без добавления символа перехода на следующую строку \r\n, который требует Windows. Точно также, как и для оператора LOAD DATA INFILE, формат текстового файла задается при помощи ключевых слов: LINES – определяет формат строки данных, соответствующей записи. FIELDS – определяет формат поля данных. LINES задает символ начала и конца строки при помощи конструкций STARTING BY и TERMINATED BY соответственно. FIELDS размещается перед LINES и задает порядок обработки полей с помощью конструкций: TERMINATED BY – определяет символ-разделитель между полями в строке, по умолчанию это символ табуляции \t, но может быть задан любой другой символ. 55 ENCLOSED BY – определяет символ кавычек, которыми ограничиваются поля, по умолчанию это пустая строка, т.е. кавычки не применяются. ESCAPED BY – назначает символ экранирования в полях, по умолчанию это обратный слэш \ Создадим дамп таблицы, в котором каждая строка оформлена в виде запроса INSERT. SELECT * INTO OUTFILE 'dump.sql' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES STARTING BY 'INSERT INTO tbl VALUES(' TERMINATED BY ' );\r\n' FROM catalogs ORDER BY id_catalog; 56