Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Управление данными (пособие).pdf
Скачиваний:
280
Добавлен:
21.05.2015
Размер:
5.42 Mб
Скачать

100

существующему значению потенциального ключа родительского отношения.

Установить в NULL. Операция вставки кортежа разрешается, но вместо предлагаемого пользователем некорректного значения внешнего ключа устанавливается NULL-значение.

Установить по умолчанию. Операция вставки кортежа разрешается, но вместо предлагаемого пользователем некорректного значения внешнего ключа устанавливается значение, принятое по умолчанию.

При обновлении кортежа в дочернем отношении

Ограничить. Операция обновления кортежа отвергается, если новое значение внешнего ключа этого кортежа не соответствует ни одному существующему значению потенциального ключа родительского отношения.

Установить в NULL. Операция обновления кортежа разрешается, но вместо предлагаемого пользователем некорректного нового значения внешнего ключа устанавливается NULL-значение.

Установить по умолчанию. Операция обновления кортежа

разрешается, но вместо предлагаемого пользователем некорректного значения внешнего ключа устанавливается значение, принятое по умолчанию.

В заключение этого раздела можно еще отметить, что, вообще говоря, возможно использование еще одной стратегии поведения при возникновении ситуации, нарушающей ссылочную целостность базы данных, которая состоит в отказе обеспечения ссылочной целостности, а именно:

Игнорировать. Операция выполняется, не обращая внимания на нарушение ссылочной целостности.

Вэтом случае разработчик базы данных, использую средства СУБД, должен реализовать свою специальную стратегию поддержания ссылочной целостности данных.

9.5.Средства обеспечения целостности данных в СУБД

Предыдущие разделы были посвящены рассмотрению вопросов, связанных с необходимостью представления в базе данных специального вида

101

информации о предметной области, называемого ограничениями целостности данных. В данном разделе рассмотрим средства, с помощью которых в СУБД обеспечивается описание информации об ограничениях целостности и реализуется механизм выполнения этих ограничений. В самом общем виде различают два способа реализации механизма обеспечения целостности данных, это:

декларативная поддержка ограничений целостности,

процедурная поддержка ограничений целостности.

Декларативная поддержка ограничений целостности заключается в описании ограничений целостности средствами языка определения данных (DDL - Data Definition Language), поддерживаемого СУБД. Обычно средства декларативной поддержки целостности (если они имеются в конкретной СУБД) определяют ограничения на значения доменов и атрибутов, целостность сущностей (потенциальные ключи отношений) и ссылочную целостность (целостность внешних ключей). Декларативные ограничения целостности можно использовать как при создании таблиц-отношений средствами языка DDL, так и задавать и модифицировать для уже существующих таблиц. Стандартом языка SQL предусмотрен широкий набор средств декларативной поддержки ограничений целостности, которые более подробно рассматриваются ниже.

Процедурная поддержка ограничений целостности заключается в использовании программного кода, реализуемого в СУБД в виде так называемых хранимых процедур и триггеров.

Хранимые процедуры – это процедуры и функции (программный код), хранящиеся непосредственно в базе данных в откомпилированном виде и которые могут запускаться пользователями или приложениями, работающими с базой данных.

Триггеры – это хранимые процедуры, особенность которых состоит в том, что их запуск на исполнение связан с определенными событиями, происходящими во время работы базы данных.

В качестве таких событий выступают операции вставки, обновления и удаления строк таблиц. Если в базе данных определен некоторый триггер, то он запускается автоматически и всегда при возникновении события, с которым этот триггер связан. Очень важным является то, что пользователь не может обойти триггер. Триггер срабатывает всегда и независимо от того, кто из пользователей и каким способом инициировал событие, вызвавшее запуск триггера.

102

Основное назначение триггеров – автоматическое выполнение действий по поддержанию целостности базы данных.

