
- •Письменные лекции по дисциплине «Базы данных»
- •Лекция 1. Понятие субд. Модели данных. Реляционная модель
- •1.1. Бд и субд
- •1.2. Классификация бд
- •1.3. Классификация субд
- •1.3.1. Состав субд и работа бд
- •1.4. Язык sql
- •1.5. Основные типы sql запросов по их видам
- •1.6. Основные функции субд
- •1.7. Модели данных
- •1.8. Реляционная модель данных
- •1.9. Информационный объект
- •1.10. Нормализация отношений
- •1.10.1. Первая нормальная форма
- •1.10.2. Вторая нормальная форма
- •Лекция 2. Продолжение прошлой лекции
- •2.1. Третья нормальная форма
- •2.2. Отношения
- •2.3. Ключ
- •2.4. Пример выгрузки данных
- •2.5. Заполнение таблиц
- •2.6. Реляционные операции
- •1. Выборка
- •2. Проекция
- •3. Объединение
- •4. Пересечение
- •5. Разность
- •6. Произведение
- •7. Деление
- •8. Соединение
- •2.7. Соединение таблиц
- •2.8. Изменение таблицы
- •2.9. Типы данных MySql
- •2.10. Параллелизм
- •Лекция 3. Хранимые процедуры и функции
- •3.1. Хранимая процедура MySql
- •3.2. Переменные
- •3.3. Параметры процедуры
- •3.4. Операторы if и case
- •3.5. Оператор return
- •Лекция 4. Транзакции. Уровни изоляции. Блокировки.
- •4.1. Понятие транзакции
- •4.2. Операторы транзакции
- •4.3. Уровни изоляции (изолированности) транзакций
- •4.4. Тест acid
- •4.5. Механизм блокировок
- •4.6. Взаимоблокировки
- •4.7. Ведение журнала транзакций
- •Лекция 5. Ссылочная целостность данных. Внешние ключи. Индексирование.
- •5.1. Ссылочная целостность данных
- •5.2. Внешний ключ
- •5.2.1. Условия обеспечения целостности данных при помощи внешнего ключа
- •5.2.2. Практический пример
- •5.2.3. Синтаксис объявления внешнего ключа
- •5.3. Индекс
- •5.3.1. Для каких полей нужно создавать индексы
- •5.3.2. Принцип работы индексов
- •5.3.3. Виды индексов
- •5.3.4. Индексирование таблиц MySql
- •5.3.5. Создание индекса в MySql
- •5.3.6. Типы индексов в MySql
- •5.3.7. Удаление индекса в MySql
- •5.3.8. Преимущества использования индексов
- •5.3.9. Недостатки использования индексов
- •5.3.10. Практический пример
- •5.4. Курсор
- •Лекция 6. Администрирование баз данных
- •6.1. Резервирование и восстановление вручную
- •6.2. Команды grant и revoke
- •6.3. Утилита mysqldump
- •6.3.1. Создание дампа
- •6.3.2. Развертывание дампа
- •6.4. Утилита mysqlhotcopy
- •6.5. Утилита mysqlcheck
- •Лекция 7. Администрирование бд
- •7.7. Статус таблиц
- •7.8. Просмотр таблиц, доступных в бд
- •7.9. Получение информации о статусе сервера
- •7.10. Получение информации о переменных
- •7.16. Файлы журналов
- •7.17. Как обезопасить MySql от хакеров
- •Указатели на страницы с ответами
8. Соединение
SELECT <columns...> FROM <tables...> WHERE <condition>
Выбирает все наборы значений (по столбцам <columns...>) по указанным таблицам <tables...> в соответствии с условием <condition>. Первый этап — произведение. Второй этап — фильтрация в соответствии с условием.
Пример
Код_мульта |
Название_мульта |
Название_канала |
0 |
The Simpsons |
2x2 |
1 |
Family Guy |
2x2 |
2 |
Duck Tales |
RenTV |
Код_канала |
Частота |
RenTV |
3.1415 |
2x2 |
783.25 |
SELECT * FROM Мультфильмы, Каналы WHERE Название_канала = Код_канала
Первый этап — произведение.
Код_мульта |
Название_мульта |
Название_канала |
Код_канала |
Частота |
0 |
The Simpsons |
2x2 |
RenTV |
3.1415 |
0 |
The Simpsons |
2x2 |
2x2 |
783.25 |
1 |
Family Guy |
2x2 |
RenTV |
3.1415 |
1 |
Family Guy |
2x2 |
2x2 |
783.25 |
2 |
Duck Tales |
RenTV |
RenTV |
3.1415 |
2 |
Duck Tales |
RenTV |
2x2 |
783.25 |
Второй этап — фильтрация в соответствии с условием.
Код_мульта |
Название_мульта |
Название_канала |
Код_канала |
Частота |
0 |
The Simpsons |
2x2 |
2x2 |
783.25 |
1 |
Family Guy |
2x2 |
2x2 |
783.25 |
2 |
Duck Tales |
RenTV |
RenTV |
3.1415 |
Подробнее: http://migku.wikidot.com/gos-db-16
2.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 и наоборот.