Рассмотрим на множестве вещественных чисел
Пример 1
. Рассмотрим на множестве вещественных чисел
![](images/image_74.gif)
![](images/image_75.gif)
Условия 1-3, очевидно, выполняются, поэтому данное отношение является отношением эквивалентности. Каждый класс эквивалентности этого отношения состоит из одного числа.
Пример 1
. Рассмотрим отношение "Сотрудники" заданное на доменах "Номер_сотрудника", "Фамилия", "Зарплата", "Номер_отдела". Т.к. все домены различны, то имена атрибутов отношения удобно назвать так же, как и соответствующие домены. Заголовок отношения имеет вид:
Сотрудники (Номер_сотрудника, Фамилия, Зарплата, Номер_отдела)
Пусть в данный момент отношение содержит три кортежа:
(1,Иванов, 1000, 1)
(2, Петров, 2000, 2)
(3, Сидоров, 3000, 1)
такое отношение естественным образом представляется в виде таблицы:
Пример 1
.
Следующий оператор возвращает неименованное отношение, в котором атрибут
![](images/image_236.gif)
![Пример 1](images/image_237.gif)
:
![](images/image_238.gif)
Пример 1
. В отношении СОТРУДНИКИ_ОТДЕЛЫ_ПРОЕКТЫ можно привести следующие примеры функциональных зависимостей:
Зависимость атрибутов от ключа отношения:{Н_СОТР, Н_ПРО}
ФАМ
{Н_СОТР, Н_ПРО}
Н_ОТД
{Н_СОТР, Н_ПРО}
ТЕЛ
{Н_СОТР, Н_ПРО}
ПРОЕКТ
{Н_СОТР, Н_ПРО}
Н_ЗАДАН
Зависимость атрибутов, характеризующих сотрудника от табельного номера сотрудника:
Н_СОТР
ФАМ
Н_СОТР
Н_ОТД
Н_СОТР
ТЕЛ
Зависимость наименования проекта от номера проекта:
Н_ПРО
ПРОЕКТ
Зависимость номера телефона от номера отдела:
Н_ОТД
ТЕЛ
Замечание. Приведенные функциональные зависимости не выведены из внешнего вида отношения, приведенного в таблице 1. Эти зависимости отражают взаимосвязи, обнаруженные между объектами предметной области и являются дополнительными ограничениями, определяемыми предметной областью. Таким образом, функциональная зависимость - семантическое понятие. Она возникает, когда по значениям одних данных в предметной области можно определить значения других данных. Например, зная табельный номер сотрудника, можно определить его фамилию, по номеру отдела можно определить телефона. Функциональная зависимость задает дополнительные ограничения на данные, которые могут храниться в отношениях. Для корректности базы данных (адекватности предметной области) необходимо при выполнении операций модификации базы данных проверять все ограничения, определенные функциональными зависимостями.
Пример 1
. Пусть требуется хранить данные о поставках деталей некоторыми поставщиками. Предположим, что наименования поставщиков являются уникальными. Кроме того, каждый поставщик имеет свой уникальный номер. Данные о поставках можно хранить в следующем отношении:
Рассмотрим более сложное отношение эквивалентности.
Пример 2
. Рассмотрим более сложное отношение эквивалентности. На множестве целых чисел ![](images/image_77.gif)
и
равны по модулю n, если их остатки при делении на n равны. Например, по модулю 5 равны числа 2, 7, 12 и т.д.
Условия 1-3 легко проверяются, поэтому равенство по модулю является отношением эквивалентности. Предикат этого отношения имеет вид:
Классы эквивалентности этого отношения состоят из чисел, дающих при делении на n одинаковые остатки. Таких классов ровно n:
[0] = {0, n, 2n, …}
[1] = {1, n+1, 2n+1, …}[n-1] = {n-1, n+n-1, 2n+n-1, …}
Пример 2
. Пусть даны два отношения ![](images/image_248.gif)
с информацией о сотрудниках:
Пример 2
. Вставка в таблицу нескольких строк, выбранных из другой таблицы (в таблицу TMP_TABLE вставляются данные о поставщиках из таблицы P, имеющие номера, большие 2):
INSERT INTO
TMP_TABLE (PNUM, PNAME)
SELECT PNUM, PNAME
FROM P
WHERE P.PNUM>2;
Пример 2
. Пусть дано отношение
Пример 2
. Предположим, что нам по- прежнему необходимо учитывать поставки, но каждый акт поставки должен иметь некоторый уникальный номер (назовем его "сквозной номер поставки"). Отношение может иметь следующий вид:
Простым примером отношения порядка является
Пример 3
. Простым примером отношения порядка является отношение, задаваемое обычным неравенством ![](images/image_105.gif)
. Заметим, что для любых чисел ![](images/image_107.gif)
выполняется либо ![](images/image_109.gif)
, т.е. любые два числа сравнимы между собой. Такие отношения называются отношениями полного порядка.
Предикат данного отношения есть просто утверждение
Пример 3
. Для тех же отношений ![](images/image_265.gif)
, что и в предыдущем примере пересечение имеет вид:
Пример 3
. Обновление нескольких строк в таблице:
UPDATE P
SET PNAME = "Пушников"
WHERE P.PNUM = 1;
Пример 3
. Рассмотрим следующее отношение
Пример 3
. Каждый сотрудник имеет уникальный табельный номер.
представляет ограничение...
Пример 3 представляет ограничение, реализующее целостность сущности. Пример 4 представляет ограничение, реализующее ссылочную целостность. Другие ограничения являются достаточно произвольными утверждениями (примеры 2 и 5). Любое ограничение целостности является семантическим понятием, т.е. появляется как следствие определенных свойств объектов предметной области и/или их взаимосвязей.
быть начальником" является отношением порядка.
Пример 4
. Рассмотрим на множестве ![](images/image_112.gif)
предшествует сотруднику
![](images/image_115.gif)
![](images/image_116.gif)
Назовем такое отношение "быть начальником". Легко проверить, что отношение " быть начальником" является отношением порядка. Заметим, что в отличие от предыдущего примера, существуют такие пары сотрудников ![](images/image_118.gif)
, для которых не выполняется ни ![](images/image_120.gif)
(например, если ![](images/image_122.gif)
являются сослуживцами). Такие отношения, в которых есть несравнимые между собой элементы, называют отношениями частичного порядка.
Пример 4
. Для тех же отношений ![](images/image_274.gif)
, что и в предыдущем примере вычитание имеет вид:
Пример 4
. Удаление нескольких строк в таблице:
DELETE FROM P
WHERE P.PNUM = 1;
Пример 4
. Сотрудник обязан числиться в одном отделе.
о взаимоотношения данных молодых людей
Пример 5
. Пусть множество
Вовочка любит Вовочку (эгоист).
Петя любит Машу (взаимно).
Маша любит Петю (взаимно).
Маша любит Машу (себя не забывает).
Лена любит Петю (несчастная любовь).
Информацию о взаимоотношения данных молодых людей можно описать бинарным отношением "любить", заданном на множестве
Способ 1. Перечисление фактов в виде произвольного текста (как это сделано выше).
Способ 2. В виде графа взаимоотношений:![](images/image_134.gif)
Рисунок 1 Граф взаимоотношений
Способ 3. При помощи матрицы взаимоотношений:
Пример 5
. Пусть даны два отношения ![](images/image_294.gif)
с информацией о поставщиках и деталях:
Пример 5
. Удаление всех строк в таблице:
DELETE FROM P;
Пример 5
. Сумма накладной обязана равняться сумме произведений цен товаров на количество товаров для всех товаров, входящих в накладную.
Как видно из этих примеров, некоторые из ограничений целостности являются ограничениями реляционной модели данных (см. гл. 3).
В некотором университете на математическом
Пример 6
. В некотором университете на математическом факультете учатся студенты Иванов, Петров и Сидоров. Лекции им читают преподаватели Пушников, Цыганов и Шарипов, причем известны следующие факты:
Пушников читает лекции по алгебре и базам данных, соответственно, 40 и 80 часов в семестр.
Цыганов читает лекции по геометрии, 50 часов в семестр.
Шарипов читает лекции по алгебре и геометрии, соответственно, 40 и 50 часов в семестр.
Студент Иванов посещает лекции по алгебре у Шарипова и по базам данных у Пушникова.
Студент Петров посещает лекции по алгебре у Пушникова и по геометрии у Цыганова.
Студент Сидоров посещает лекции по геометрии у Цыганова и по базам данных у Пушникова.
Для того чтобы формально описать данную ситуацию (например, в целях разработки информационной системы, учитывающей данные о ходе учебного процесса), введем три множества:
Множество преподавателей
Множество предметов
Множество студентов
Имеющиеся факты можно разделить на две группы. 1 группа (факты 1-3) - факты о преподавателях, 2 группа (факты 4-6) - факты о студентах.
Для того чтобы отразить факты 1-3 (характеризующие преподавателей и читаемые ими лекции), введем отношение ![](images/image_138.gif)
, где ![](images/image_140.gif)
тогда и только тогда, когда преподаватель ![](images/image_142.gif)
в количестве ![](images/image_144.gif)
удобно представить в виде таблицы:
Пример 6
. Пусть дано отношение
Пример 6
. Атрибут "Возраст сотрудника" в таблице "Спецподразделение", может иметь дополнительное ограничение " Возраст сотрудника не менее 25 и не более 45", помимо того, что этот атрибут уже имеет ограничение, определяемое доменом - "Возраст сотрудника не менее 18 и не более 65".
Приведенное ограничение кортежа, по сути, является дополнительным ограничением на значения одного атрибута. В этом случае допустимы два решения. Можно объявить новый домен "Возраст сотрудника спецподразделения" и тогда ограничение кортежа становится ограничением домена и атрибута, либо рассматривать это ограничение именно как ограничение кортежа. Оба решения имеют свои положительные и отрицательные стороны.
Замечание. Тут имеются некоторые возможности для оптимизации. Формально, при изменении значения данного атрибута необходимо проверить два ограничения - ограничение атрибута и ограничение кортежа. Но в данном случае ограничение кортежа сильнее ограничения атрибута и достаточно проверить только ограничение кортежа. Разумно построенная СУБД могла бы выявлять такие случаи и уменьшать лишнюю работу.
и конструкций могут использоваться при
Пример 7
. Пусть множество ![](images/image_170.gif)
причем некоторые из деталей и конструкций могут использоваться при сборке других конструкций. Взаимосвязь деталей описывается отношением
Пример 7
. Пусть дано отношение
Пример 7
. Выбрать все строки из таблицы поставщиков, удовлетворяющих некоторому условию (ключевое слово WHERE…):
SELECT *
FROM P
WHERE P.PNUM > 2;
Замечание. В качестве условия в разделе WHERE можно использовать сложные логические выражения, использующие поля таблиц, константы, сравнения (>, <, = и т.д.), скобки, союзы AND и OR, отрицание NOT.
Пример 7
. Для отношения "Сотрудники" можно сформулировать следующее ограничение: если атрибут "Должность" принимает значение "Директор", то атрибут "Зарплата" содержит значение не менее 1000$.
Это ограничение связывает два атрибута одного кортежа.
и поставляемых деталях. Пусть поставщикам
Пример 8
. Рассмотрим некоторую компанию, в которой хранятся данные о поставщиках и поставляемых деталях. Пусть поставщикам и деталям присвоен некий статус. Пусть бизнес компании организован таким образом, что поставщики имеют право поставлять только те детали, статус которых не выше статуса поставщика (смысл этого может быть в том, что хороший поставщик с высоким статусом может поставлять больше разновидностей деталей, а плохой поставщик с низким статусом может поставлять только ограниченный список деталей, важность которых (статус детали) не очень высока).
Пример 8
. Выбрать некоторые колонки из исходной таблицы (указание списка отбираемых колонок):
SELECT P.NAME
FROM P;
Замечание. В результате получим таблицу с одной колонкой, содержащую все наименования поставщиков.
Замечание. Если в исходной таблице присутствовало несколько поставщиков с разными номерами, но одинаковыми наименованиями, то в результатирующей таблице будут строки с повторениями - дубликаты строк автоматически не отбрасываются.
Пример 8
. В накладной можно установить следующую взаимосвязь атрибутов - "Цена*Количество=Сумма", связывающую атрибуты "Цена", "Количество", "Сумма".
Данный пример кажется неестественным, т.к. сумма является явно избыточным атрибутом, значение которого просто выводятся из значений других атрибутов. Поэтому кажется, что лучше хранить только два базовых атрибута "Цена" и "Количество", а сумму вычислять во время выполнения запросов по мере необходимости. Так, собственно, требует реляционная теория, стремящаяся свести избыточность к минимуму. В практике, однако, дело обстоит сложнее. Например, каждая строка реальной накладной может содержать следующие данные о товаре:
Пусть имеются отношения
Пример 9
. Пусть имеются отношения ![](images/image_362.gif)
и
Пример 9
. Выбрать некоторые колонки из исходной таблицы, удалив из результата повторяющиеся строки (ключевое слово DISTINCT):
SELECT DISTINCT P.NAME
FROM P;
Замечание. Использование ключевого слова DISTINCT приводит к тому, что в результатирующей таблице будут удалены все повторяющиеся строки.
Пример 9
. Ограничение целостности сущности (см. гл. 3), задаваемое потенциальным ключом отношения, является ограничением отношения, т.к. для его проверки необходимо иметь информацию обо всех кортежах отношения (более точно, обо всех занятых в данный момент значениях потенциального ключа).
В предыдущем примере ответ на
Пример 10
. В предыдущем примере ответ на вопрос "какие детали поставляются поставщиками", более просто записывается в виде естественного соединения трех отношений
Пример 10
. Использование скалярных выражений и переименований колонок в запросах (ключевое слово AS…):
SELECT
TOVAR.TNAME,
TOVAR.KOL,
TOVAR.PRICE,
"=" AS EQU,
TOVAR.KOL*TOVAR.PRICE AS SUMMA
FROM TOVAR;
В результате получим таблицу с колонками, которых не было в исходной таблице TOVAR:
Пример 10
. Ограничение целостности, определяемые наличием функциональных, многозначных зависимостей и зависимостей соединения, являются ограничениями отношения.
и поставками ответим на вопрос,
Пример 11
. В примере с поставщиками, деталями и поставками ответим на вопрос, "какие поставщики поставляют все детали?".
В качестве делимого возьмем проекцию
Пример 11
.Упорядочение результатов запроса (ключевое слово ORDER BY…):
SELECT
PD.PNUM,
PD.DNUM,
PD.VOLUME
FROM PD
ORDER BY DNUM;
В результате получим следующую таблицу, упорядоченную по полю DNUM:
Пример 11
. Предположим, что в отношении PERSON (см. пример 1) задано следующее ограничение - в каждом отделе должно быть не менее двух сотрудников. Это ограничение можно сформулировать так - количество строк с одинаковым значением Dept_Id должно быть не меньше 2.
Замечание. Для того чтобы ввести в действие (объявить) это ограничение, необходимо, чтобы в отношение уже были вставлены некоторые кортежи.
Упорядочение результатов запроса по нескольким
Пример 12
. Упорядочение результатов запроса по нескольким полям с возрастанием или убыванием (ключевые слова ASC, DESC):
SELECT
PD.PNUM,
PD.DNUM,
PD.VOLUME
FROM PD
ORDER BY
DNUM ASC,
VOLUME DESC;
В результате получим таблицу, в которой строки идут в порядке возрастания значения поля DNUM, а строки, с одинаковым значением DNUM идут в порядке убывания значения поля VOLUME:
Пример 12
. Ограничение целостности, определяемое требованием, что некоторая таблица должна быть не пуста, являются ограничениями отношения.
Проверка ограничения. К моменту проверки ограничения отношения должны быть проверены ограничения целостности кортежей этого отношения.
Ограничение отношения может быть как немедленно проверяемым ограничением, так и ограничением с отложенной проверкой.
Ограничение отношения, являющееся ограничением потенциального ключа (пример 9) является немедленно проверяемым ограничением.
Ограничение, определенное наличием функциональной зависимости атрибутов также является немедленно проверяемым ограничением.
Ограничения же, определенные многозначной зависимостью или зависимостью соединения являются ограничениями с отложенной проверкой. Действительно, эти ограничения требуют, чтобы кортежи вставлялись и удалялись целыми группами (см. гл. 7). Это невозможно сделать, если выполнять проверку после каждой одиночной вставки или удаления кортежа.
Ограничение в примере 11 кажется немедленно проверяемым. Действительно, можно сразу после вставки или удаления кортежа проверить, выполняется ли ограничение, и, если оно не выполняется, то откатить операцию. Но, однако, в этом случае, невозможно вставить ни один новый кортеж для нового отдела. В новый отдел необходимо вставить сразу не менее двух сотрудников. Таким образом, это ограничение с отложенной проверкой.
Ограничение из примера 12 имеет смысл проверять только при удалении кортежей из отношения. Это ограничение может быть как немедленно проверяемым, так и отложенным.
Получить имена поставщиков, поставляющих по
Пример 13
. Получить имена поставщиков, поставляющих по крайней мере одну гайку.Решение:
Ответ на этот запрос можно получить и иначе:
Пример 13
. Естественное соединение таблиц (способ 1 - явное указание условий соединения):
SELECT
P.PNUM,
P.PNAME,
PD.DNUM,
PD.VOLUME
FROM P, PD
WHERE P.PNUM = PD.PNUM;
В результате получим новую таблицу, в которой строки с данными о поставщиках соединены со строками с данными о поставках деталей:
Пример 13
. Ограничение целостности ссылок (см. гл. 3), задаваемое внешним ключом отношения, является ограничением базы данных.
Получить имена поставщиков, поставляющих все
Пример 14
. Получить имена поставщиков, поставляющих все детали.Решение:
Пример 14
. Естественное соединение таблиц (способ 2 - ключевые слова JOIN… USING…):
SELECT
P.PNUM,
P.PNAME,
PD.DNUM,
PD.VOLUME
FROM P JOIN PD USING PNUM;
Замечание. Ключевое слово USING позволяет явно указать, по каким из общих колонок таблиц будет производиться соединение.
Пример 14
. Ограничение на таблицы DEPART и PERSON из примера 1 является отношением базы данных, т.к. оно связывает данные, размещенные в различных таблицах.
Проверка ограничения. К моменту проверки ограничения базы данных должны быть проверены ограничения целостности отношений.
Ограничение базы данных может быть как немедленно проверяемым ограничением, так и ограничением с отложенной проверкой.
Ограничение отношения, являющееся ограничением внешнего ключа может быть как немедленно проверяемым ограничением, так и отложенным ограничением. Действительно, в простейшем случае, если кортеж ![](images/image_797.gif)
должен ссылаться на кортеж ![](images/image_799.gif)
, то проверку ограничения ссылочной целостности можно производить сразу после любой из операций вставки, обновления или удаления в любом из отношений ![](images/image_801.gif)
. В более сложном случае, предположим, что кортеж ![](images/image_803.gif)
должен ссылаться на кортеж ![](images/image_805.gif)
, а кортеж ![](images/image_807.gif)
должен в свою очередь ссылаться на кортеж ![](images/image_809.gif)
(циклическая ссылка). Очевидно, что сразу после вставки кортежа ![](images/image_811.gif)
ссылочная целостность обязательно нарушена, т.к. кортежа ![](images/image_813.gif)
. Проверку ссылочной целостности можно провести только посл
завершения транзакции, состоящей из последовательности операций:
вставки кортежа ![](images/image_815.gif)
с нулевой ссылкой на отношение
вставки кортежа ![](images/image_818.gif)
со ссылкой на кортеж ![](images/image_820.gif)
,
исправления ссылки в кортеже ![](images/image_822.gif)
.
Ограничение, приведенное в примере 1, может быть только ограничением с отложенной проверкой.
Получить имена поставщиков, не поставляющих
Пример 15
. Получить имена поставщиков, не поставляющих деталь номер 2.Решение:
Ответ на этот запрос можно получить и пошагово:
![](images/image_401.gif)
![](images/image_402.gif)
![](images/image_403.gif)
![](images/image_404.gif)
![](images/image_405.gif)
![](images/image_406.gif)
Пример 15
. Естественное соединение таблиц (способ 3 - ключевое слово NATURAL JOIN):
SELECT
P.PNUM,
P.PNAME,
PD.DNUM,
PD.VOLUME
FROM P NATURAL JOIN PD;
Замечание. В разделе FROM не указано, по каким полям производится соединение. NATURAL JOIN автоматически соединяет по всем одинаковым полям в таблицах.
являются наименования химических веществ, значениями
Пример 16
. Пусть имеется отношение ХИМИЧЕСКИЙ_СОСТАВ_ВЕЩЕСТВ с набором атрибутов (Наименование вещества, Водород, Гелий, …, 105_элемент). Значением атрибута "Вещество" являются наименования химических веществ, значениями остальных атрибутов - процентный состав соответствующих элементов в этом веществе. Такое отношение могло бы иметь, к примеру, следующий вид:
Пример 16
. Естественное соединение трех таблиц:
SELECT
P.PNAME,
D.DNAME,
PD.VOLUME
FROM
P NATURAL JOIN PD NATURAL JOIN D;
В результате получим следующую таблицу:
Рассмотрим отношение, описывающее сотрудников некоего
Пример 17
. Рассмотрим отношение, описывающее сотрудников некоего предприятия. Отношение содержит данные о табельном номере сотрудника, фамилии, должности и табельном номере руководителя сотрудника – СОТРУДНИКИ (ТАБ_НОМ, ФАМИЛИЯ, ДОЛЖНОСТЬ, ТАБ_НОМ_РУК):
Пример 17
. Прямое произведение таблиц:
SELECT
P.PNUM,
P.PNAME,
D.DNUM,
D.DNAME
FROM P, D;
В результате получим следующую таблицу:
Соединение таблиц по произвольному условию.
Пример 18
. Соединение таблиц по произвольному условию. Рассмотрим таблицы поставщиков и деталей, которыми присвоен некоторый статую (см. пример 8 из предыдущей главы):
Пример 18
. Приведенный ниже оператор создает домен Salary на основе целочисленного типа данных, причем значения из этого домена не могут принимать неположительные значения (но могут принимать значение NULL!). По умолчанию это ограничение проверяется немедленно, но может быть и отложенным:
CREATE DOMAIN Salary AS integer CHECK (VALUE > 0) DEFERRABLE INITIALLY IMMEDIATEALTER DOMAIN Имя домена
{SET DEFAULT Значение по умолчанию}
| {DROP DEFAULT}
| {ADD [Имя ограничения] Ограничение check [Атрибуты ограничения]}
| {DROP CONSTRAINT Имя ограничения}Этот оператор изменяет имеющийся домен. Стандарт запрещает вносить несколько изменений одной командой ALTER DOMAIN. Т.е. если требуется удалить ограничение CHECK и добавить значение по умолчанию, то придется выполнить два оператора ALTER DOMAIN.DROP DOMAIN Имя домена CASCADE | RESTRICTЭтот оператор уничтожает имеющийся домен. Если указана опция RESTRICT, то домен не уничтожается, если имеются ссылки на него из столбцов таблиц. Если указана опция CASCADE, то происходят следующие действия:
Тип данных домена передается столбцам, основанным на этом домене.
Если столбец не имеет значения по умолчанию, а для домена значение по умолчанию определено, то оно становится значением по умолчанию для столбца.
Все ограничения домена становятся ограничениями столбца.
CREATE TABLE Имя таблицы
( {
City_Id INTEGER REFERENCES City ON
Пример 19
.
CREATE TABLE Salespeaple
(Salespeaple_Id Id_Nums PRIMARY KEY,
Fam CHAR(20) NOT NULL,
Im CHAR(15),
BirthDate DATE,
Salary Salary_Domain DEFAULT 1000,
City_Id INTEGER REFERENCES City ON UPDATE CASCADE ON DELETE RESTRICT,
District_Id INTEGER,
CONSTRAINT AltKey UNIQUE(Fam, Im, BirthDate),
CHECK (City_Id IS NOT NULL OR District_Id IS NOT NULL),
FOREIN KEY District_Id REFERENCES District ON UPDATE CASCADE ON DELETE RESTRICT)
Этот оператор создает таблицу Salespeaple с колонками (Salespeaple_Id, Fam, Im, BirthDate, Salary, City_Id, District_Id) и следующими ограничениями:
Колонка Salespeaple_Id наследует все ограничения домена Id_Nums. Кроме того, эта колонка образует первичный ключ таблицы (следовательно, не допускает NULL-значений).
Колонка Fam не допускает NULL-значений.
Колонка Salary наследует все ограничения домена Salary_Domain. Кроме того, эта колонка имеет значения по умолчанию1000.
Колонка City_Id является внешним ключом, ссылающимся на первичный ключ таблицы City. При изменении первичного ключа в таблице City соответствующие значения внешнего ключа в таблице Salespeaple будут каскадно изменены. При удалении строки из таблицы City будет выполняться проверка, нет ли ссылок на удаляемую строку из таблицы Salespeaple. Если такие ссылки найдутся, то операция удаления в таблице City будет отвергнута.
Колонка District_Id также является внешним ключом, ссылающимся на первичный ключ таблицы District. Этот внешний ключ, в отличие от предыдущего, определен как ограничение таблицы. Действия, определенные по ссылке аналогичны предыдущим.
Колонки (Fam, Im, BirthDate) образуют альтернативный ключ таблицы. Это ограничение имеет наименование AltKey.
Колонки City_Id и District_Id не могут одновременно принимать NULL-значения (хотя каждая из них по отдельности допускает использование NULL-значений).
ALTER TABLE Имя таблицы
{ADD [COLUMN]
Отобрать все пары поставщиков...
Таблица 10
PNAME1
PSTATUS1
PNAME2
PSTATUS2
Иванов |
4 |
Петров |
1 |
Иванов |
4 |
Сидоров |
2 |
Сидоров |
2 |
Петров |
1 |
Рассмотрим ситуацию, когда некоторые поставщики
Пример 20
. Рассмотрим ситуацию, когда некоторые поставщики (назовем их контрагенты) могут выступать как в качестве поставщиков деталей, так и в качестве получателей. Таблицы, хранящие данные могут иметь следующий вид:
Пример 20
.CREATE ASSERTION Check_Pay CHECK (Salespeaple.Salary IS NOT NULL) OR
(Salespeaple. Commission IS NOT NULL) DEFERRABLE INITIALLY IMMEDIATEDROP ASSERTION Имя утвержденияЭтот оператор позволяет удалять имеющееся утверждение.COMMIT WORKЭтот оператор фиксирует транзакцию. При этом проверяются все отложенные до конца транзакции ограничения. Если одно из ограничений не выполняется, то транзакция откатывается.SET CONSTRAINT {Имя ограничения.,.. | ALL}
{DEFERRED | IMMEDIATE}Этот оператор позволяет во время выполнения транзакции менять момент проверки всех (ALL) или некоторых ограничений. Этот оператор действует только на ограничения, определенные как DEFERRABLE (потенциально откладываемые). Если ограничение A находилось в состоянии IMMEDIATE (немедленно проверяемое), то оператор SET CONSTRAINT A DEFERRED переводит его в состояние DEFERRED (с отложенной проверкой) и тогда все операции, потенциально могущие нарушить это ограничение, будут выполняться без проверки. Проверка будет произведена в конце транзакции или в момент подачи команды SET CONSTRAINT A IMMEDIATE.
и одной строкой, содержащей количество
Пример 21
. Получить общее количество поставщиков (ключевое слово COUNT):
SELECT COUNT(*) AS N
FROM P;
В результате получим таблицу с одним столбцом и одной строкой, содержащей количество строк из таблицы P:
и среднее количества поставляемых деталей
Пример 22
. Получить общее, максимальное, минимальное и среднее количества поставляемых деталей (ключевые слова SUM, MAX, MIN, AVG):
SELECT
SUM(PD.VOLUME) AS SM,
MAX(PD.VOLUME) AS MX,
MIN(PD.VOLUME) AS MN,
AVG(PD.VOLUME) AS AV
FROM PD;
В результате получим следующую таблицу с одной строкой:
Для каждой детали получить суммарное
Пример 23
. Для каждой детали получить суммарное поставляемое количество (ключевое слово GROUP BY…):
SELECT
PD.DNUM,
SUM(PD.VOLUME) AS SM
GROUP BY PD.DNUM;
Этот запрос будет выполняться следующим образом. Сначала строки исходной таблицы будут сгруппированы так, чтобы в каждую группу попали строки с одинаковыми значениями DNUM. Потом внутри каждой группы будет просуммировано поле VOLUME. От каждой группы в результатирующую таблицу будет включена одна строка:
Получить номера деталей, суммарное поставляемое
Пример 24
. Получить номера деталей, суммарное поставляемое количество которых превосходит 400 (ключевое слово HAVING…):
Замечание. Условие, что суммарное поставляемое количество должно быть больше 400 не может быть сформулировано в разделе WHERE, т.к. в этом разделе нельзя использовать агрегатные функции. Условия, использующие агрегатные функции должны быть размещены в специальном разделе HAVING:
SELECT
PD.DNUM,
SUM(PD.VOLUME) AS SM
GROUP BY PD.DNUM
HAVING SUM(PD.VOLUME) > 400;
В результате получим следующую таблицу:
Получить список поставщиков, статус которых
Пример 25
. Получить список поставщиков, статус которых меньше максимального статуса в таблице поставщиков (сравнение с подзапросом):
SELECT *
FROM P
WHERE P.STATYS <
(SELECT MAX(P.STATUS)
FROM P);
Замечание. Т.к. поле P.STATUS сравнивается с результатом подзапроса, то подзапрос должен быть сформулирован так, чтобы возвращать таблицу, состоящую ровно из одной строки и одной колонки.
Замечание. Результат выполнения запроса будет эквивалентен результату следующей последовательности действий:
Выполнить один раз вложенный подзапрос и получить максимальное значение статуса.
Просканировать таблицу поставщиков P, каждый раз сравнивая значение статуса поставщика с результатом подзапроса, и отобрать только те строки, в которых статус меньше максимального.
Использование предиката IN. Получить список
Пример 26
. Использование предиката IN. Получить список поставщиков, поставляющих деталь номер 2:
SELECT *
FROM P
WHERE P.PNUM IN
(SELECT DISTINCT PD.PNUM
FROM PD
WHERE PD.DNUM = 2);
Замечание. В данном случае вложенный подзапрос может возвращать таблицу, содержащую несколько строк.
Замечание. Результат выполнения запроса будет эквивалентен результату следующей последовательности действий:
Выполнить один раз вложенный подзапрос и получить список номеров поставщиков, поставляющих деталь номер 2.
Просканировать таблицу поставщиков P, каждый раз проверяя, содержится ли номер поставщика в результате подзапроса.
Использование предиката EXIST. Получить список
Пример 27
. Использование предиката EXIST. Получить список поставщиков, поставляющих деталь номер 2:
SELECT *
FROM P
WHERE EXIST
(SELECT *
FROM PD
WHERE
PD.PNUM = P.PNUM AND
PD.DNUM = 2);
Замечание. Результат выполнения запроса будет эквивалентен результату следующей последовательности действий:
Просканировать таблицу поставщиков P, каждый раз выполняя подзапрос с новым значением номера поставщика, взятым из таблицы P.
В результат запроса включить только те строки из таблицы поставщиков, для которых вложенный подзапрос вернул непустое множество строк.
Замечание. В отличие от двух предыдущих примеров, вложенный подзапрос содержит параметр (внешнюю ссылку), передаваемый из основного запроса - номер поставщика P.PNUM. Такие подзапросы называются коррелируемыми (correlated). Внешняя ссылка может принимать различные значения для каждой строки-кандидата, оцениваемого с помощью подзапроса, поэтому подзапрос должен выполняться заново для каждой строки, отбираемой в основном запросе. Такие подзапросы характерны для предиката EXIST, но могут быть использованы и в других подзапросах.
Замечание. Может показаться, что запросы, содержащие коррелируемые подзапросы будут выполняться медленнее, чем запросы с некоррелируемыми подзапросами. На самом деле это не так, т.к. то, как пользователь, сформулировал запрос, не определяет, как этот запрос будет выполняться. Язык SQL является непроцедурным, а декларативным. Это значит, что пользователь, формулирующий запрос, просто описывает, каким должен быть результат запроса, а как этот результат будет получен - за это отвечает сама СУБД.
Использование предиката NOT EXIST. Получить
Пример 28
. Использование предиката NOT EXIST. Получить список поставщиков, не поставляющих деталь номер 2:
SELECT *
FROM P
WHERE NOT EXIST
(SELECT *
FROM PD
WHERE
PD.PNUM = P.PNUM AND
PD.DNUM = 2);
Замечание. Также как и в предыдущем примере, здесь используется коррелируемый подзапрос. Отличие в том, что в основном запросе будут отобраны те строки из таблицы поставщиков, для которых вложенный подзапрос не выдаст ни одной строки.
Получить имена поставщиков, поставляющих все
Пример 29
. Получить имена поставщиков, поставляющих все детали:
SELECT DISTINCT PNAME
FROM P
WHERE NOT EXIST
(SELECT *
FROM D
WHERE NOT EXIST
(SELECT *
FROM PD
WHERE
PD.DNUM = D.DNUM AND
PD.PNUM = P.PNUM));
Замечание. Данный запрос содержит два вложенных подзапроса и реализует реляционную операцию деления отношений.
Самый внутренний подзапрос параметризован двумя параметрами (D.DNUM, P.PNUM) и имеет следующий смысл: отобрать все строки, содержащие данные о поставках поставщика с номером PNUM детали с номером DNUM. Отрицание NOT EXIST говорит о том, что данный поставщик не поставляет данную деталь. Внешний к нему подзапрос, сам являющийся вложенным и параметризованным параметром P.PNUM, имеет смысл: отобрать список деталей, которые не поставляются поставщиком PNUM. Отрицание NOT EXIST говорит о том, что для поставщика с номером PNUM не должно быть деталей, которые не поставлялись бы этим поставщиком. Это в точности означает, что во внешнем запросе отбираются только поставщики, поставляющие все детали.
Получить имена поставщиков, имеющих статус,
Пример 30
. Получить имена поставщиков, имеющих статус, больший 3 или поставляющих хотя бы одну деталь номер 2 (объединение двух подзапросов - ключевое слово UNION):
SELECT P.PNAME
FROM P
WHERE P.STATUS > 3
UNION
SELECT P.PNAME
FROM P, PD
WHERE P.PNUM = PD.PNUM AND
PD.DNUM = 2;
Замечание. Результатирующие таблицы объединяемых запросов должны быть совместимы, т.е. иметь одинаковое количество столбцов и одинаковые типы столбцов в порядке их перечисления. Не требуется, чтобы объединяемые таблицы имели бы одинаковые имена колонок. Это отличает операцию объединения запросов в SQL от операции объединения в реляционной алгебре. Наименования колонок в результатирующем запросе будут автоматически взяты из результата первого запроса в объединении.
Получить имена поставщиков, имеющих статус,
Пример 31
. Получить имена поставщиков, имеющих статус, больший 3 и одновременно поставляющих хотя бы одну деталь номер 2 (пересечение двух подзапросов - ключевое слово INTERSECT):
SELECT P.PNAME
FROM P
WHERE P.STATUS > 3
INTERSECT
SELECT P.PNAME
FROM P, PD
WHERE P.PNUM = PD.PNUM AND
PD.DNUM = 2;
Получить имена поставщиков, имеющих статус,
Пример 32
. Получить имена поставщиков, имеющих статус, больший 3, за исключением тех, кто поставляет хотя бы одну деталь номер 2 (разность двух подзапросов - ключевое слово EXCEPT):
SELECT P.PNAME
FROM P
WHERE P.STATUS > 3
EXCEPT
SELECT P.PNAME
FROM P, PD
WHERE P.PNUM = PD.PNUM AND
PD.DNUM = 2;
Сравнение поля таблицы
Пример 33
. Сравнение поля таблицы и скалярного значения:POSTAV.VOLUME > 100
Конструктор значений строки AND Конструктор
Пример 34
. Сравнение двух сконструированных строк:(PD.PNUM, PD.DNUM) = (1, 25)Этот пример эквивалентен условному выражениюPD.PNUM = 1 AND PD.DNUM = 25Предикат between ::=
Конструктор значений строки [NOT] BETWEEN
Конструктор значений строки AND Конструктор значений строки
VOLUME BETWEEN 10 AND 100Предикат
Пример 35
. PD. VOLUME BETWEEN 10 AND 100Предикат in ::=
Конструктор значений строки [NOT] IN
{(Select-выражение) | (Выражение для вычисления значения.,..)}
PNUM FROM PD WHERE
Пример 36
. P.PNUM IN (SELECT PD. PNUM FROM PD WHERE PD.DNUM=2)
шаблоне разрешается использовать два трафаретных
Пример 37
. P.PNUM IN (1, 2, 3, 5)Предикат like ::=
Выражение для вычисления значения строки-поиска [NOT] LIKE
Выражение для вычисления значения строки-шаблона [ESCAPE Символ]Замечание. Предикат LIKE производит поиск строки-поиска в строке-шаблоне. В строке- шаблоне разрешается использовать два трафаретных символа:
Символ подчеркивания "_" может использоваться вместо любого единичного символа в строке-поиска,
Символ процента "%" может заменять набор любых символов в строке-поиска (число символов в наборе может быть от 0 и более).
Предикат null ::=
Конструктор значений строки IS [NOT] NULLЗамечание. Предикат NULL применяется специально для проверки, не равно ли проверяемое выражение null-значению.Предикат количественного сравнения ::=
Конструктор значений строки {= | < | > | <= | >= | <>}
{ANY | SOME | ALL} (Select-выражение)Замечание. Кванторы ANY и SOME являются синонимами и полностью взаимозаменяемы.
Замечание. Если указан один из кванторов ANY и SOME, то предикат количественного сравнения возвращает TRUE, если сравниваемое значение совпадает хотя бы с одним значением, возвращаемом в подзапросе (select-выражении).
Замечание. Если указан квантор ALL, то предикат количественного сравнения возвращает TRUE, если сравниваемое значение совпадает с каждым значением, возвращаемом в подзапросе (select-выражении).
Предикат EXIST возвращает значение TRUE,
Пример 38
. P.PNUM = SOME (SELECT PD.PNUM FROM PD WHERE PD.DNUM=2)Предикат exist ::=
EXIST (Select-выражение)Замечание. Предикат EXIST возвращает значение TRUE, если результат подзапроса (select-выражения) не пуст.Предикат unique ::=
UNIQUE (Select-выражение)Замечание. Предикат UNIQUE возвращает TRUE, если в результате подзапроса (select-выражения) нет совпадающих строк.Предикат match ::=
Конструктор значений строки MATCH [UNIQUE]
[PARTIAL | FULL] (Select-выражение)Замечание. Предикат MATCH проверяет, будет ли значение, определенное в конструкторе строки совпадать со значением любой строки, полученной в результате подзапроса.Предикат overlaps ::=
Конструктор значений строки OVERLAPS Конструктор значений строкиЗамечание. Предикат OVERLAPS, является специализированным предикатом, позволяющем определить, будет ли указанный период времени перекрывать другой период времени.
Пример нарушения целостности базы...
. Пусть имеется система, в которой хранятся данные о подразделениях и работающих в них сотрудниках. Список подразделений хранится в таблице DEPART(Dep_Id, Dep_Name, Dept_Kol), где Dept_Id - идентификатор подразделения, Dept_Name - наименование подразделения, Dept_Kol - количество сотрудников в подразделении. Список сотрудников хранится в таблице PERSON(Pers_Id, Pers_Name, Dept_Id), где Pers_Id - идентификатор сотрудника, Pers_Name - имя сотрудника, Dept_Id - идентификатор подразделения, в котором работает сотрудник:
Пример ограничения типа check...
Пример ограничения типа CHECK:
CHECK (Salespeaple.Salary IS NOT NULL) OR (Salespeaple.Commission IS NOT NULL)
Данное ограничение утверждает, что каждый продавец должен иметь либо ненулевую зарплату, либо ненулевые комиссионные.
Пример 16
. Еще пример ограничения типа CHECK:
CHECK EXIST(SELECT * FROM Salespeaple)
Данное ограничение утверждает, что список продавцов не может быть пустым.
Ограничения таблицы и ограничения столбца. Ограничения таблицы и ограничения столбца таблицы входят как часть описания соответственно таблицы или столбца таблицы. Ограничение таблицы может относиться к нескольким столбцам таблицы. Ограничение столбца относится только к одному столбцу таблицы. Любое ограничение столбца можно описать как ограничение таблицы, но не наоборот.
Ограничения таблицы или столбца могут иметь наименования, при помощи которого в дальнейшем можно отменять это ограничение или менять время его проверки.
Ограничение PRIMARY KEY. Ограничение PRIMARY KEY для таблицы или столбца означает, что группа из одного или нескольких столбцов образуют потенциальный ключ таблицы. Это означает, что комбинация значений в PRIMARY KEY должна быть уникальной для каждой строки таблицы. Дублированные значения или значения, содержащие NULL, будут отвергнуты. Для одной таблицы может быть определено единственное ограничение PRIMARY KEY. В терминах стандарта SQL это называется первичным ключом таблицы.
Ограничение UNIQUE. Ограничение UNIQUE для таблицы или столбца означает, что группа из одного или нескольких столбцов образуют потенциальный ключ таблицы, в котором допускаются значения NULL. Это означает, что две строки, содержащие одинаковые и не равные NULL-значения, считаются нарушающими уникальность и не допускаются. Две строки, содержащие NULL-значения считаются различными и допускаются. Для одной таблицы может быть определено несколько ограничений UNIQUE.
Замечание. С точки зрения реляционной модели данных (см. главу 3, замечание к правилам целостности сущностей и внешних ключей), ограничение типа UNIQUE не определяет потенциальный ключ, т.к. потенциальный ключ не должен содержать NULL-значений.
Ограничения FOREIGN KEY и REFERENCES. Ограничение FOREIGN KEY… REFERENCES… для таблицы и ограничение REFERENCES… для столбца определяют внешний ключ таблицы. Ограничение REFERENCES… для столбца определяет простой внешний ключ, т.е. ключ, состоящий из одной колонки. Ограничение FOREIGN KEY… REFERENCES… для таблицы может определять как простой, так и сложный внешний ключ, т.е. ключ, состоящий из нескольких колонок таблицы. Столбец или группа столбцов таблицы, на которую ссылается внешний ключ, должна иметь ограничения PRIMARY KEY или UNIQUE. Столбцы, на которые ссылается внешний ключ, должны иметь тот же тип данных, что и столбцы, входящие в состав внешнего ключа. Таблица может иметь ссылку на себя. Ограничение внешнего ключа нарушается, если значения, присутствующие во внешнем ключе, не совпадают со значениями соответствующего ключа родительской таблицы ни для одной строки из родительской таблицы. Операции, приводящие к нарушению ограничения внешнего ключа, отвергаются. Как должны совпадать значения внешнего ключа и ключа родительской таблицы, а также, какие действия необходимо выполнить при изменениях ключей в родительской таблице, описаны ниже в ссылочной спецификации.
Ограничение NOT NULL. Ограничение NOT NULL столбца не допускает появления в столбце NULL-значений.
Ссылочная спецификация. Ссылочная спецификация определяет характеристики внешнего ключа таблицы.
Предложение MATCH {FULL | PARTIAL}. Предложение MATCH FULL требует полного совпадения значений внешнего и первичного ключей. Предложение MATCH PARTIAL допускает частичное совпадение значений внешнего и первичного ключей. Предложение MATCH может быть также пропущенным. Для случая MATCH PARTIAL в дочерней таблице могут появиться строки, имеющие значения внешнего ключа, неуникально совпадающие со значениями родительского ключа. Т.е. одна строка дочерней таблицы может иметь неуникальные ссылки не несколько строк родительской таблицы. Это очень сильно отличается от реляционной модели данных, и это отличие провоцируется допущением NULL-значений. Чтобы рассмотреть различные варианты совпадений внешнего и родительского ключей, рассмотрим следующий пример.
Задав дополнительные вопросы менеджеру, мы выяснили, что фирма имеет несколько складов. Причем, каждый товар может храниться на нескольких складах и быть проданным с любого склада.
Куда поместить сущности "Накладная" и "Склад" и с чем их связать? Спросим себя, как связаны эти сущности между собой и с сущностями "Покупатель" и "Товар"? Покупатели покупают товары, получая при этом накладные, в которые внесены данные о количестве и цене купленного товара. Каждый покупатель может получить несколько накладных. Каждая накладная обязана выписываться на одного покупателя. Каждая накладная обязана содержать несколько товаров (не бывает пустых накладных). Каждый товар, в свою очередь, может быть продан нескольким покупателям через несколько накладных. Кроме того, каждая накладная должна быть выписана с определенного склада, и с любого склада может быть выписано много накладных. Таким образом, после уточнения, диаграмма будет выглядеть следующим образом:
![](images/image_793.gif)
Рис. 8
Пора подумать об атрибутах сущностей. Беседуя с сотрудниками фирмы, мы выяснили следующее:
Каждый покупатель является юридическим лицом и имеет наименование, адрес, банковские реквизиты.
Каждый товар имеет наименование, цену, а также характеризуется единицами измерения.
Каждая накладная имеет уникальный номер, дату выписки, список товаров с количествами и ценами, а также общую сумму накладной. Накладная выписывается с определенного склада и на определенного покупателя.
Каждый склад имеет свое наименование.
Снова выпишем все существительные, которые будут потенциальными атрибутами, и проанализируем их:
Юридическое лицо - термин риторический, мы не работаем с физическими лицами. Не обращаем внимания.
Наименование покупателя - явная характеристика покупателя.
Адрес - явная характеристика покупателя.
Банковские реквизиты - явная характеристика покупателя.
Наименование товара - явная характеристика товара.
(?)Цена товара - похоже, что это характеристика товара. Отличается ли эта характеристика от цены в накладной?
Единица измерения - явная характеристика товара.
Номер накладной - явная уникальная характеристика накладной.
Дата накладной - явная характеристика накладной.
(?)Список товаров в накладной - список не может быть атрибутом. Вероятно, нужно выделить этот список в отдельную сущность.
(?)Количество товара в накладной - это явная характеристика, но характеристика чего? Это характеристика не просто "товара", а "товара в накладной".
(?)Цена товара в накладной - опять же это должна быть не просто характеристика товара, а характеристика товара в накладной. Но цена товара уже встречалась выше - это одно и то же?
Сумма накладной - явная характеристика накладной. Эта характеристика не является независимой. Сумма накладной равна сумме стоимостей всех товаров, входящих в накладную.
Наименование склада - явная характеристика склада.
В ходе дополнительной беседы с менеджером удалось прояснить различные понятия цен. Оказалось, что каждый товар имеет некоторую текущую цену. Эта цена, по которой товар продается в данный момент. Естественно, что эта цена может меняться со временем. Цена одного и того же товара в разных накладных, выписанных в разное время, может быть различной. Таким образом, имеется две цены - цена товара в накладной и текущая цена товара.
С возникающим понятием "Список товаров в накладной" все довольно ясно. Сущности "Накладная" и "Товар" связаны друг с другом отношением типа много-ко-многим. Такая связь, как мы отмечали ранее, должна быть расщеплена на две связи типа один-ко-многим. Для этого требуется дополнительная сущность. Этой сущностью и будет сущность "Список товаров в накладной". Связь ее с сущностями "Накладная" и "Товар" характеризуется следующими фразами - "каждая накладная обязана иметь несколько записей из списка товаров в накладной", "каждая запись из списка товаров в накладной обязана включаться ровно в одну накладную", "каждый товар может включаться в несколько записей из списка товаров в накладной", " каждая запись из списка товаров в накладной обязана быть связана ровно с одним товаром". Атрибуты "Количество товара в накладной" и "Цена товара в накладной" являются атрибутами сущности " Список товаров в накладной".
Точно также поступим со связью, соединяющей сущности "Склад" и "Товар". Введем дополнительную сущность "Товар на складе". Атрибутом этой сущности будет "Количество товара на складе". Таким образом, товар будет числиться на любом складе и количество его на каждом складе будет свое.
Теперь можно внести все это в диаграмму:
![](images/image_794.gif)
Рис. 9
Примерами атрибутов сущности "сотрудник"...
Примерами атрибутов сущности "Сотрудник" могут быть такие атрибуты как "Табельный номер", "Фамилия", "Имя", "Отчество", "Должность", "Зарплата" и т.п.
Атрибуты изображаются в пределах прямоугольника, определяющего сущность:
![](images/image_788.gif)
Рис. 2
Примерами ограничений целостности могут служить
Примерами ограничений целостности могут служить следующие утверждения:
Пример 2
. Возраст сотрудника не может быть меньше 18 и больше 65 лет.
Примерами сущностей могут быть...
Примерами сущностей могут быть такие классы объектов как "Поставщик", "Сотрудник", "Накладная".
Каждая сущность в модели изображается в виде прямоугольника с наименованием:
![](images/image_787.gif)
Рис. 1
Примером ограничения, которое...
Примером ограничения, которое не может быть проверено немедленно является ограничение из примера 1. Это происходит оттого, что транзакция, заключающаяся во вставке нового сотрудника в таблицу PERSON, состоит не менее чем из двух операций - вставки строки в таблицу PERSON и обновления строки в таблице DEPART. Ограничение, безусловно, неверно после первой операции и становится верным после второй операции.
Примером такого ограничения может...
Примером такого ограничения может служить требование из примера 1, утверждающее, что поле Dept_Kol таблицы DEPART должно содержать количество сотрудников, реально числящихся в подразделении. Для реализации этого ограничения необходимо создать триггер, запускающийся при вставке, модификации и удалении записей в таблице PERSON, который корректно изменяет значение поля Dept_Kol. Например, при вставке в таблицу PERSON новой строки, триггер увеличивает на единицу значение поля Dept_Kol, а при удалении строки - уменьшает. Заметим, что при модификации записей в таблице PERSON могут потребоваться даже более сложные действия. Действительно, модификация записи в таблице PERSON может заключаться в том, что мы переводим сотрудника из одного отдела в другой, меняя значение в поле Dept_Id. При этом необходимо в старом подразделении уменьшить количество сотрудников, а в новом - увеличить.
Кроме того, необходимо защититься от неправильной модификации строк таблицы DEPART. Действительно, пользователь может попытаться модифицировать запись об отделе, введя неверное значение поля Dept_Kol. Для предотвращения подобных действий необходимо создать также триггеры, запускающиеся при вставке и модификации записей в таблице DEPART. Триггер, запускающийся при удалении записей из таблицы DEPART не нужен, т.к. уже имеется ограничение ссылочной целостности, каскадно удаляющее записи из таблицы PERSON при удалении записи из таблицы DEPART.
По сути, наличие ограничения целостности (как декларативного, так и процедурного характера) всегда приводит к созданию или использованию некоторого программного кода, реализующего это ограничение. Разница заключается в том, где такой код хранится и как он создается.
Если ограничение целостности реализовано в виде триггеров, то этот программный код является просто телом триггера. Если используется декларативное ограничение целостности, то возможны два подхода:
При декларировании (объявлении) ограничения текст ограничения хранится в виде некоторого объекта СУБД, а для реализации ограничения используются встроенные в СУБД функции, и тогда этот код представляет собой внутренние функции ядра СУБД.
При декларировании ограничения СУБД автоматически генерирует триггеры, выполняющие необходимые действия по проверке ограничений.
Примером использования функций ядра для проверки декларативных ограничений является автоматическая проверка уникальности индексов, соответствующих потенциальным ключам отношений. В качестве другого примера можно привести поддержку ссылочной целостности средствами СУБД ORACLE. Ограничение ссылочной целостности является в ORACLE объектом базы данных, хранящим формулировку этого ограничения. Проверка ограничения выполняется функциями ядра ORACLE со ссылкой на этот объект. Ограничение целостности в этом случае нельзя модифицировать иначе, как используя декларативные операторы создания и модификации ограничений.
Примером генерации новых триггеров для реализации декларативных ограничений, может служить система Visual FoxPro. Триггеры, автоматически сгенерированные Visual FoxPro при объявлении ограничений ссылочной целостности можно посмотреть и даже внести в них изменения, так чтобы они могли выполнять некоторые дополнительные действия.
Если система не поддерживает ни декларативную поддержку ссылочной целостности, ни триггеры (как, например, FoxPro 2.5), то программный код, следящий за корректностью базы данных, приходится размещать в пользовательском приложении (такой ведь код все равно необходим!). Это сильно затрудняет разработку программ и не защищает от попыток пользователей напрямую внести некорректные данные в базу данных. Особенно сложно становится в том случае, когда имеется сложная база данных и множество различных приложений, работающих с ней (например, к базе данных торгового предприятия может обращаться несколько приложений, таких как "Складской учет", "Прием заказов", "Главный бухгалтер" и т.п.). Каждое из таких приложений должно содержать один и тот же код, отвечающий за поддержание целостности базы данных. Особенно весело становится разработчику, когда необходимо внести изменения в логику поддержания целостности. Приходится заменять во всех программах одни и те же места, перекомпилировать все приложения и распространять по рабочим местам новые версии.
Примером такого отношения могут...
Примером такого отношения могут быть данные с объемами продаж различных товаров за некоторые промежутки времени:
Примеры использования оператора...
Отбор данных из одной таблицы
Пример 6. Выбрать все данные из таблицы поставщиков (ключевые слова SELECT… FROM…):
SELECT *
FROM P;
Замечание. В результате получим новую таблицу, содержащую полную копию данных из исходной таблицы P.
Примеры использования операторов манипулирования данными insert - вставка строк в таблицу
INSERT - вставка строк в таблицу
Пример 1. Вставка одной строки в таблицу:
INSERT INTO
P (PNUM, PNAME)
VALUES (4, "Иванов");
Получить имена поставщиков, поставляющих деталь
. Получить имена поставщиков, поставляющих деталь номер 2.Решение:
Примеры отношений бинарные отношения (отношения степени 2)
Бинарные отношения (отношения степени 2)
В математике большую роль играют бинарные отношения, т.е. отношения, заданные на декартовом произведении двух множеств