Триггеры могут быть как достаточно простыми, например, поддерживающими ссылочную целостность, так и довольно сложными, реализующими какие-либо сложные ограничения предметной области или сложные действия, которые должны произойти при наступлении некоторых событий.

Обычно хранимые процедуры и триггеры пишутся либо на специальном процедурном расширении языка SQL (например, PL/SQL для ORACLE или Transact-SQL для MS SQL Server), или на некотором универсальном языке программирования, например, C++, с включением в код операторов SQL в соответствии со специальными правилами такого включения.

Использование для обеспечения целостности триггеров и хранимых процедур более сложно, чем использование декларативных средств языка SQL, так как предполагает более низкоуровневые средства формирования программного кода и более высокие требования к квалификации разработчика базы данных. Однако триггеры позволяют реализовать в СУБД обработку гораздо более изощренных ограничений целостности данных, не реализуемых с использованием стандартных встроенных средств декларативной поддержки целостности.

Вообще говоря, наличие ограничения целостности (как декларативного, так и процедурного характера) всегда приводит к созданию или использованию некоторого программного кода, реализующего это ограничение. Разница заключается в том, где такой код хранится и как он создается. И в этом плане наличие, развитость и уровень реализации в конкретной СУБД средств описания и обеспечения целостности данных является одним из важных показателей ее уровня, с точки зрения возможностей и эффективности реализации на ее основе информационных систем с базами данных.

При реализации в СУБД ограничений целостности в виде триггеров соответствующий программный код является просто телом триггера. Если используется декларативное задание ограничений целостности, например средствами языка SQL, то возможны два подхода.

1.Использование для реализации ограничения функций, встроенных в ядро СУБД, с сохранением задаваемого при декларировании исходного текста ограничения в виде некоторого объекта СУБД. В этом случае проверка

ограничения выполняется функциями ядра СУБД (например, ядра Oracle) со ссылкой на этот объект. Ограничение целостности, при этом нельзя модифицировать иначе, как путем использования декларативных операторов создания и модификации ограничений.

2.Автоматическая генерация программного кода триггеров, выполняющих необходимые действия по проверке ограничений, при декларировании ограничения СУБД. В некоторых СУБД, например Visual FoxPro,

103

допускается последующее «ручное» редактирование автоматически сгенерированного кода триггера.

Если система не поддерживает ни декларативную поддержку ссылочной целостности, ни триггеры (как, например FoxPro 2.5, Clipper и др.), то программный код, следящий за корректностью базы данных, приходится размещать в пользовательском приложении. Это существенно затрудняет разработку программ и, главное, не защищает от возможности внесения пользователем некорректных данных напрямую в базу данных. Ситуация особенно усложняется в случае, когда с базой данных работает не одно, а множество различных приложений. Каждое из таких приложений должно содержать один и тот же код, отвечающий за поддержание целостности базы данных, который при необходимости изменения характера ограничения целостности необходимо модифицировать синхронно во всех приложениях.

9.6.Поддержка декларативных ограничений целостности в языке SQL

Практически во всех современных промышленных СУБД имеются процедурные средства ограничений целостности с помощью хранимых процедур и триггеров. Эти средства, однако, являются системно зависимыми, то есть зависящими от особенностей конкретной СУБД. В стандарте же языка SQL процедурные средства реализации ограничений целостности не предусмотрены. В связи с этим в SQL отсутствуют такие понятия, как триггер или хранимая процедура. Однако, при этом, в SQL имеются развитые декларативные средства для определения ограничений целостности.

Декларативные ограничения целостности являются частью синтаксиса команд определения данных (DDL) языка SQL.Чаще всего они используются с командой CREATE TABLE, предназначенной для создания пустой таблицы базы данных, и команды ALTER TABLE, с помощью которой осуществляется модификация структуры и параметров существующей таблицы.

Следующий пример показывает команду, позволяющую создать таблицу

STUDENT.

CREATE TABLE СТУДЕНТЫ

