Основное / Письменные лекции по дисциплине «Базы данных»
.pdf2.7. Соединение таблиц
Итак, предположим, что у нас есть два стола. Стол A (TableA) слева, а стол B (TableB) справа. Мы заселим каждый четырьмя персонажами, имена которых могут присутствовать на обоих столах.
TableA |
|
|
TableB |
|
||
|
|
|
|
|
|
|
id |
name |
|
id |
|
name |
|
|
|
|
|
|
|
|
1 |
Pirate |
|
1 |
|
Rutabaga |
|
|
|
|
|
|
|
|
2 |
Monkey |
|
2 |
|
Pirate |
|
|
|
|
|
|
|
|
3 |
Ninja |
|
3 |
|
Darth Vader |
|
|
|
|
|
|
|
|
4 |
Spaghetti |
|
4 |
|
Ninja |
|
|
|
|
|
|
|
|
2.7.1. INNER |
JOIN |
|
|
|
|
|
— INNER |
JOIN производит |
выборку |
записей, которые только |
существуют в TableA и TableB одновременно.
—CROSS JOIN — это эквивалент INNER JOIN.
—INNER JOIN можно заменить условием объединения в WHERE. Запрос:
SELECT * FROM `TableA`
INNER JOIN `TableB`
ON `TableA`.`name` = `TableB`.`name`
Идентичный запрос:
SELECT * FROM `TableA`,`TableB`
WHERE `TableA`.`name` = `TableB`.`name`
Результат:
TableA |
|
|
TableB |
||
|
|
|
|
|
|
id |
|
name |
id |
|
name |
|
|
|
|
|
|
1 |
|
Pirate |
2 |
|
Pirate |
|
|
|
|
|
|
3 |
|
Ninja |
4 |
|
Ninja |
|
|
|
|
|
|
2.7.2. FULL OUTER JOIN
*Не доступно в MySQL.
FULL OUTER JOIN производит выборку всех записей из TableA и TableB, вне зависимости есть ли соответствующая запись в соседней таблице. Если таковой нет, то недостающая сторона будет содержать пустой указатель и результатом будет выводится NULL.
Запрос:
SELECT * FROM `TableA`
FULL OUTER JOIN `TableB`
ON `TableA`.`name` = `TableB`.`name`
Результат:
TableA |
|
|
TableB |
||
|
|
|
|
|
|
id |
|
name |
id |
|
name |
|
|
|
|
|
|
1 |
|
Pirate |
2 |
|
Pirate |
|
|
|
|
|
|
2 |
|
Monkey |
NULL |
|
NULL |
|
|
|
|
|
|
3 |
|
Ninja |
4 |
|
Ninja |
|
|
|
|
|
|
4 |
|
Spaghetti |
NULL |
|
NULL |
|
|
|
|
|
|
NULL |
|
NULL |
1 |
|
Rutabaga |
|
|
|
|
|
|
NULL |
|
NULL |
3 |
|
Darth Vader |
|
|
|
|
|
|
В MySQL нечто похожее можно получить запросом:
SELECT `TableA`.*, `TableB`.* FROM `TableA`
LEFT JOIN `TableB` USING (`name`)
UNION SELECT `TableA`.*, `TableB`.* FROM `TableB`
LEFT JOIN `TableA`
USING (`name`)
WHERE `TableA`.`name` IS NULL
Результат тот же, что и выше.
Чтобы произвести выборку уникальных записей из двух таблиц (значения одной таблицы отсутствуют в другой), мы воспользуемся тем же FULL OUTER JOIN, указав, что NULL может быть как в результате одной таблицы, так и в результате другой.
Запрос:
SELECT * FROM `TableA`
FULL OUTER JOIN `TableB`
ON `TableA`.`name` = `TableB`.`name`
WHERE `TableA`.`id` IS NULL OR `TableB`.`id` IS NULL
Результат:
TableA |
|
|
TableB |
||
|
|
|
|
|
|
id |
|
name |
id |
|
name |
|
|
|
|
|
|
2 |
|
Monkey |
NULL |
|
NULL |
|
|
|
|
|
|
4 |
|
Spaghetti |
NULL |
|
NULL |
|
|
|
|
|
|
NULL |
|
NULL |
1 |
|
Rutabaga |
|
|
|
|
|
|
NULL |
|
NULL |
3 |
|
Darth Vader |
|
|
|
|
|
|
В MySQL нечто похожее можно получить запросом:
SELECT `TableA`.*, `TableB`.* FROM
TableA LEFT JOIN `TableB`
USING (`name`)
WHERE `TableB`.`name` IS NULL
UNION SELECT `TableA`.*, `TableB`.* FROM `TableB ` LEFT JOIN `TableA` USING (`name`)
WHERE `TableA`.`name` IS NULL
Результат тот же, что и выше.
2.7.3. LEFT JOIN
LEFT OUTER JOIN (LEFT JOIN) указывает, что левая таблица управляющая (в нашем случае TableA) и производит из нее полную выборку, осуществляя поиск соответствующих записей в таблице TableB. Если таких соответствий не найдено, то база вернет пустой указатель — NULL. Указание OUTER — не обязательно.
Запрос:
SELECT * FROM `TableA`
LEFT JOIN `TableB`
ON `TableA`.`name` = `TableB`.`name`
Результат:
TableA |
|
|
TableB |
||
|
|
|
|
|
|
id |
|
name |
id |
|
name |
|
|
|
|
|
|
1 |
|
Pirate |
2 |
|
Pirate |
|
|
|
|
|
|
2 |
|
Monkey |
NULL |
|
NULL |
|
|
|
|
|
|
3 |
Ninja |
4 |
Ninja |
|
|
|
|
4 |
Spaghetti |
NULL |
NULL |
|
|
|
|
Чтобы произвести выборку записей из таблицы TableA, которых не существует в таблице TableB, мы выполняем LEFT JOIN, но затем из результата исключаем записи, которые не хотим видеть, путем указания, что TableB.id является нулем (указывая, что записи нет в таблице
TableB).
Запрос:
SELECT * FROM `TableA`
LEFT JOIN `TableB`
ON `TableA`.`name` = `TableB`.`name`
WHERE `TableB`.`id` IS NULL
Результат:
|
TableA |
|
TableB |
||
|
|
|
|
|
|
id |
|
name |
id |
|
name |
|
|
|
|
|
|
2 |
|
Monkey |
NULL |
|
NULL |
|
|
|
|
|
|
4 |
|
Spaghetti |
NULL |
|
NULL |
|
|
|
|
|
|
2.7.4. RIGHT JOIN
RIGHT JOIN выполняет те же самые функции, что и LEFT JOIN, за исключением того, что правая таблица будет прочитана первой. Таким образом, если в запросах из предыдущей главы LEFT заменить на RIGHT, то таблица результатов, грубо говоря, отразится по вертикали. То есть, в результате вместо значений TableA будут записи TableB и наоборот.
2.8. Изменение таблицы Переименование таблицы:
ALTER TABLE "Все заказы(кп)"
RENAME TO "Все заказы(кп1)"
Аналогичный результат может быть получен следующим образом:
RENAME "Все заказы(кп)" TO "Все заказы(кп1)"
Добавление нового поля:
ALTER TABLE "Клиент(кп)"
ADD ( "Образование" CHAR(20) )
Удаление поля:
ALTER TABLE "Клиент(кп)"
DROP ("Образование")
Переименование поля:
ALTER TABLE "Клиент(кп)"
RENAME column "Образование" TO "Степень"
2.9. Типы данных MySQL
Числовые данные — это все целые числа (без дробной части) и вещественные числа (с дробной частью).
Строковые данные — последовательность символов, заключенная в кавычки. В MySQL в качестве стандарта используются одинарные кавычки и для совместимости с другими базами данных рекомендуется именно их использование.
Календарные данные — тип для обозначение даты и времени, принимает различные формы, например строковую «2007-11-23» или числовую 20071123. Особенностью этого типа данных является их
хранение в едином внутреннем формате, что позволяет производить операции сложения и вычитания, в независимости от внешнего представления.
NULL — специальный тип данных, означает отсутствие информации.
● Числовые данные делятся на точечные (это BOOLEAN, INTEGER,
DECIMAL) и приближенные (FLOAT, REAL, DOUBLE PRECISION).
●Одни из основных строковых типов данных: CHAR(N) (строгий реальный размер: не больше, не меньше заданного N), VARCHAR(N) (нестрогий реальный размер: не больше заданного N) и TEXT (нестрогий реальный размер вплоть до 2^16-1 символов).
●Одни из основных календарных типов данных: DATE (от
'1000-01-01' до '9999-12-31'), TIME (от '-828:59:59' до
'828:59:59') и DATETIME (от '1000-01-01 00:00:00' до
'9999-12-31 00:00:00').
Подробнее: https://kbss.ru/blog/bd_mysql/153.html
2.10. Параллелизм Параллелизм — возможность параллельной обработки в СУБД
многих параллельных транзакций к одним и тем же данным в одно и то же время.
СУБД должно осуществлять правильное восстановление данных при отмене транзакций или в случае системного сбоя и гарантировать, что пользователи при параллельной работе с данными мешать друг другу не будут.
Лекция 3. Хранимые процедуры и функции
●Хранимая процедура MySQL;
●Переменные;
●Параметры процедуры;
●Операторы IF и CASE;
●Оператор RETURN.
3.1. Хранимая процедура MySQL
Хранимая процедура MySQL представляет собой подпрограмму, которая хранится в базе данных. Она содержит имя, список параметров и операторы SQL. Все популярные системы управления базами данных поддерживают хранимые процедуры. Они были введены в MySQL 5.
Существует два типа процедур (подпрограмм): хранимые процедуры (не возвращающие значения) и функции, возвращающие значения, которые используются в операторах SQL (например, pi()).
Основное отличие заключается в том, что функции могут использоваться как любое выражение в операторах SQL (простой вызов: pi()), а хранимые процедуры должны вызываться с помощью оператора
CALL (CALL proc).
По умолчанию процедура связана с базой данных, используемой в данный момент. Чтобы связать процедуру с конкретной базой данных, нужно указать её при создании хранимой процедуры:
имя_базы_данных.имя_хранимой_процедуры
Полный синтаксис
CREATE [DEFINER = { user | CURRENT_USER }]
PROCEDURE имя_процедуры ([параметры_процедуры[,...]]) [характеристики ...] тело_подпрограммы
параметры_процедуры: [ IN | OUT | INOUT ] имя_параметра type type: Любой валидный тип данных MySQL
характеристики: COMMENT 'string' | LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
тело_подпрограммы: Валидный оператор программы SQL
Можно ещё внутрь хранимой функции и хранимой процедуры добавлять ключевые слова BEGIN и END для того, чтобы выделить тело подпрограммы.
IN — параметр на вход (чтение), OUT — параметр на выход (запись), INOUT — параметр, который будет меняться в течение выполнения процедуры (и чтение, и запись).
Достоинства хранимой процедуры:
—упрощает управление кодом;
—позволяет ограничить доступ к данным в таблицах и уменьшить вероятность нежелательных действий в отношении этих данных;
—обычно выполняются быстрее, чем обычные SQL-инструкции, так как код процедур компилируется один раз при первом ее запуске, а затем сохраняется в скомпилированной форме.
Перед тем, как осуществить вызов хранимой процедуры, необходимо получить определенную информацию.
Проверка версии MySQL
mysql>SELECT VERSION();
+ |
----------- |
+ |
| VERSION() | |
||
+----------- |
|
+ |
| 5.6.12 |
| |
|
+----------- |
|
+ |
1 |
row in set (0.00 sec) |
Разделитель — символ или строка символов, которая используется для закрытия оператора SQL. По умолчанию в качестве разделителя используется точка с запятой (;). Но это вызывает проблемы в хранимых
процедурах и триггерах MySQL, поскольку она может иметь много операторов, и каждый должен заканчиваться точкой с запятой. Поэтому в качестве разделителя будем использовать двойной знак доллара — $$. Чтобы позже снова использовать в качестве разделителя ; выполните команду DELIMITER ; $$. Ниже приведен код для смены разделителя:
mysql> DELIMITER $$ ;
Теперь DELIMITER по умолчанию — $$.
mysql> DELIMITER ; $$
Теперь DELIMITER по умолчанию — ;.
Пример процедуры MySQL:
mysql> DELIMITER $$;
mysql> CREATE PROCEDURE job_data() -> SELECT * FROM JOBS; $$
Query OK, 0 rows affected (0.00 sec)
Пояснение:
●Команда CREATE PROCEDURE создает хранимую процедуру;
●Следующая часть — это имя процедуры job_data;
●Имена процедур не чувствительны к регистру, поэтому job_data равносильно JOB_DATA;
●Нельзя использовать две процедуры с одним именем в одной и той же базе данных.
●Можно использовать имена в формате
имя_процедуры.имя_базы_данных, например, hr.job_data.
●Имена процедур могут быть разделены. Если имя разделено, оно может содержать пробелы.
●Максимальная длина имени процедуры составляет 64 символа.
●Избегайте использования имен встроенных функций MySQL.