- •Введение
- •Глава 1. Основные понятия баз данных
- •1.1. История возникновения баз данных
- •1.2. Модели данных
- •1.2.1. Иерархическая модель данных
- •1.2.2. Сетевая модель базы данных
- •1.2.3. Реляционная модель базы данных
- •1.2.4. Другие модели баз данных (ООСУБД)
- •2.1. История появления и развития SQL
- •Глава 2. SQL
- •2.2. Стандарты SQL
- •2.2.1. Стандарты ANSI/ISO
- •2.2.2. ODBC и консорциум SQL Access Group
- •2.2.3. JDBC и серверы приложений
- •2.3. SQL и переносимость
- •2.4. SQL и сети
- •2.4.1. Централизованная архитектура
- •2.4.2. Архитектура файлового сервера
- •2.4.3. Архитектура “клиент/сервер”
- •2.4.4. Многоуровневая архитектура
- •2.4.5. SQL и мэйнфреймы
- •2.4.7. SQL и UNIX
- •2.4.8. SQL и персональные компьютеры
- •2.4.9. SQL, хранилища данных и интеллектуальные ресурсы предприятия
- •2.4.10. SQL и интернет-приложения
- •2.5. Основы SQL
- •2.5.1. Использование SQL для извлечения информации из таблиц
- •2.5.2. Команда SELECT
- •2.5.3. Создание более сложных предикатов в предложении SELECT
- •2.5.4. Формирование вывода запросов
- •2.5.5. Агрегатные группы
- •2.6. Запросы к нескольким таблицам
- •2.6.1. Подзапросы
- •2.6.2. Использование операторов ANY, ALL и SOME
- •2.6.3. Использование предложения UNION
- •2.6.4. Ввод, удаление и изменение значения поля
- •2.7. DDL (Язык описания данных)
- •2.7.1. Создание таблиц
- •2.7.2. Индексы
- •2.7.3. Изменение структуры таблицы после ее создания
- •2.8. Ограничение данных
- •2.8.1. Ограничение таблиц
- •2.8.2. Установка значений по умолчанию
- •2.9. Поддержка целостности данных
- •2.9.1. Первичные ключи
- •2.9.2. Пользовательские представления
- •2.10. Модификация данных с помощью представлений
- •2.11. Разграничение доступа в базе данных
- •Глава 3. Математические основы реляционных баз данных
- •3.1. Отношения и их схемы
- •3.2. Реляционные операторы
- •3.2.1. Булевы операции
- •3.2.2. Оператор выбора
- •3.2.3. Оператор проекции
- •3.2.4. Оператор соединения
- •3.2.5. Другие операции на отношениях
- •3.2.6. Оператор деления
- •3.2.7. Оператор переименования атрибутов
- •3.2.8. Оператор эквисоединения
- •3.2.9. Расширения для сравнения на доменах
- •3.2.9.1. Расширение выбора
- •3.3. Реляционная алгебра
- •3.3.1. Дополнительные операторы
- •3.3.1.1. Оператор расщепления
- •3.3.1.2. Оператор FACTOR
- •3.4. Функциональные зависимости
- •3.4.1. Определение
- •3.4.2. Аксиомы вывода
- •3.4.3. Применение аксиом вывода
- •3.4.4. Выводы на основе аксиом вывода
- •3.4.6. Направленные ациклические графы вывода
- •3.4.7. Проверка принадлежности к замыканию множества функциональных зависимостей
- •3.5. Покрытия функциональных зависимостей
- •3.5.1. Покрытия и эквивалентность
- •3.5.2. Неизбыточные покрытия
- •3.5.3. Редуцированные покрытия
- •3.5.3.1. Посторонние атрибуты
- •3.5.3.3. Алгоритм построения редуцированного покрытия
- •3.5.3.4. Канонические покрытия
- •3.5.3.5. Структура неизбыточных покрытий
- •3.5.4. Минимальные покрытия
- •3.5.4.1. Прямая определяемость
- •3.5.4.2. Вычисление минимальных покрытий
- •3.5.4.3. Оптимальные покрытия
- •3.5.5. Составные функциональные зависимости
- •3.5.6. Кольцевые покрытия
- •3.6. Многозначные зависимости и зависимости соединения
- •3.6.1. Многозначные зависимости
- •3.6.2. Многозначные и функциональные зависимости
- •3.6.3. Аксиомы вывода для многозначных зависимостей
- •3.6.4. Только многозначные зависимости
- •3.6.5. Функциональные и многозначные зависимости
- •3.6.6. Зависимости соединения
- •3.7. Синтез схем реляционных баз данных
- •3.7.1. Базы данных и их схемы
- •3.7.2. Нормальные формы баз данных
- •3.7.2.1. Первая нормальная форма
- •3.7.2.2. Вторая нормальная форма
- •3.7.2.4. Нормальная форма Бойса - Кодда (НФБК)
- •3.7.2.5. Четвертая нормальная форма
- •3.7.2.3. Третья нормальная форма
- •3.8. Алгоритмы синтеза схем баз данных
- •3.8.1. Нормализация через декомпозицию
- •3.8.2. Недостатки нормализации через декомпозицию
- •3.8.3. Нормализация посредством синтеза
- •Глава 4. Система управления базами данных PostgreSQL
- •4.1. Установка
- •4.2. Запуск и останов сервера PostgreSQL
- •4.2.1. Утилита psql
- •4.2.2. Создание базы данных
- •4.3. Объекты базы данных
- •4.4. Функции и операторы
- •4.4.1. Логические операторы
- •4.4.2. Операторы сравнения
- •4.5. Клиентские приложения PostgreSQL
- •4.5.1. clusterdb
- •4.5.2. createdb
- •4.5.3. createuser
- •4.5.4. dropdb
- •4.5.5. dropuser
- •4.5.6. ecpg
- •4.5.7. pg_basebackup
- •4.5.8. pgbench
- •4.5.9. pg_config
- •4.5.10. pg_dump
- •4.5.11. pg_dumpall
- •4.5.12. pg_isready
- •4.5.13. pg_receivewal
- •4.5.14. pg_restore
- •4.5.15. psql
- •4.5.16. reindexdb
- •4.5.17. vacuumdb
- •4.6. Серверные приложения PostgreSQL
- •4.6.1. initdb
- •4.6.2. pg_archivecleanup
- •4.6.3. pg_checksums
- •4.6.4. pg_controldata
- •4.6.6. pg_resetwal
- •4.6.7. pg_rewind
- •4.6.8. pg_test_fsync
- •4.6.9. pg_test_timing
- •4.6.10. pg_upgrade
- •4.6.11. pg_waldump
- •4.6.12. postgres
- •4.6.13. postmaster
- •4.7. Серверное программирование
- •4.7.1. Расширение SQL
- •4.7.2. Триггеры
- •Заключение
- •Библиографический список
- 35 -
Можно использовать подзапросы внутри предложения HAVING. Эти подзапросы могут использовать свои собственные агрегатные функции, если они не производят нескольких значений, или использовать GROUP BY или HAVING. Примером этого служит следующий запрос, в котором находятся группы, у которых средний балл по группе выше среднего балла по всем студентам.
SELECT s.stgroup,AVG(gpa)
FROM students s |
||
GROUP BY stgroup |
||
HAVING AVG(gpa) > |
||
(SELECT AVG(gpa) FROM students); |
||
stgroup |
| |
avg |
---------+-------------------- |
||
345 |
| 4.8700000000000000 |
|
342 |
| 4.6250000000000000 |
|
(2 rows)
2.6.2. Использование операторов ANY, ALL и SOME
Если вы поймёте работу этих операторов, вы будете понимать все типы подзапросов предиката, используемых в SQL. Кроме того, вам будут представлены различные способы того, как данный запрос может быть сформирован с использованием различных типов подзапросов предиката.
ANY, ALL и SOME принимют подзапросы как аргументы и используются совместно с реляционными операциями. В этом отношении они напоминают оператор IN, когда тот используется с подзапросами: они берут все значения, выведенные подзапросом, и обрабатывают их как модуль. Однако в отличие от IN они могут использоваться только с подзапросами.
Операторы SOME и ANY взаимозаменяемы везде, и там, где мы используем ANY, SOME будет работать точно так же. Различие в терминологии состоит в том, чтобы позволить людям использовать тот термин, который является однозначным.
В примере ниже мы выбираем только те группы, для которых в таблице students имеется хотя бы один студент. Предположим, что мы добавили в таблицу stgroups запись о группе 311, причем в таблице students нет ни одного студента, который учится в этой группе.
SELECT * |
FROM stgroups ; |
|
stgroup |
| department |
| curator |
--------- |
+------------ |
+----------- |
340 |
| ЭВМ |
| Логинов |
|
|
- 36 - |
341 |
| ЭВМ |
| Кузьмин |
342 |
| ЭВМ |
| Гринченко |
344 |
| САПР |
| Бабаев |
345 |
| ВПМ |
| Макаров |
349 |
| АСУ |
| Маркин |
311 |
| РТФ |
| Езерский |
(7 rows) |
|
|
В результате следующего запроса не будет записи с группой 311, поскольку у нас нет ни одного обучающегося в этой группе.
SELECT * FROM stgroups WHERE stgroup = ANY
(SELECT stgroup FROM students );
stgroup |
| department |
| curator |
--------- |
+------------ |
+----------- |
342 |
| ЭВМ |
| Гринченко |
344 |
| САПР |
| Бабаев |
345 |
| ВПМ |
| Макаров |
349 |
| АСУ |
| Маркин |
(4 rows) |
|
|
Еще один часто используемый оператор - это ALL. С помощью ALL предикат будет верным, если каждое значение, выбранное подзапросом, удовлетворяет условию в предикате внешнего запроса. Если мы хотим пересмотреть наш предыдущий пример, чтобы вывести только тех студентов, чьи средние оценки фактически выше, чем у каждого студента в определенной группе (в примере это группа 345, в которой, правда, всего один студент), мы можем сформировать следующий запрос:
SELECT * FROM students WHERE gpa > All
(SELECT gpa FROM students
WHERE stgroup = '345'); |
|
|
||||
family |
| name |
| |
stgroup | |
gpa | sex |
||
--------- |
+-------- |
+ |
--------- |
+------ |
+ |
----- |
Балашов |
| Андрей | |
342 |
| |
5.00 | |
м |
|
(1 row) |
|
|
|
|
|
|
ALL чаще используется с неравенствами, нежели с равенствами, так как значение может быть "равным для всех" результатом подзапроса, только если все результаты фактически идентичны.
В SQL сказать, что значение больше (или меньше), чем любое (ANY) из набора значений, - то же самое, что сказать, что оно больше (или меньше), чем любое отдельное из этих значений. И наоборот, сказать, что значение не равно всему (ALL) набору значений, это то же, что сказать, что нет такого значения в наборе, которому оно равно.
-37 -
2.6.3.Использование предложения UNION
Ранее мы обсуждали различные способы вложения запросов друг в друга. Имеется другой способ объединения нескольких запросов - формирование их в объединение.
Рассмотрим использование предложения UNION в SQL. UNION отличается от подзапросов тем, что в нём ни один из двух (или более) запросов не управляется другим запросом. Все запросы выполняются независимо друг от друга, а уже вывод их объединяется. В примере мы объединяем результаты двух запросов. В первом выводятся все студенты группы 342, а во втором куратор этой группы.
SELECT family FROM students s WHERE s.stgroup='342'
UNION
SELECT curator FROM stgroups g WHERE g.stgroup='342';
family
--------------
Гринченко
Фахрудинова
Катеринченко
Никулкин
Балашов (5 rows)
С другой стороны, мы можем использовать константы в каждом из объединяемых запросов. Предположим, что нам надо отделить в предыдущем примере студентов от куратора, тогда будем добавлять в каждый запрос константное поле следующим образом:
SELECT family, 'студент' AS member FROM students s WHERE s.stgroup='342'
UNION
SELECT curator, 'куратор' FROM stgroups g WHERE g.stgroup='342';
family |
| member |
-------------- |
+--------- |
Фахрудинова |
| студент |
Гринченко |
| куратор |
Балашов |
| студент |
Катеринченко |
| студент |
Никулкин |
| студент |
(5 rows) |
|
- 38 -
Обратите внимание, что с помощью оператора AS имя константному полю задано только в первом запросе, а на результат второго запроса оно распространяется автоматически.
Когда два (или более) запроса подвергаются объединению, их столбцы вывода должны быть совместимы для объединения. Это означает, что каждый запрос должен указывать одинаковое количество столбцов и в том же порядке и каждый должен иметь тип, совместимый с каждым.
2.6.4. Ввод, удаление и изменение значения поля
Значения могут быть помещены и удалены из полей тремя командами языка DML (язык манипулирования данными):
INSERT (ВСТАВИТЬ),
UPDATE (МОДИФИЦИРОВАТЬ), DELETE (УДАЛИТЬ).
Все значения в SQL вводятся с использованием команды модификации INSERT. В самой простой форме INSERT использует следующий синтаксис:
INSERT INTO VALUES (<value>, . . .);
Так, для ввода данных об еще одном студенте следует использовать следующую команду:
INSERT INTO students
VALUES ('Дубоделов','Андрей','345',4.87,'м');
Если вам нужно ввести пустое значение (NULL), вы вводите его точно так же, как и обычное значение. Предположим, что ещё нет значения среднего балла для студентки Макаркиной. Вы можете вставить в строку значение=NULL в это поле следующим образом:
INSERT INTO students
VALUES ('Макаркина','Надежда','344',NULL,'ж');
INSERT 0 |
1 |
|
|
|
|
SELECT * |
FROM students ; |
|
|
|
|
family |
|
| name |
| stgroup | gpa |
| sex |
|
-------------- |
|
+--------- |
+--------- |
+------ |
+----- |
Балашов |
|
| Андрей |
| 342 |
| 5.00 |
| м |
Катеринченко |
| Андрей |
| 342 |
| 4.59 |
| м |
|
Колычева |
|
| Лия |
| 349 |
| 4.38 |
| ж |
Малин |
|
| Сергей |
| 345 |
| 4.87 |
| м |
Никулкин |
|
| Сергей |
| 342 |
| 4.79 |
| м |
Фахрудинова |
| Тамара |
| 342 |
| 4.12 |
| ж |
|
Чертков |
|
| Максим |
| 344 |
| 4.31 |
| м |
Дубоделов |
| Андрей |
| 345 |
| 4.87 |
| м |
|
Макаркина |
| Надежда | 344 |
| |
| ж |
||
(9 rows) |
|
|
|
|
|
- 39 -
Так как значение NULL - это специальный маркёр, а не просто символьное значение, оно не заключается в одинарные кавычки.
Вы можете также использовать команду INSERT, чтобы получать или выбирать значения из одной таблицы и помещать их в другую для использования их вместе с запросом. Чтобы сделать это, вы просто заменяете предложение VALUES (из предыдущего примера) на соответствующий запрос:
INSERT INTO boys
SELECT family,name FROM students WHERE sex='м'; INSERT 0 6
SELECT * FROM boys ;
family |
| name |
-------------- |
+-------- |
Балашов |
| Андрей |
Катеринченко |
| Андрей |
Малин |
| Сергей |
Никулкин |
| Сергей |
Чертков |
| Максим |
Дубоделов |
| Андрей |
(6 rows) |
|
Здесь мы в созданную ранее пустую таблицу boys вставляем из таблицы students записи обо всех студентах мужского пола.
Вы можете удалять строки из таблицы командой модификации DELETE. Она может удалять только строки, а не индивидуальные значения полей, так что параметр поля является необязательным или недоступным. Чтобы удалить всё содержание таблицы, вы можете ввести следующую команду:
DELETE FROM boys ; DELETE 6
SELECT * FROM boys ; family | name
--------+------
(0 rows)
Теперь, когда таблица пуста, её можно окончательно удалить командой DROP TABLE . Обычно вам нужно удалить только некоторые определённые строки из таблицы. Чтобы определить, какие строки будут удалены, вы используете предикат так же, как вы это делали для запросов. Например, чтобы удалить студентов с именем Андрей из таблицы, вы можете ввести:
DELETE FROM boys WHERE name='Андрей'; DELETE 3
SELECT * FROM boys ;
- 40 -
family |
| name |
---------- |
+-------- |
Малин |
| Сергей |
Никулкин |
| Сергей |
Чертков |
| Максим |
(3 rows) |
|
Теперь рассмотрим, как можно изменять значения строк с помощью команды UPDATE. Предположим, что всех студентов из таблицы надо перевести в группу 340, тогда надо выполнить следующую команду:
UPDATE students SET stgroup = '340'; |
|
|||
UPDATE 9 |
|
|
|
|
SELECT * FROM students ; |
|
|
|
|
family |
| name |
| stgroup | gpa |
| sex |
|
-------------- |
+--------- |
+--------- |
+------ |
+----- |
Балашов |
| Андрей |
| 340 |
| 5.00 |
| м |
Катеринченко |
| Андрей |
| 340 |
| 4.59 |
| м |
Колычева |
| Лия |
| 340 |
| 4.38 |
| ж |
Малин |
| Сергей |
| 340 |
| 4.87 |
| м |
Никулкин |
| Сергей |
| 340 |
| 4.79 |
| м |
Фахрудинова |
| Тамара |
| 340 |
| 4.12 |
| ж |
Чертков |
| Максим |
| 340 |
| 4.31 |
| м |
Дубоделов |
| Андрей |
| 340 |
| 4.87 |
| м |
Макаркина |
| Надежда | 340 |
| |
| ж |
|
(9 rows) |
|
|
|
|
На практике такое глобальное изменение значений в таблицах |
||||
используется крайне редко. Чаще всего модифицируются только определенные строки. В примере мы переведем студентку Макаркину в группу 340 и заодно наконец установим для нее средний балл:
UPDATE students |
|
|
|
|
SET stgroup = '340', gpa = 4.55 |
|
|||
WHERE family = 'Макаркина'; |
|
|
||
UPDATE 1 |
|
|
|
|
SELECT * FROM students ; |
|
|
|
|
family |
| name |
| stgroup | gpa |
| sex |
|
-------------- |
+--------- |
+--------- |
+------ |
+----- |
Балашов |
| Андрей |
| 342 |
| 5.00 |
| м |
Катеринченко |
| Андрей |
| 342 |
| 4.59 |
| м |
Колычева |
| Лия |
| 349 |
| 4.38 |
| ж |
Малин |
| Сергей |
| 345 |
| 4.87 |
| м |
Никулкин |
| Сергей |
| 342 |
| 4.79 |
| м |
Фахрудинова |
| Тамара |
| 342 |
| 4.12 |
| ж |
Чертков |
| Максим |
| 344 |
| 4.31 |
| м |
Дубоделов |
| Андрей |
| 345 |
| 4.87 |
| м |
Макаркина |
| Надежда | 340 |
| 4.55 |
| ж |
|
(9 rows) |
|
|
|
|