( КОД_СТУД INTEGER,

ФИО CHAR(20),

ПАСПОРТ CHAR(15),

104

СТИПЕНДИЯ NUMERIC(4),

КУРС INTEGER,

ФАКУЛЬТЕТ CHAR(50), СТАРОСТА INTEGER);

Добавить в существующую таблицу STUDENT новые столбцы можно командой

ALTER TABLE STUDENT ADD

( ДАТА_РОЖД DATE,

АДРЕС CHAR(60));

А изменить параметры уже существующего столбца можно с помощью команды

ALTER TABLE СТУДЕНТЫ MODIFY (ФИО CHAR(60));

которая увеличивает ширину столбца ФИО с 20-ти символов, заданных предыдущей командой CREATE, до 60-ти символов.

Как видно из приведенных SQL-выражений, при описании столбцов таблицы указывается тип данных, которые могут использоваться в качестве значений столбцов. В примерах использованы типы данных: INTEGER – целое число, NUMERIC() – число с фиксированной точкой, CHAR() – строка символов, DATE – дата. Указание типа данных столбца уже является простейшим ограничением, накладываемым на его значения (ограничение уровня атрибута). Однако должно быть понятно, что указание типа данных столбца не эквивалентно ограничению на значения атрибута, задаваемого его доменом.

Синтаксис SQL позволяет задавать гораздо более сложные ограничения целостности данных. Это следующие виды ограничений

ограничение типа,

ограничение столбца и

ограничение таблицы.

Ограничение типа задается с помощью ключевого слова CHECK. Ключевое слова CHECK позволяет указать предикат, задающий

ограничение целостности, который может принимать значения true, false и unknown. Ограничение типа может быть использовано как часть описания домена, столбца таблицы, самой таблицы или отдельного ограничения целостности, задаваемого командой ASSEPTION. Например, следующее ограничение

CHECK(СТУДЕНТЫ.КУРС > 0 AND СТУДЕНТЫ.КУРС <=6)

105

состоит в том, что значение атрибута КУРС таблицы СТУДЕНТЫ (курс, на котором учится студент) может принимать значения в диапазоне от 1 до 6.

Ограничение целостности в командах описания данных языка SQL могут задаваться как часть описания столбца (в этом случае они будут распространяться на данный столбец) или задаваться как часть описания таблицы (в этом случае они будут относиться ко всей таблице). При этом любое ограничение столбца может быть описано как ограничение таблицы, но не наоборот.

Для задания ограничения столбца или ограничения таблицы в современном SQL может использоваться необязательное ключевое слово CONSTRAINT, которое позволяет присваивать ограничению уникальное имя. Имя ограничения может быть впоследствии использовано для изменения параметров данного ограничения или его удаления, а также в сообщениях об ошибках, возникающих при проверке ограничения.

Несколько упрощенный синтаксис выражения для описания ограничения столбца и ограничения таблицы выглядит следующим образом

Ограничения столбца::= [CONSTRAINT Имя ограничения]

{

{NOT NULL}

| {PRIMARY KEY} | {UNIQUE}

| {[FOREIGN KEY] REFERENCES Имя таблицы [(Имя столбца)] [Ссылочная спецификация]}

| {Ограничение check}

}

Ограничения таблицы::= [CONSTRAINT Имя ограничения]

{

{PRIMARY KEY(Имя столбца, ...)} | {UNIQUE(Имя столбца, ...)}

| {FOREIGN KEY(Имя столбца, ...)

REFERENCES Имя таблицы [(Имя столбца, ...)] [Ссылочная спецификация]}

| {Ограничение check}

}

Ссылочная спецификация::=

[ON UPDATE {NO ACTION | CASCADE | SET NULL | SET DEFAULT}] [ON DELETE {NO ACTION | CASCADE | SET NULL | SET DEFAULT}]

