- •Глава 1. Базы данных и системы управления 9
- •Глава 2. Организация доступа к данным 45
- •Глава 3. Реляционная алгебра 60
- •Глава 4. Основы sql 67
- •Глава 5. Проектирование реляционных баз данных 89
- •Глава 6. Взаимодействие sql с приложениями 116
- •Глава 7. Некоторые проблемы администрирования баз данных 154
- •Базы данных и системы управления
- •Файловые системы
- •Концепция баз данных
- •Основные функции субд
- •Непосредственное управление данными во внешней памяти
- •Управление буферами оперативной памяти
- •Управление транзакциями
- •Журнализация
- •Поддержка языков баз данных
- •Трехуровневая модель архитектуры систем баз данных
- •Модели данных
- •Характеристика связей
- •Компьютерно-ориентированные модели данных
- •Реляционный подход
- •Ключи и целостность реляционных данных
- •Моделирование концептуальной схемы базы данных
- •Организация доступа к данным
- •Страницы и файлы
- •Индексирование
- •Структуры типа б-дерева
- •Хеширование
- •Методы сжатия
- •Метод дифференциального сжатия
- •Иерархические методы сжатия
- •Кодирование по методу Хаффмена
- •Реляционная алгебра
- •Традиционные реляционные операции
- •Специальные реляционные операции
- •Дополнительные реляционные операции
- •Примеры использования реляционной алгебры для выражения словесных запросов в виде формул
- •Основы sql
- •Типы данных
- •Строковые типы данных
- •Битовые типы данных
- •Точные числовые типы данных
- •Вещественные числовые типы данных
- •Календарные типы данных
- •Значения null
- •Создание и обслуживание таблиц
- •Запрос на выборку
- •Статистические функции
- •Создание соединений
- •Вложенные запросы
- •Запрос на объединение
- •Запросы, выполняющие реляционные операции вычитания, пересечения и деления
- •Запросы на изменение
- •Перекрестные запросы
- •Проектирование реляционных баз данных
- •Нормализация отношений
- •Функциональные зависимости
- •Н ормальные формы, обоснованные функциональными зависимостями
- •Нормальная форма Бойса–Кодда
- •Нормальные формы, обоснованные более сложными зависимостями
- •Процедура нормализации и проектирования
- •Пример проектирования базы данных
- •Назначение и предметная область
- •Проектирование базы данных
- •Взаимодействие sql с приложениями
- •Встраивание sql-операторов в программный код
- •Тип курсора
- •Триггеры
- •Хранимые процедуры
- •Стандартные интерфейсы для доступа к данным
- •Информационное окружение веб-сервера
- •Стандарт odbc
- •Уровни соответствия
- •Уровень соответствия odbc
- •Задание имени источника данных odbc
- •Расширяемый язык разметки xml
- •Xml как язык разметки
- •Материализация хмl-документов с помощью xslt
- •Создание хмl-документов на основе информации из базы данных
- •Некоторые проблемы администрирования баз данных
- •Оптимизация запросов
- •Параллельная обработка данных
- •Потеря обновления
- •Зависимость от незафиксированных обновлений
- •Несогласованный анализ
- •Блокировки транзакций
- •Согласованность и уровень изоляции транзакций
- •Распределенные системы баз данных
- •Фрагментация
- •Репликация
- •Распространение обновлений
- •Управление каталогом
- •Распределенная обработка запросов
- •Типы распределенных систем баз данных
- •Нераспределенные мультибазовые субд
- •Клиент-серверные системы
- •Системы с общими ресурсами
- •Технические аспекты администрирования базы данных
- •Восстановление базы данных
- •Безопасность баз данных
- •Шифрование данных
- •Производительность баз данных
- •Администрирование данных
- •Литература
Запросы, выполняющие реляционные операции вычитания, пересечения и деления
В некоторых модификациях языка SQL, например, используемой в СУБД Oracle, реляционная операция пересечения отношений выполняется оператором INTERSECT, который возвращает только те строки, которые присутствуют в обеих таблицах. Вычитание отношений реализуется оператором EXCEPT, который возвращает строки первой таблицы за исключением тех, которые присутствуют и во второй таблице. Как и в случае оператора UNION, обрабатываемые таблицы должны иметь одинаковый набор и последовательность имен полей. В СУБД Access эти операции могут быть реализованы при помощи оператора EXISTS.
Оператор EXISTS в предложении WHERE выполняет проверку на существование данных, которые удовлетворяют критериям соответствующего вложенного запроса, и возвращает булево значение «истина» или «ложь».
Пример. Найти имена поставщиков, которые поставляют деталь Д1:
SELECT DISTINCT П.Имя_П FROM Поставщики AS П WHERE EXISTS (SELECT * FROM Поставки AS Пк WHERE Пк.ПN=П.ПN AND Пк.ДN='Д1');
Для каждого кортежа отношения Поставщики, которое обрабатывается во внешнем запросе, для вложенного запроса будет возвращено значение “истина”, если существует хотя бы один кортеж в отношении Поставки с тем же значением П№, который рассматривает внешний запрос. Чтобы это определить, выполняется соединение по Пк.П№=П.П№. Во вложенном запросе используется предложение SELECT *, но можно указать имя любого атрибута, т.к. этот вложенный запрос возвращает не данные, а значение истинности.
Чтобы получить имена поставщиков, которые не поставляют деталь Д1, можно использовать отрицание предложения EXISTS:
SELECT DISTINCT П.Имя_П FROM Поставщики AS П WHERE NOT EXISTS (SELECT * FROM Поставки AS ПК WHERE ПК.ПN=П.ПN AND ПК.ДN='Д1');
Пример решения задачи двумя способами – с оператором EXISTS и без него: Найти номера деталей, поставляемых поставщиком из города, название которого начинается на букву М.
I. SELECT DISTINCT Пк.ДN FROM Поставки AS Пк WHERE Пк.ПN IN (SELECT П.ПN FROM Поставщики AS П WHERE П.Гор LIKE 'М*');
II. SELECT DISTINCT Пк.Д№ FROM Поставки Пк WHERE EXISTS (SELECT * FROM Поставщики П WHERE П.П№ = Пк.П№ AND Гор LIKE ′М*′);
Если надо указать имя детали, т.е. получить сведения из 3-й таблицы, то команда SQL выглядит так:
SELECT DISTINCT Д.Имя_Д FROM Детали AS Д WHERE EXISTS (SELECT DISTINCT Пк.ДN FROM Поставки AS Пк WHERE EXISTS (SELECT * FROM Поставщики AS П WHERE П.ПN=Пк.ПN AND Гор LIKE 'М*') AND Д.ДN=П.ДN);
Покажем, как при помощи оператора EXISTS можно реализовать операции пересечения, разности и деления.
Пример. Пересечением таблиц Детали и Поставщики по полю Гор является множество городов, в которых есть и детали, и поставщики:
SELECT DISTINCT Д.Гор FROM Детали AS Д WHERE EXISTS (SELECT * FROM Поставщики П WHERE Д.Гор=П.Гор);
Разностью между этими таблицами по полю Гор является множество городов, в которых есть детали, но нет поставщиков:
SELECT DISTINCT Д.Гор FROM Детали Д WHERE NOT EXISTS (SELECT * FROM Поставщики П WHERE Д.Гор=П.Гор);
Операция пересечения может быть реализована и без оператора EXISTS:
SELECT DISTINCT Д.Гор FROM Детали Д WHERE (SELECT COUNT (*) FROM Поставщики П WHERE Д.Гор = П.Гор) >0;
(если количество найденных строк больше 0, значит они есть и оператор EXISTS принял бы значение “истина”).
При таком запросе производительность ниже, чем при использовании EXISTS, т.к. EXISTS возвращает результат, как только ему встретится хотя бы одна строка, удовлетворяющая условию, а COUNT (*) подсчитывает строки, просматривая таблицу до конца.
Пример реализации реляционной операции деления DIVIDED BY: Получить номера поставщиков, поставляющих все детали
SELECT DISTINCT Пк.ПN FROM Поставки AS Пк WHERE NOT EXISTS (SELECT Д.ДN FROM Детали AS Д WHERE NOT EXISTS (SELECT Пк1.ДN FROM Поставки AS Пк1 WHERE Пк1.ПN=Пк.ПN AND Пк1.ДN=Д.ДN));
Внешний запрос исследует каждый кортеж отношения Поставки и возвращает из него ПN, если вложенный запрос возвращает значение «Ложь». Вложенный запрос создает множество всех возможных значений ДN из отношения Детали. Из этого множества удаляются те значения ДN, которые состоят в паре с ПN в кортеже с тем же значением ПN, что и кортеж, рассматриваемый во внешнем запросе. Если рассматриваемый ПN комбинируется со всеми возможными значениями ДN, то результатом будет пустое множество и вложенный запрос возвратит значение «Ложь», т.е., не существует значений ДN, которые не состоят в паре с этим конкретным ПN.
Чтобы получить имена поставщиков, надо вложить этот запрос в другой:
SELECT П.Имя_П
FROM Поставщики AS П
WHERE П.ПN IN
(SELECT DISTINCT Пк.ПN FROM Поставки AS Пк WHERE NOT EXISTS (SELECT Д.ДN FROM Детали AS Д WHERE NOT EXISTS (SELECT Пк1.ДN FROM Поставки AS Пк1 WHERE Пк1.ПN=Пк.ПN AND Пк1.ДN=Д.ДN)));