Безопасность систем баз данных. Учебное пособие
.pdf·Он работает только в том случае, когда две таблицы совместно используют столбец с одним именем в качестве условия объединения. В противном случае нужно применять альтернативный синтаксис. Отметим, что MySQL не может автоматически определять столбец, желаемый для использования для объединения (даже если в двух таблицах присутствуют столбцы с одним и тем же именем), так что его следует задавать явным образом.
·В результатах отображаются строки, где объединяющий столбец (или столбцы) совпадает в обеих таблицах. Строки из одной таблицы, для которых нет соответствия в другой таблице, игнорируются.
·Не стоит забывать о выражении USING. В MySQL оно не является обязательным, но если его пропустить, то результаты будут бессмысленными, поскольку получим декартово произведение, т. е. каждой записи в одной таблице будет поставлена
всоответствие каждая запись из другой таблицы.
·Столбец (или столбцы), указанный после выражения USING, должен быть заключен в круглые скобки. В случае объединения по нескольким столбцам нужно разделить их имена -за пятыми.
Если следовать этим правилам, то выполнение объединений с помощью выражения INNER JOIN не вызовет никаких проблем. Теперь рассмотрим еще несколько примеров.
Предположим, нужно перечислить преступников и их пре-
ступления. Путем анализа таблиц prestupnik и prestuplenie определим, что объединение следует выполнить по двум столбцам gruppirovka_id и prestupnik_id. Проведем эту операцию объеди-
нения (рис. 5.16):
mysql> SELECT prestupnik_name, prestuplenie_name
-> FROM prestupnik INNER JOIN prestuplenie -> USING (gruppirovka_id, prestupnik_id) LIMIT 15;
61
Рис. 5.16. Объединение по двум столбцам
В выражении USING указаны два объединяющих столбца,
разделенных запятыми: USING (gruppirovka_id, prestupnik_id). В
результате показаны преступники и преступления, которые они совершили. Для экономии места ограничим выходные данные15 строками с помощью выраженияLIMIT, описанного в разделе «Выражение LIMIT».
Усовершенствуем предыдущий пример путем добавления выражения ORDER BY. Имеет смысл отобразить преступников в алфавитном порядке, а преступления — в том порядке, в котором они совершались, так что модифицируем предыдущий запрос следующим образом (рис. 5.17):
mysql> SELECT prestupnik_name, prestuplenie_name
-> FROM prestupnik INNER JOIN prestuplenie -> USING (gruppirovka_id, prestupnik_id) -> ORDER BY prestupnik_name, ->prestuplenie_id LIMIT 15;
Рис. 5.17. Объединение выражения ORDER BY
62
Выражение ORDER BY, что стоит в запросе после условия объединения, сортирует преступников и преступления в требуемом порядке.
Теперь попробуем выполнить другой запрос. Предположим, что требуется определить, в какой преступной группировке состоит самый пожилой преступник. Это можно сделать путем
объединения |
таблиц gruppirovka (содержащей |
поле gruppi- |
rovka_name) |
и prestupnik (содержащей |
поле prestup- |
nik_god_rozhdeniya) используя в условии объединения столбцы поле gruppirovka_id. Тогда запрос будет выглядеть так (рис. 5.18):
mysql> SELECT gruppirovka_name, prestupnik_name,
-> prestupnik_god_rozhdeniya FROM
-> gruppirovka INNER JOIN prestupnik USING (gruppirovka_id)
-> ORDER BY prestupnik_god_rozhdeniya LIMIT 1;
|
|
Рис. 5.18. Определение самого пожилого преступника |
|
||
|
Произвели сортировку по полюprestupnik_god_rozhdeniya, |
|
|||
где находится год рождения преступников, и ограничили выбор- |
|
||||
ку одной записью. |
|
|
|
||
|
Необходимо знать еще об одной функции, которая исполь- |
|
|||
зуется для агрегирования значений. Предположим, что требуется |
|
||||
определить какое количество лет осуждены преступники входя- |
|
||||
щие |
в |
состав |
Солнцевской |
преступной |
группиров |
(Solncevskaya). Это можно сделать путем суммирования звучания |
|
||||
отдельных столбцов с помощью функции SUM() из SQL (рис. 5.19): |
|
||||
|
mysql> SELECT SUM(prestuplenie_srok) FROM |
|
|||
-> gruppirovka INNER JOIN prestuplenie -> USING (gruppirovka_id)
-> WHERE gruppirovka_id=1;
63
Рис. 5.19. Сумиирование отдельных столбцов
Таким образом, искомое значение равно 47 годам. Функция SUM() определяет сумму всех значений столбца, заключенного в круглые скобки (в данном случае это столбец prestuplenie_srok), а не отдельных значений. Поскольку использовалось выражение WHERE для выбора строк лишь для группировки «Solncevskaya», суммой значений «prestuplenie_srok» будет искомая величина.
Контрольные вопросы
1.Какое выражение языкаSQL организует сортировку данных?
2.Как организовать сортировку по алфавиту и в обратном порядке? К полям каких типов применяется сортировка?
3.С помощью какого выражения языкаSQL ограничивается выборка? Какова структура выражения LIMIT?
4.C помощью какого оператора организуется объединение таблиц?
5. Назначение |
выражения USING. Можно ли объединять |
больше 2 таблиц |
в одном запросе? |
64
6. ДОБАВЛЕНИЕ, УДАЛЕНИЕ И РЕДАКТИРОВАНИЕ ЗАПИСЕЙ В ТАБЛИЦАХ
(ПК-35)
6.1. Добавление записей в таблицы базы данных. Инструкции INSERT
Инструкция INSERT используется для добавления новых данных в таблицы. Опишем базовый синтаксис инструкции INSERT и покажем примеры ее использования во время добавления отдельных записей и их групп. В представленных ниже примерах рассматриваются вопросы добавления записей в таблицы базы данных prestupnost, они предназначены для обучения синтаксису инструкций добавления записей в таблицы. Начнем с главной задачи — попробуем вставить одну новую строку в таблицу gruppirovka. Для этого нужно хорошо знать структуру таблицы. Можно определить структуру таблицы с помощью инст-
рукции SHOW COLUMNS (рис. 6.1):
mysql> SHOW COLUMNS FROM gruppirovka;
Рис. 6.1. Определение структуры таблицы
Приведенные данные свидетельствуют о ,томчто два столбца в таблице расположены в таком порядке: gruppirovka_id и gruppirovka_пате — и это важно знать при использовании базового синтаксиса.
Новая строка предназначена для добавления информации о новой преступной группировке. Какое значение gruppirovka_id задается для этой строки? Поскольку в таблице уже имеется шесть строк, очевидно, что ее значением будет7. Можно проверить это с помощью следующей команды (рис. 6.2):
mysql> SELECT МАХ(gruppirovka_id)
-> FROM gruppirovka;
65
Рис. 6.2. Определение количества строк
Функция МАХ() является агрегатной функцией и показывает максимальное значение для столбца, указанного в качестве параметра. Этот метод проще, чем использование инструкции
SELECT gruppirovka_id FROM gruppirovka. В этом случае выво-
дятся все строки, которые придется просмотреть для определения максимального значения (хотя это можно сделать с помощью выражения ORDER BY). Функцию МАХ() также удобнее использо-
вать, чем инструкцию SELECT gruppirovka_id FROM gruppirovka ORDER BY gruppirovka_id DESС LIMIT 1, поскольку эта функция возвращает корректный результат.
Теперь вставим строку. Запрос будет выглядеть следующим образом:
mysql> INSERT INTO gruppirovka VALUES
(7, "Danilovskaya");
Query OK, 1 row affected (0.00 sec)
В результате будет создана новая строка, о чем вам сооб-
щит MySQL (Query OK, 1 row affected (0.00 sec)). В
качестве значения gruppirovka_id будет использоваться 7, а в качестве gruppirovka_пате — Danilovskaya. Убедиться в этом можно, введя запрос (рис. 6.3):
mysql> SELECT * FROM gruppirovka WHERE gruppirovka_id = 7;
Рис. 6.3. Проверка значения
66
Чтобы продолжить пример и продемонстрировать метод групповой вставки, добавим в базу данных преступника, который входит в состав, добавленной ранее преступной группировки, и все его преступления. Для этого вставим в таблицуprestupnik запись содержащую информацию о преступнике. Вначале проверим структуру таблицы prestupnik (рис.6.4):
mysql> SHOW COLUMNS FROM prestupnik;
Рис. 6.4. Проверка структуры таблицы
Теперь вставим преступника с помощью предыдущего ме-
тода: mysql> INSERT INTO prestupnik
-> VALUES (7, 1, "Pomoev Artur Vladimirovich", 1970);
Query OK, 1 row affected (0.00 sec)
Первое значение предназначено дляgruppirovka_id, оно уже известно. Второе значение, равное 1, предназначено для prestupnik_id, поскольку это первый преступник, входящий в Даниловскую преступную группировку, которого добавляем в базу данных.
Теперь необходимо добавить несколько преступлений в таблицу prestuplenie, для этого проверим структуру таблицы prestuplenie (рис. 6.5):
mysql> SHOW COLUMNS FROM prestuplenie;
Рис. 6.5. Добавление в таблицу
67
И наконец вставим преступления:
mysql> INSERT INTO prestuplenie VALUES
-> (7,1,1,’Kvartirnaya krazha’,3,’1995-10- 22’),
-> (7,1,2, ‘Ograblenie magazina’,5,’2001-09- 18’);
Query OK, 2rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0
Здесь, для того чтобы добавить два преступления в один запрос SQL, использовали другой синтаксис в выражении INSERT. Такой синтаксис рекомендуется применять в том случае, когда требуется загрузить больше одной строки. Данный синтаксис похож на синтаксис отдельной вставки за исключением того, что значения для нескольких строк собраны вместе в списке
и разделены запятыми. Указывая MySQL в одной инструкции все данные, которые требуется вставить в таблицу, оптимизируем процесс вставки, позволяя запросам, использующим такой синтаксис, работать во много раз быстрее, чем при повторении вставок отдельных строк.
Синтаксис выражения INSERT отдельной вставки довольно строг: если имеется дубликат, то выполнение запроса будет прекращено сразу же. Попробуйте, например, вставить снова те же преступления:
-> (7,1,1,’Kvartirnaya krazha’,3,’1995-10-22’), -> (7,1,2, ‘Ograblenie magazina’,5,’2001-09-18’),
ERROR 1062 (23000): Duplicate entry '7-1-1' for key 1
Операция INSERT будет прервана на первом же дублирующем ключе. Можно добавить ключевое словоIGNORE для предотвращения этой ошибки:
mysql> INSERT IGNORE INTO prestuplenie VALUES -> (7,1,1,’Kvartirnaya krazha’,3,’1995-10-22’), -> (7,1,2, ‘Ograblenie magazina’,5,’2001-09-
18’),
Query OK, 0 rows affected (0.01 sec) Records: 2 Duplicates: 2 Warnings: 0
68
Однако в большинстве случаев возможно появление проблем (должна поддерживаться уникальность первичных ключей), поэтому ключевое слово IGNORE используется редко.
MySQL выводит результаты групповой вставки не так, как при отдельной вставке. Для нашей исходной групповой вставки результаты выглядят следующим образом:
Query 0К, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0
В первой строке отображается количество вставленных строк, а в первой записи последней строки— количество строк (или записей), которые были реально обработаны. Если при использовании операцию INSERT с ключевым словомIGNORE, вновь попытаетесь вставить дублирующую запись(первичный ключ которой соответствует ключу в существующей строке), то MySQL без проблем проигнорирует вставку и укажет на дублирование:
Query 0К, 0 rows affected (0.01 sec) Records: 2 Duplicates: 2 Warnings: 0
Существует несколько вариантов использования синтаксиса с ключевым словом VALUES, и продемонстрируем их, а также опишем преимущества и недостатки.
Известно три недостатка использования ключевого слова VALUES. Во-первых, нужно помнить порядок столбцов.
Во-вторых, нужно обеспечить значение для каждого столбца.
В-третьих, такой синтаксис зависит от структуры таблицы. Изменяя структуру, придется менять и инструкциюINSERT: ее работа не будет очевидна без знания структуры таблицы. В связи с вышесказанным во время работы как с отдельной, так и с групповой вставкой получим сообщение об ошибке, если забудете предоставить значения для всех столбцов. Однако все эти недостатки можно легко обойти, если немного изменить синтаксис.
Предположим, добавляете нового преступника в таблицу prestupnik, содержащей четыре столбца, однако забыли порядок. Можно выполнить вставку следующим образом:
mysql> INSERT INTO prestupnik (gruppirovka_id,
69
-> prestupnik_name,prestupnik_god_rozhdeniya, -> prestupnik_id) VALUES
-> (7, ‘Sidorov Gennadiy Ivanovich’,1955,2);
Query OK, 1 row affected (0.00 sec)
Имена столбцов, заключенные в круглые скобки, расположены после имени таблицы, а значения, хранящиеся в этих столбцах, перечислены в круглых скобках после ключевого слова VALUES. Таким образом, в данном примере создается новая строка со значением 7 в столбце gruppirovka_id, значением ‘Sidorov Gennadiy Ivanovich’ в столбце prestupnik_name, значением
1955 в столбце prestupnik_god_rozhdeniya и значением 2 в столбце prestupnik_id. Преимущество этого синтаксиса состоит в том, что он читабелен, гибок (в отношении третьего недостатка, который мы описывали) и не зависит от порядка (первый недостаток). Недостаток данного синтаксиса заключается в том, что нужно по памяти вводить имена столбцов.
Этот синтаксис, в отличие от более простого метода, позволяет вставлять значения только для некоторых столбцов. Чтобы понять, как это можно использовать, взглянем на таблицу prestuplenie (рис. 6.6):
mysql> SHOW COLUMNS FROM prestuplenie;
Рис. 6.6. Таблица «преступление»
Столбцы prestuplenie_srok и data_osvobozhdeniya могут быть пустыми при добавлении записи(об этом свидетельствует значение «Yes» в поле «Null»), то есть если не вставили значение для этих столбцов. Предположим, что известно, какое было совершено преступление добавленным ранее преступником, но не известно срока и даты освобождения. Далее показано, как произвести такую вставку:
70