Напомним, что квадратные скобки при описании синтаксиса языка указывают на необязательность использования находящегося внутри них

106

элемента, а вертикальная черта разделяет возможные варианты допустимых для использования элементов.

Используемые при описании синтаксиса ограничений ключевые слова имеют следующий смысл.

Ограничение NOT NULL – требует обязательного указания у атрибута какого-либо конкретного значения, т.е. не допускает в столбце пустых (неопределенных) значений.

Ограничение UNIQUE означает, что значение атрибута или группы атрибутов, для которых указано это ограничение, должны быть уникальными в данной таблице. При этом для данных атрибутов допускаются NULL-значения (если не указано ограничение NOT NULL), считается, что они не нарушают уникальности строк таблицы.

Ограничение PRIMARY KEY означает, что столбец или группа столбцов образуют первичный ключ таблицы. То есть значения столбца или комбинация значений столбцов должны быть уникальными в таблице и для них не допустимы NULL-значения. Ограничение PRIMARY KEY эквивалентно одновременному использованию ограничений NOT NULL и UNIQUE.

Ограничения FOREIGN KEY и REFERENCES определяют внешний ключ таблицы. Ограничение REFERENCES … для столбца определяет простой внешний ключ, т.е. ключ, состоящий из одного атрибута. Ограничение FOREIGN KEY REFERENCES … для таблицы может определять как простой, так и составной внешний ключ, т.е. ключ, состоящий из нескольких атрибутов. Типы столбцов внешнего ключа и столбцов, на которые он ссылается, должны быть одинаковыми. Столбец или группа столбцов, на которые ссылается внешний ключ, должны иметь ограничения PRIMARY KEY или UNIQUE. Допустимо внешнему ключу ссылаться на атрибуты той же самой таблицы. Ограничение внешнего ключа нарушается, если значения составляющих его атрибутов в какой-либо строке таблицы не совпадают со значениями атрибутов, на которые он ссылается, ни в одной из строк родительской таблицы.

Ссылочная спецификация определения внешнего ключа определяет реакцию системы на попытку совершения действий при выполнении команд UPDATE и DELETE над родительской таблицей, которые могут привести к нарушению согласованности значений внешнего и родительского ключей.

Приведем несколько примеров, иллюстрирующих использование приведенных выше видов ограничений.

Запрос SQL для создания таблицы СТУДЕНТЫ, предназначенной для хранения индивидуальной информации о студентах.

 

 

107

CREATE TABLE

СТУДЕНТЫ

PRIMARY KEY,

( КОД_СТУД

INTEGER

ФИО

CHAR(20)

NOT NULL,

ДАТА_РОЖД

DATE

NOT NULL,

АДРЕС

CHAR(60)

NOT NULL UNIQUE,

ПАСПОРТ

CHAR(15)

СТИПЕНДИЯ

NUMERIC(4),

КУРС

INTEGER

CHECK(КУРС > 0 AND КУРС <=6),

ФАКУЛЬТЕТ

CHAR(50)

FOREIGN KEY REFERENCES ФАКУЛЬТЕТЫ

 

 

ON UPDATE CASCADE

СТАРОСТА

INTEGER

ON DELETE SET NULL,

FOREIGN KEY REFERENCES СТУДЕНТЫ

 

 

ON DELETE SET NULL);

В этом запросе все ограничения указываются в описании столбцов (ограничения столбца). Эти ограничения имеют следующий смысл:

для столбца КОД_СТУД установлено ограничение первичного ключа PRIMARY KEY, эквивалентное паре ограничений NOT NULL и UNIQUE;

для столбца ПАСПОРТ установлено ограничение NOT NULL, требующее обязательного указания значения поля, и ограничение UNIQUE, требующее уникальности его значений (это поле фактически является альтернативным ключом);

для столбца КУРС установлено ограничение CHECK, задающее допустимый диапазон его значений;

столбец ФАКУЛЬТЕТ объявлен внешним ключом (FOREIGN KEY), ссылающимся (REFERENCES) на одноименный столбец таблицы ФАКУЛЬТЕТЫ, причем при обновлении в этой таблице указанного родительского ключа, должны каскадно обновляться соответствующие значения поля ФАКУЛЬТЕТ и в таблице СТУДЕНТЫ (ON UPDATE CASCADE), а при удалении записи о факультете в таблице ФАКУЛЬТЕТ соответствующие значения в таблице должны СТУДЕНТЫ должны устанавливаться в NULL;

столбец СТАРОСТА также объявлен внешним ключом, ссылающимся на первичный ключ самой таблицы СТУДЕНТЫ, при этом, при удалении из таблицы записи о студенте, на которого была хотя бы одна ссылка, как на старосту, эта ссылка должна устанавливаться в NULL.

Другой пример SQL-запроса для создания таблицы УСПЕВАЕМОСТЬ, предназначенной для хранения результатов сдачи студентами экзаменов по конкретным дисциплинам.

108

CREATE TABLE УСПЕВАЕМОСТЬ

 

(КОД_СТУД

INTEGER,

 

КОД_ДИСЦ

INTEGER,

NOT NULL,

ОЦЕНКА

INTEGER

ДАТА_СДАЧИ

DATE

NOT NULL,

CONSTRAINT УСП_ПЕРВ_КЛ PRIMARY KEY (КОД_СТУД, КОД_ДИСЦ), CONSTRAINT КОД_СТУД_ВНЕШН_КЛ FOREIGN KEY (КОД_СТУД)

REFERENCES СТУДЕНТЫ ON UPDATE CASCADE ON DELETE NO ACTION),

CONSTRAINT КОД_ДИСЦ_ВНЕШН_КЛ FOREIGN KEY (КОД_ДИСЦ)

REFERENCES ДИСЦИПЛИНЫ,

CONSTRAINT ОЦЕНКА_ОГР CHECK (ОЦЕНКА>=2 AND ОЦЕНКА<=5));

В этом запросе кроме ограничений столбцов используются и ограничения таблицы. Поясним эти ограничения:

для столбцов ОЦЕНКА и ДАТА_СДАЧИ запрещено использование NULL- значений, то есть система должна требовать обязательного ввода действительных значений оценки и даты сдачи экзамена;

ограничение таблицы УСП_ПЕРВ_КЛ объявляет составной атрибут {КОД_СТУД, КОД_ДИСЦ} первичным ключом отношения;

ограничение таблицы КОД_СТУД_ВНЕШН_КЛ объявляет столбец КОД_СТУД внешним ключом, ссылающимся на одноименный первичный ключ таблицы СТУДЕНТЫ, причем, при обновлении значения кода студента в родительской таблице, ссылающиеся на них (если они есть) значения столбца КОД_СТУД таблицы УСПЕВАЕМОСТЬ должны каскадно обновляться, а попытки удаления записи о студенте в таблице СТУДЕНТЫ при наличии ссылающихся на него записей в таблице УСПЕВАЕМОСТЬ должны отвергаться (спецификация NO ACTION);

ограничение КОД_ДИСЦ_ВНЕШН_КЛ объявляет столбец КОД_ДИСЦ внешним ключом, ссылающимся на одноименный первичный ключ таблицы ДИСЦИПЛИНЫ, причем, все попытки обновления значения кода дисциплины в этой родительской таблице, или удаления какой либо записи из этой таблицы, в случае наличия хотя бы одной ссылки на это обновляемое или удаляемое значение кода дисциплины, должны отвергаться (по умолчанию действует опция NO ACTION);

и, наконец, ограничение ОЦЕНКА_ОГР устанавливает допустимый диапазон значений этого поля. Любая попытка ввести значение атрибута ОЦЕНКА, лежащего вне диапазона 2 ÷ 5, также будет отвергнута системой.