    Глава 16 

    Целостность 

    16.1. Введение 

    Как уже объяснялось в начале предыдущей главы, термин целостность 
используется для описания точности и корректности данных, хранящихся в базе 
данных. Его не следует путать с безопасностью, хотя оба эти понятия обладают 
некоторыми сходными чертами. Повторяя сказанное ранее, отметим, что как при 
обеспечении безопасности, так и при поддержке целостности система должна 
содержать сведения о тех правилах, которые пользователю не следует нарушать. В 
обоих случаях эти правила должны быть заданы (обычно администратором базы 
данных) на некотором удобном языке и должны храниться в системном каталоге. 
Кроме того, СУБД каким-то образом должна следить за соблюдением заданных 
правил при выполнении пользователем некоторых операций. Единственным отличием 
ограничений целостности от правил безопасности является то, что ограничения 
целостности не зависят от пользователя. Иначе говоря, если бы они зависели от 
пользователя, то по определению назывались бы правилами безопасности, а не 
ограничениями целостно сти! 
    В этой главе основное внимание уделяется именно ограничениям целостности. 
Сначала в общих чертах представлена концепция целостности. Затем описан 
гипотетический язык, на котором формулируются ограничения целостности. Этот 
язык также используется для введения и демонстрации классификационной схемы 
ограничений целостности. После этого описываются различия между ограничениями 
состояния и перехода. Потом вновь рассматриваются описанные в главе 5 понятия 
потенциального и внешнего ключа, в частности показано, как эти понятия могут 
быть представлены в рамках концепции целостности. Далее описываются 
соответствующие аспекты стандарта языка SQL, а в конце представлен краткий 
обзор всей главы. 
    Замечание. Многие части материала, излагаемого в этой главе, основаны на 
ранних публикациях автора, в частности [16.5]. Однако представленная здесь 
классификация ограничений целостности существенно усовершенствована и 
превосходит классификацию, данную ранее в [16.5]. Более того, во время 
написания этой книги новая схема, разработанная автором и Дэвидом 
Мак-Говерэном (David McGoveran), еще не была широко представлена в литературе. 
Одно важное отличие между новой схемой и ее прежней версией следует упомянуть 
сразу же. Здесь представлена в новом виде концепция спецификации проверки 
времени, т.е. утверждения типа ON UPDATE R, назначение которых состоит в том, 
чтобы указать СУБД, когда проверить то или иное ограничение, связанное с 
некоторым отношением R. Подробнее это описано в комментариях к [16.4]. 

    16.2. Общие соображения 

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

    416 Часть IV. Защита данных 

    2.  Далее следует кратко напомнить материал, изложенный в главе 5. 
    • Обычно ограничения целостности применяются для описания базовых 
отношений, поскольку базовые отношения прекрасно "отражают реальность" и, 
следовательно, должны регулироваться таким образом, чтобы содержать корректные 
или, по крайней мере, правдоподобные значения. Однако на самом деле 
производные отношения также могут регулироваться ограничениями целостности. 
Например, ограничение для базового отношения S, утверждающее, что номера 
поставщиков должны быть уникальными, очевидно, будет использовано и во всех 
других ограничениях этого отношения. 
    • Как предполагается в предыдущем примере, производные отношения 
автоматически наследуют некоторые ограничения целостности отношений, из 
которых они выведены. Однако для производного отношения, кроме автоматически 
наследуемых ограничений, могут быть заданы также некоторые дополнительные 
ограничения целостности. 
    В этой главе, однако, для упрощения изложения рассматриваются только 
ограничения целостности, которые фактически применяются прежде всего к базовым 
отношениям. (В соответствии с этим термин "отношение", за исключением особо 
оговоренных случаев, будет в основном означать базовое отношение.) Ограничения 
целостности для производных отношений рассматриваются более подробно в 
следующей главе. 
    3. Следует учесть, что далее речь пойдет о декларативной поддержке 
ограничений целостности. К сожалению, к моменту написания этой книги 
существовало совсем немного реляционных и других СУБД, в которых была 
предусмотрена декларативная поддержка. В некоторых программных продуктах, 
наоборот, используется совершенно другой подход, называемый процедурной 
поддержкой. (Процедурная поддержка вкратце описывалась в главе 5, а более 
подробно обсуждается ниже в этой главе и далее в книге.) Однако если бы в СУБД 
была предусмотрена декларативная поддержка, то описание типичной базы данных 
на 90 % складывалось бы из объявлений ограничений целостности. Таким образом, 
работая в системе с такой поддержкой, программисты были бы избавлены от 
значительной части ненужной работы. В то же время это позволило бы им 
существенно повысить производительность. Поэтому декларативная поддержка — 
весьма важный аспект, который следует учитывать при разработке программного обеспечения. 
    4. Выше было отмечено, что термин "целостность" относится к точности или 
корректности данных в базе данных. То, что база данных находится в состоянии 
целостности, означает, что эта база данных корректна, а точнее, не нарушает ни 
одного ограничения целостности. Иначе говоря, база данных корректна тогда и 
только тогда, когда удовлетворяет логическому умножению всех известных 
ограничений. Совершенно очевидно, однако, что для системы, в которой не 
поддерживаются ограничения целостности, понятие корректности большого смысла 
не имеет. В главе 13 отмечалось, что термин восстановление означает 
возвращение к известному "корректному" состоянию. Кроме того, в главе 14 
упоминалось понятие параллелизма (или управления параллелизмом), которое 
означает, что допускающий упорядочение график запуска позволяет преобразовать 
одно "корректное состояние" базы данных в другое "корректное состояние". Из 
этого можно сделать вывод, что целостность является действительно более 
фундаментальным понятием, чем "вос становление" или "параллелизм". 
Действительно, поддержка целостности необходима даже в однопользовательских системах. 
    5. Следует напомнить читателю, что аспекты целостности необходимо 
учитывать как при проектировании базы данных, так и во время ее использования. 
Это значит, что при проектировании недостаточно правильно задать только структуру 

    Глава 16, Целостность	417 
    14 Введение в системы баз данных 

    данных, следует также указать необходимые ограничения целостности. 
Обратите внимание также на то, что "ограничения целостности" не обязательно 
относятся к функциональным и другим зависимостям, не обязательно связаны с 
понятиями целостности объектов и ссылочной целостности, которые на самом деле 
являются лишь частными случаями более общей задачи. 
    6.   Наконец, необходимо отметить, что (как уже упоминалось раньше) 
ограничения целостности, как и правила безопасности, хранятся в системном 
каталоге. Они приводятся в действие подсистемой целостности СУБД, которая 
ответственна за отслеживание выполняемых пользователем операций (INSERT, 
UPDATE, DELETE) и гарантирует выполнение только тех, которые не нарушают 
известных системе ограничений. 
    Замечание. Напомним читателю, что (как говорилось в первых главах) для 
повышения производительности некоторые утилиты, например утилита загрузки, 
могут функционировать непосредственно на внутреннем уровне системы. Однако 
описание способов такой реализации утилит, не нарушающих целостность, выходит 
за рамки данной главы. Этот вопрос еще будет обсуждаться далее в книге. 

    16.3. Ограничения целостности 

    В этом разделе ограничения целостности (правила целостности) описаны в 
общих чертах, а подробности представлены в последующих разделах. Ниже приведен 
один из примеров ограничения целостности. 

    CREATE INTEGRITY ROLE PR4 
    TORALL PX ( PX.WEIGHT > 0 ) 
    ON ATTEMPTED VIOLATION REJECT ; 

    Это записанное на некотором гипотетическом языке утверждение впервые было 
предложено в несколько ином виде в [16.5] и представляет собой не более чем 
расширенную форму утверждения о том, что вес товара должен быть положительным 
значением. Оно приведено именно в таком виде для того, чтобы 
проиллюстрировать, что ограничения целостности в общем случае содержат три компонента. 
    1.   Ограничение целостности регистрируется в системном каталоге под 
некоторым именем (в приведенном примере это PR4). Данное имя также 
используется в любых диагностических сообщениях системы в ответ на попытки 
нарушения этого ограничения. 
    2.  Ограничения целостности, которые обязательно должны удовлетворяться, 
задаются с помощью истинностного выражения, т.е. ограничение целостности 
удовлетворяется тогда и только тогда, когда это выражение истинно, а 
нарушается тогда и только тогда, когда это выражение ложно. 
    Замечание. В данном примере в ограничениях целостности с помощью квантора 
общности FORALL РХ указано, что все товары должны иметь вес больше нуля. 
(Здесь и далее в этой главе будут использоваться обычные обозначения SX, SY, 
... для представления переменных отношения S; обозначения PX, PY, ... — для 
представления переменных отношения Р и т.д. Кроме того, как отмечалось ранее в 
этой книге, для имени неявной переменной данного отношения часто будет 
использоваться сокращенное имя этого отношения.) Конечно, на практике 
достаточно проверять вес только у новых или обновленных товаров, а не у всех 
сразу. По крайней мере концептуально это может рассматриваться как 
оптимизация, тем не менее, ограничения рекомендуется задавать для "всех" 
товаров. Подробнее этот аспект обсуждается ниже в этой главе. 
    Обратите внимание, что, строго говоря, само по себе частное ограничение 
целостности является одним компонентом более общего правила целостности. 
Однако термины "ограничение целостности" и "правило целостности" часто 
используются как синонимы. 

    418	Часть IV. Защита данных 

    3.   Реакция на нарушение, заданная с помощью предложения ON ATTEMPTED 
VIOLATION, указывает системе те действия, которые необходимо выполнить при 
попытке пользователя нарушить ограничение целостности. В рассматриваемом 
примере реакция на нарушение заключается в простом отказе выполнить нарушающее 
целостность обновление. (При этом, конечно, устраняются все последствия 
нанесенного ущерба и предоставляется вся необходимая диагностическая 
информация.) Реакция такого типа наиболее часто применяется на практике, а 
потому ее следует задавать по умолчанию. Однако в общем случае реакция на 
нарушение может быть процедурой произвольной сложности. 
    При выполнении утверждения CREATE INTEGRITY RULE система должна сначала 
проверить, удовлетворяет ли текущее состояние базы данных некоторому заданному 
ограничению. Если это не так, то новое ограничение целостности может быть 
отвергнуто, в противном случае оно будет прийято (т.е. сохранено в каталоге) и 
с этого момента будет применяться далее. При задании ограничения целостности 
из рассматриваемого примера в СУБД будут отслеживаться все операции изменения 
или обновления значений атрибута P.WEIGHT. 
    Замечание о синтаксисе. На практике ограничение целостности почти всегда 
начинается с квантора общности, а в случаях, когда он отсутствует, его наличие 
предполагается по умолчанию. Соответственно этот квантор (общности) может быть 
по желанию опущен. Принимая это допущение, а также используя сокращенную 
запись (которая позволяет применять имя отношения для обозначения переменной 
области значений) и предполагая принятую по умолчанию реакцию на нарушение 
ограничения, исходную запись рассматриваемого примера можно значительно упростить: 

    CREATE INTEGRITY RULE PR4 P.WEIGHT > 0 ; 

    Конечно, для этого ограничения также следует задать правило его устранения: 

    DESTROY INTEGRITY RULE имя ; 

    Ниже приводится пример использования такого правила. 

    DESTROY  INTEGRITY RULE PR4   ; 

    В заключение следует привести краткую классификацию ограничений 
целостности. Их удобно классифицировать по четырем категориям, а именно: 
ограничения домена, атрибута, отношения и базы данных. 
    1. В ограничении целостности домена задаются допустимые значения для 
данного домена. 
    2.  В ограничении целостности атрибута задаются допустимые значения для 
данного атрибута. 
    3. В ограничении целостности отношения задаются допустимые значения для 
данного отношения. 
    4. В ограничении целостности базы данных задаются допустимые значения для 
этой базы данных. 
    Подробнее эти ограничения рассматриваются в следующих разделах. 

    16.4. Ограничения целостности домена 

    Ограничением целостности домена является определение множества значений, 
которые образуют этот домен. Иначе говоря, в ограничении просто перечисляются 
все допустимые значения домена. Поэтому в таком случае нет необходимости в 
создании отдельного утверждения типа CREATE DOMAIN INTEGRITY RULE, вместо 
этого его можно указать в соответствующем утверждении домена CREATE DOMAIN, например: 

    CREATE DOMAIN QTY NUMERIC (9) 
    FORALL QTY ( QTY > 0 AND 
    QTY < 5000 AND 
    MOD ( QTY, 50 ) = 0 ) ; 

    Глава 16, Целостность	419 

    В этом случае следует указать некоторые особенности. 
    •  Имя ограничения целостности домена и имя домена совпадают. 
    •  Поскольку сами домены никогда не обновляются (вместо этого обновляются 
значения атрибутов), сами по себе ограничения домена никогда не проверяются 
(вместо них проверяются ограничения атрибута, которые будут .описаны в 
следующем разделе). 
    •  Поэтому здесь не возникает вопроса о реакции на нарушение ограничения домена. 
    •  Указанное в определении домена ограничение, на которое иногда явным 
образом ссылаются как на ограничение домена, задается с помощью формулы 
реляционного исчисления (а в действительности — исчисления доменов). В этой 
формуле под квантором общности задается точно одна переменная, областью 
значений (диапазоном) которой является весь этот домен. В рассматриваемом 
примере в ограничении указано, что все значения должны делиться без остатка на 
50 и быть больше нуля, но меньше 5000. При этом квантор общности может быть опущен. 
    •  Устранить ограничение целостности домена можно только за счет 
устранения самого домена с помощью утверждения DESTROY DOMAIN. 
    Выражение VALUES (перечвнь_литералов_через_запятую) довольно удачно 
сокращает форму записи для ограничений целостности домена. Рассмотрим, 
например, утверждение CREATE DOMAIN: 

    CREATE DCMAIN COLOR CHAR   (6) 
    VALUES   (   'Red1,   'Yellow',   'Blue',   'Green'   )   ; 

    Оно эквивалентно следующему утверждению: 

    CREATE DCMAIN COLOR CHAR (6) FORALL COLOR 
    ( COLOR = 'Red' OR COLOR = 'Yellow' OR COLOR = 'Blue' OR COLOR = 'Green' ) ; 

    Также в случае необходимости можно использовать формы сокращенной записи 
диапазонов (например, а ТО Ь), рисунков (например, PIC '999-99-9999') и т.д. 

    Замечание. Следует отметить, что ограничения домена в стандарте языка SQL 
не идентичны данному выше определению ограничения домена. Подробнее это 
обсуждается несколько ниже в данной главе. 

    16.5. Ограничения целостности атрибута 

    Ограничение целостности атрибута — это определение домена, из которого 
выводятся значения для данного атрибута. Таким образом, нет никакой 
необходимости создавать отдельное утверждение типа CREATE ATTRIBUTE INTEGRITY 
RULE, вместо этого ограничение атрибута можно задать в виде отдельной части 
соответствующего определения атрибута. (Помните, что, за исключением особо 
оговоренных случаев, "отношение" здесь означает базовое отношение.) Ниже 
приведен пример ограничения целостности атрибута, который является частью 
утверждения CREATE BASE RELATION для отношения поставщиков S. 

    SNAME DCMAIN   ( хмя_дамена ) 

    Если спецификация имени домена в определении атрибута опущена, то 
предполагается, что атрибут задан для домена с тем же именем. 
    В этом случае следует учесть перечисленные ниже особенности. 
    •  Имя ограничения целостности атрибута совпадает с именем 
соответствующего ограничения домена, которое является именем домена. 
    •  Офаничения целостности атрибута всегда проверяются немедленно, т.е. 
любая попытка (с помощью операции вставки INSERT или обновления UPDATE) введе

    420	Часть IV. Защита данных 

ния в базу данных некоторого значения атрибута, не соответствующего 
заданным ограничениям, будет отвергнута (при этом данная операция будет 
отменена "немедленно"). 
    •  Как уже упоминалось, реакцией на нарушение ограничений целостности 
атрибута является выполнение операции REJECT с отменой действий, вызвавших это нарушение. 
    •  Указанное в определении атрибута ограничение, на которое иногда явным 
образом ссылаются как на ограничение атрибута, выводится очевидным образом из 
соответствующего ограничения домена. (Этот процесс обычно заключается в 
модификации ограничения домена с заменой ссылок на домен ссылками на атрибут.) 
    •  Ограничение целостности атрибута может быть снято только за счет 
устранения самого атрибута (что на практике обычно выполняется с помощью 
устранения содержащего его отношения). 

    16.6. Ограничения целостности отношения 

    Ограничение целостности данного отношения является правилом, заданным 
только для некоторого отношения и больше ни для какого другого отношения или 
домена. Ниже приведен пример ограничения целостности отношения, которое 
указывает, что "Следует отметить, что ограничение целостности атрибута на 
самом деле не более чем спецификация типа данных атрибута (здесь термин "тип 
данных атрибута" относится либо к встроенным типам данных, например 
NUMERlC(w), либо к заданным пользователем, например "номер поставщика"). 
Подробнее это описано далее в книге, поставщики в Лондоне должны обладать 
статусом 20". 

    CREATE INTEGRITY RULE SR7 
    FDRALL S ( IF S.CITY = 'London' THEN S.STATUS = 20 ) ON ATTEMPTED 
VIOLATION REJECT ; 

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

    CREATE INTEGRITY RULE имя ограничение [ ON ATTEMPTED VIOLATION действие ] ; 

    Пояснения: 
    • Параметр имя является именем этого ограничения. 
    • Ограничения целостности отношения всегда проверяются немедленно, т.е. 
концептуально заключительным этапом каждой операции обновления данного 
отношения является проверка всех заданных для этого отношения ограничений целостности. 
    •  Параметр ограничение (иногда на него ссылаются как на ограничение 
отношения) является закрытой формулой WFF (формулы WFF обсуждались в главе 7) 
в исчислении кортежей (или истинностным выражением реляционной алгебры, хотя 
для определенности здесь используется термин "исчисление"). Иначе говоря, это 
истинностное выражение, которое не содержит свободных переменных и потому 
однозначно оценивается либо как истинное, либо как ложное. Более того, каждая 
связанная (т.е. квантованная) переменная в этой формуле должна выполняться в 
области значений того же отношения, т.е. отношения, для которого заданы эти 
ограничения. В примере с ограничением SR7 существует только одна связанная 
переменная, а именно S, область значений которой ограничена отношением с тем 
же именем. 
    • Параметр действие (как правило) является процедурой произвольной 
сложности, которая вызывается в случаях, когда параметр ограничение 
оценивается как ложный. Как уже упоминалось выше, действием по умолчанию 
является просто отмена операции, вызвавшей нарушение ограничений целостности. 
Однако в более 

    Глава 16. Целостность	421 

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

    Замечание. Если вместо операции REJECT задана какая-то определенная 
процедура, то ее выполнение должно рассматриваться как часть выполнения 
операции обновления, включенной во время проверки целостности. Более того, 
после окончания выполнения этой процедуры снова должна быть выполнена проверка 
целостности. (Очевидно, что эта процедура не должна оставлять данное отношение 
в состоянии, нарушающем ограничения целостности.) 

    Ниже приведены некоторые примеры применения ограничений целостности отношения. 

    1. CREATE INTEGRITY RULE RX1 
    S.STATUS > 0 AND S.STATUS < 100 ; 

    В этом ограничении указано, что "значения статуса поставщиков должны быть 
в диапазоне 1-100". Здесь предполагается, что домен STATUS содержит значения, 
которые могут выходить за пределы заданного диапазона. Поэтому для атрибута 
STATUS в дополнение к существующему ограничению целостности задано еще одно 
условие ограничения диапазона. 
    Этим примером подчеркивается одна интересная особенность: ограничение 
целостности отношения применимо не только к одному отношению, но даже только к 
одному атрибуту этого отношения. Ограничение целостности PR4, показанное выше 
в этой главе ("вес должен быть положительным"), является примером другой 
особенности. На практике ограничения целостности отношения часто имеют именно 
такую простую форму. Возможно, поэтому в некоторых программных продуктах 
ограничения поддерживаются именно в таком виде (например, в виде "проверки 
принадлежности к области значений" или ограничений типа "null-значения не 
допускаются"), а не в более общей формулировке. К сожалению, в таких 
программных продуктах ограничения такого рода называют ограничениями 
целостности атрибута (или столбца). Однако автор считает, что определение 
атрибута, данное выше в этой главе, более логично, и хотел бы предостеречь 
читателей от возможности возникновения путаницы в этом вопросе. 
    2.  В следующем примере используется немного измененная версия отношения 
поставок SCP из главы 9 (см. рис. 9.1). Напомним, что отношение SCP содержит в 
дополнение к обычным атрибутам S#, P# и QTY атрибут CITY, представляющий 
город, в котором размещен соответствующий поставщик. 

    CREATE INTEGRITY RULE RX2 
    FORALL SCPX ( FDRALL SCPY 
    ( IF  SCPX.S* = SCPY.S# THEN SCPX.CITY = SCPY.CITY ) ) ; 

    Здесь указаны две связанные переменные — SCPX и SCPY — с диапазоном по 
всему отношению SCP. Ограничение указывает на то, что если у двух кортежей 
отношения SCP совпадают два значения атрибута S#, то в этом отношении у них 
также должны совпадать значения атрибута CITY. Иначе говоря, в этом отношении 
существует функциональная зависимость атрибута CITY от атрибута S#, более 
известная запись которой "S#-»CITY" может рассматриваться как сокращенный 
вариант этой формулировки. 

    422	Часть IV. Защита данных 

    Ниже приводится то же ограничение целостности отношения, для которого 
кванторы заданы неявным образом. 

    CREATE INTEGRITY RULE RX2 
    IF SCPX.S* = SCPY.S* THEN SCPX.CITY = SCPY.CITY ; 
    3. CREATE INTEGRITY RULE RX3 
    IF SX.S# = SY.S# THEN SX.SNAME = SY.SNAME AND SX.STATUS = SY.STATUS AND 
SX.CITY = SY.CITY ; 

    Если два кортежа отношения S совпадают по значению атрибута S#, то они 
также должны совпадать по всем другим значениям; иначе говоря, они просто 
представляют собой один и тот же кортеж. Таким образом, это ограничение 
утверждает, что атрибут S# является потенциальным ключом отношения S. Более 
известная запись такого утверждения типа CANDIDATE KEY (s#) может 
рассматриваться как сокращенный вариант этой формулировки (подробности ниже в 
этой главе). 

    4. CREATE INTEGRITY RULE RX4 
    COUNT ( P WHERE P.COLOR = 'Red' ) > 1 ; 

    (В этом ограничении указано, что "должно существовать по крайней мере два 
товара красного цвета".) В главе 7 отмечалось, что итоговые функции (COUNT и 
др.) в некоторых отношениях ведут себя так же, как и кванторы. Точнее говоря, 
ограничивающее условие в этом ограничении на самом деле выражается наличием 
переменной Р в выражении p.COLOR = 'Red1 (которая в данном случае является 
свободной). Это ограничение можно переписать, используя вместо директивы COUNT 
директиву EXISTS: 

    CREATE INTEGRITY RULE RX4 
    EXISTS PX   (  EXISTS  PY   (   PX.Ptt Ф PY.P# AND 
    PX.COLOR =   'Red'  AND PY.COLOR =  'Red'   )   )   ; 

    Следует отметить, что ограничение RX4 должно быть задано после того, как 
соответствующее множество кортежей будет введено в отношение Р (объясните 
почему?). Обратите внимание, что этот пример отличается от всех других 
примеров, которые рассматривались до сих пор, так как операции удаления DELETE 
потенциально способны нарушить целостность (хотя, с другой стороны, операции 
INSERT не нарушают ее). 
    В заключение следует напомнить, что (как уже объяснялось в главе 4) каждое 
отношение имеет связанный с ним предикат, в котором содержится критерий 
приемлемости операций обновления для данного отношения. Теперь эту концепцию 
можно выразить более точно. Фактически предикат отношения — это логическое 
умножение всех ограничений целостности отношения и всех ограничений 
целостности атрибутов, которые используются в этом отношении. 
    Не следует путать ограничения отношения с предикатами отношения. Попросту 
говоря, ограничение отношения является отдельным правилом, заданным для этого 
отношения, а предикат отношения является логическим умножением нескольких 
правил и, таким образом, формально выражает суть этого отношения. 

    16.7. Ограничения целостности базы данных 

    Ограничение целостности базы данных является правилом, которое задается 
для двух или более связанных между собой отношений. Ниже приводится пример 
такого ограничения, которое означает, что "поставщики со статусом меньше 20 не 
могут поставлять товары в количестве более 500". 

    CREATE INTEGRITY RULE C95 
    FORALL SX ( FORALL SPX 
    ( IF SX.STATUS < 20 AND SX.S# = SPX.S* THEN SPX.QTY < 500 } ) ; 

    Глава 16. Целостность	423 

    Его можно также записать без кванторов общности и соответствующих им 
скобок в следующем виде: 

    CREATE INTEGRITY RULE C95 
    IF SX.STATUS < 20 AND SX.S# = SPX.S* THEN SPX.QTY < 500 ; 

    В этом примере есть две связанные переменные — SX (для отношения S) и SPX 
(для отношения SP). Упражнение. Какие операции должны отслеживаться в СУБД для 
приведения в действие этого ограничения? 
    Общий синтаксис для ограничения целостности базы данных выглядит почти так 
же, как и для ограничений целостности отношения: 

    CREATE INTEGRITY RULE имя 
    ограничение [ ON ATTEMPTED VIOLATION действие ] 

    Однако между ними все же существуют некоторые важные различия. 
    •  Ограничение целостности базы данных должно включать по крайней мере 
одно "условие соединения", содержащее две различных связанных переменных, 
которые определены в двух разных отношениях (примером такого условия 
соединения может быть выражение "SP.S#=S.S#"). Таким образом, такое 
ограничение приводит к тому, что эти отношения становятся связанными между собой. 
    •  Ограничения целостности базы данных не проверяются немедленно. Проверка 
ограничений целостности базы данных, по крайней мере концептуально, 
откладывается до конца выполнения транзакции (операции COMMIT). Это делается 
для того, чтобы были выполнены обновления различных отношений. Для полного 
обновления всех этих отношений (в общем случае) может понадобиться выполнить 
несколько разных операций обновления. Некоторые ограничения базы данных (или, 
вероятно, большинство таких ограничений) могут быть "немедленно" проверены 
(точно так же, как проверялись ограничения целостности других типов), однако 
такую раннюю проверку следует рассматривать как оптимизацию, а не как присущее 
этому ограничению свойство. 
    •   По умолчанию в качестве параметра действие используется не операция 
отказа REJECT, а операция отката ROLLBACK. Часто никакие другие действия не 
будут иметь никакого смысла (поскольку не следует оставлять базу данных в 
некорректном состоянии). 

    Замечание. Если вместо операции отката ROLLBACK задана какая-то другая 
процедура, то ее следует рассматривать как часть выполнения операции 
обновления, вызванной включением проверки целостности. Более того, проверку 
ограничений целостности необходимо осуществить снова после окончания 
выполнения этой процедуры (следует убедиться в том, что по окончании этой 
процедуры база данных не осталась в состоянии, нарушающем ограничения целостности). 

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

    1. CREATE INTEGRITY RULE DBX1 
    FORALL SP ( EXISTS S ( S.S# = SP.S# ) AND EXISTS P ( P.P# = SP.P# ) ) ; 

    (В этом ограничении указано, что "каждой поставке должен соответствовать 
поставщик и товар".) При условии, что атрибут S# является потенциальным ключом 
для поставщиков, а атрибут Р# — потенциальным ключом для товаров, это правило 
задает ограничения ссылочной целостности между поставками, поставщиками и 
товарами. Обратите внимание, что в рассматриваемом примере квантор общности 
может быть опущен, а кванторы существования — нет! Однако обычно все-таки 
рекомендуется указывать все кванторы. 

    424 Часть IV. Защита данных 

    2. CREATE INTEGRITY RULE DBX2 
    FORALL P EXISTS SP ( SP.P# = P.P# ) ; 

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

    3.    CREATE INTEGRITY RULE DBX3 
    FORALL P   (   SUM   (SP WHERE SP.Pft = P.P#,   QTY)   < 2000   )   ; 

    (В этом ограничении указано, что "ни для какого товара сумма поставки не 
должна превышать 2000".) Обратите внимание, что в директиве WHERE переменная 
SP ограничена "квантором" SUM. Также следует отметить, что (как и в предыдущих 
примерах) квантор общности FORALL P может быть опущен, однако при рассмотрении 
данных примеров это может привести к ухудшению восприятия этих выражений. 
    В завершение следует заметить: как отношение обладает некоторым связанным 
с ним смысловым значением (для отношения это предикат отношения), так и база 
данных обладает некоторым связанным с ним значением — предикатом базы данных, 
который определяется как логическое умножение всех ограничений целостности 
базы данных и всех предикатов отношений, которые используются в этой базе 
данных. (Как и в случае с отношениями, не следует путать ограничения и 
предикаты. Попросту говоря, ограничение базы данных является отдельным 
правилом, а предикат базы данных является логическим умножением нескольких 
правил и, таким образом, формально выражает суть этой базы данных) 

    16.8. Ограничения состояния и перехода 

    Во всех описанных до сих пор примерах были представлены ограничения 
состояния, соотнесенные с теми или иными корректными состояниями базы данных. 
Однако иногда бывает необходимо рассмотреть переходы от одного состояния к 
другому. Например, в базе данных персонала для обработки допустимых изменений 
должны быть заданы ограничения перехода в данные о семейном положении. К таким 
допустимым изменениям можно отнести следующие: 
    •	никогда не состоял в браке — состоит в браке; 
    •	состоит в браке — овдовел; 
    •	состоит в браке — разведен; 
    •	разведен — состоит в браке. 
    А среди недопустимых изменений можно назвать такие: 
    •  никогда не состоял в браке — овдовел; 
    •  никогда не состоял в браке — разведен; 
    •  вдовствует — разведен; 
    •  разведен — овдовел. 
    Возвращаясь к примеру базы данных поставщиков и товаров, можно привести 
пример ограничения, означающего, что "статус поставщика не должен уменьшаться": 
    CREATE INTEGRITY RULE SR9 FORALL S' FORALL S ( IF S'.S# = S.S# THEN 
S'.STATUS < S.STATUS ) ; 

    Глава 16. Целостность	425 

    Пояснение. Вводится соглашение о том, что основная переменная области 
значений для соответствующего отношения определена так же, как она была 
определена до выполнения рассматриваемой операции обновления. (До сих пор 
неявно подразумевалось, что для соответствующего отношения все переменные 
определены как до, так и после обновления.) Тогда как представленное выше 
ограничение имеет следующий смысл: 
    Если S' и S являются кортежами поставщиков соответственно до и после 
выполнения операции обновления и если они имеют одинаковый номер поставщика 
(т.е. представляют собой один и тот же кортеж), то значение статуса в кортеже 
S' должно быть меньше или равно значению статуса в S. 
    То же ограничение можно записать в несколько иной форме, используя неявно 
заданные кванторы общности: 

    CREATE INTEGRITY RULE SR9 
    IF S'.S# = S.S# THEN S'.STATUS < S.STATUS ; 

    Поскольку это ограничение перехода задано для отношения (оно применяется к 
отношению поставщиков S), оно проверяется немедленно. Ниже для сравнения 
приводится ограничение перехода для базы данных. 

    CREATE INTEGRITY RULE AR43 FORALL S 
    ( SUM ( SP WHERE SP.S# = S.S#, QTY ) > ( SUM ( SP' WHERE SP'.St = S.S#, 
QTY ) ) ; 

    (Это ограничение указывает, что "общее количество любого товара, 
суммированное для всех поставщиков, может только возрастать".) Поскольку это 
ограничение задано для базы данных (оно содержит два разных отношения S и SP), 
его проверка будет отложена, а исходная переменная SP' определяется для 
отношения SP так же, как и перед началом выполнения транзакции. 
    Для доменов и атрибутов концепция ограничений состояния и перехода не 
имеет смысла. 

    16.9. Потенциальные и внешние ключи 

    Поскольку наиболее общие ограничения целостности (ограничения базы данных) 
не относятся логически только к одному простому отношению, из соображений 
симметрии можно заключить, что их следовало бы задавать отдельно, т.е. с 
помощью отдельных утверждений типа CREATE INTEGRITY RULE, как это делалось 
прежде. Поскольку точно таким же образом могут быть заданы отдельные 
ограничения отношений, из соображений эффективности и краткости их 
действительно следует так задавать; т.е. не рекомендуется "захламлять" язык их 
описания несколькими различными конструкциями, предназначенными для описания 
одной и той же сущности. (Здесь можно было бы возразить, что ограничения 
домена и атрибута задаются соответственно вместе с определением домена и 
атрибута (а ограничения базы данных задаются вместе с определением базы 
данных, что спорно), а потому ограничения отношения следовало бы задавать 
вместе с определением отношения. В любом случае этот вопрос не имеет большого 
значения и скорее носит психологический, чем логический характер.) 
    Однако такой подход, несмотря на его концептуальную чистоту, к сожалению, 
может привести к громоздким выражениям даже в самых простых и наиболее часто 
встречающихся ситуациях. В качестве иллюстрации этого утверждения рассмотрим 
пример, приводившийся выше в разделе 16.6: 

    CREATE INTEGRITY RULE RX3 
    IF SX.Stt = SY.Sff THEN SX.SNAME = SY.SNAME AND SX.STATUS = SY.STATUS AND 
SX.CITY = SY.CITY ; 

    426	Часть IV. Защита данных 

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

    CANDIDATE KEY ( S# ) 

    предпочтительнее, по крайней мере с точки зрения его восприятия. Однако, 
рассуждая логически, эта последняя формулировка не более чем сокращенная 
запись более громоздкой формулировки, приведенной выше. 
    Аналогичные замечания можно было бы сделать также и по отношению к внешним 
ключам. Например, ниже приводится общая формулировка для ограничения 
целостности, в которой указывается, что атрибут S# в отношении SP является 
внешним ключом соответствующего отношения S. 

    CREATE INTEGRITY RULE SPSFK 
    FORALL SP ( EXISTS S ( S.S# = SP.S# ) ) ; 

    Однако более краткая формулировка (которая является частью определения 
базового отношения SP) предпочтительнее: 

    FOREIGN KEY   (   S#   )   REFERENCES S   ... 

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

    CREATE INTEGRITY RULE SPSFK 
    FORALL SP ( EXISTS S ( S.S# = SP.Stt ) ) ON ATTEMPTED VIOLATION 
    DELETE SP WHERE NOT EXISTS S ( S.Stt = SP.S# ) ; 

    К концептуальным (т.е. не имеющим никакого отношения к оптимизации) 
выводам для этой формулировки можно отнести следующие: 
    1.  При попытке вставки (операция INSERT) кортежа SP, который не имеет 
никакого соответствия с кортежем S, кортеж SP будет удален. Общий результат: 
никаких изменений в базе данных выполнено не будет. 
    2.  При попытке обновления (операция UPDATE) номера поставщика в 
существующем кортеже SP значением, которое не имеет никакого соответствия с 
кортежем S, кортеж SP будет удален. Общий результат: операция обновления 
(UPDATE) будет заменена операцией удаления (DELETE). 
    3.  При попытке обновления (операция UPDATE) номера поставщика в 
существующем кортеже S все кортежи SP, которые перед этим имели соответствие с 
кортежем S, будут удалены. Общий результат: операция обновления (UPDATE) будет 
заменена операцией каскадного удаления (DELETE), а не каскадного обновления (UPDATE). 
    4.  При попытке удаления (операция DELETE) существующего кортежа S все 
кортежи SP, которые перед этим имели соответствие с кортежем S, будут удалены. 
Общий результат: операция удаления (DELETE) будет заменена операцией 
каскадного удаления (DELETE). 
    Первый вывод, очевидно, приемлем, поскольку позволяет сохранить корректное 
состояние и, следовательно, целостность. Четвертый приемлем, если есть 
необходимость в выполнении каскадного удаления. Что касается второго и 
третьего, то хотя они и приводят к сохранению целостности, но вряд ли приемлемы. 
    Приведенный пример показывает, что для задания необходимой реакции на 
нарушение ограничения (или указания процедур, компенсирующих такое нарушение) 
следует более подробно задавать методы обеспечения целостности. Конкретнее, 
необходимо разработать методы управления, в которых были бы предусмотрены 
особые компенсирующие процедуры для соответствующих операций обновления: 
например, "вызвать процедуру А при выполнении операции обновления" и "вызвать 
процедуру В при вы-

    Глава 16. Целостность	427 

    полнении операции удаления". (Обратите внимание, что в главе 5 в 
формулировках операций каскадного обновления (UPDATE CASCADES), ограниченного 
удаления (DELETE RESTRICTED) и т.д. использовались именно такие способы 
специализированного управления.) Более того, порой может потребоваться 
указать, будет ли данная процедура вызвана до или после соответствующей 
операции обновления. 
    Приведенные выше рассуждения скорее относятся к включаемым процедурам 
[16.8], а не к ограничениям целостности. Включаемой процедурой называется 
процедура, которая вызывается после выполнения некоторого заданного 
включаемого условия. В данном случае включаемым условием является нарушение 
ограничения целостности (до или после выполнения операции обновления), а целью 
включаемой процедуры — выполнение некоторых компенсирующих действий для 
приведения базы данных снова в целостное состояние. Однако в общем случае 
включаемые процедуры могут применяться и для более широкого круга проблем, а 
не только для рассматриваемых в этой главе вопросов поддержания целостности. 
(Включаемые процедуры могут быть чрезвычайно полезны для многих применений, но 
автор не рекомендует применять их для обеспечения целостности базы данных по 
причинам, изложенным в [16.6]. Там, где это только возможно, рекомендуется 
применять декларативные формулировки.) Эта тема чрезвычайно обширна и выходит 
за рамки данной главы; более подробное ее изложе ние можно найти в [16.8]. 

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

    Классификация ограничений целостности в стандарте языка SQL довольно 
сильно отличается от описанной выше схемы. В стандарте SQL такие ограничения 
делятся на три широкие категории. 
    1.	Ограничения домена. 
    2.	Ограничения базовой таблицы. 
    3.	Общие ограничения — "утверждения". 
    Ранее в этой книге уже были кратко описаны ограничения домена и базовой 
таблицы. Следует напомнить, что категория "ограничение базовой таблицы" может 
содержать различные формулировки потенциального, первичного и внешнего ключа. 
Более подробно эти вопросы были описаны в главе 8. Здесь же будут приведены 
некоторые дополнительные замечания, касающиеся этих понятий. 
    •  Ограничение домена в стандарте языка SQL не является (как это и должно 
быть) простым перечислением значений этого домена. Вместо этого оно может 
содержать формулировку ограничения произвольной сложности. 
    •  Ограничение базовой таблицы в стандарте языка SQL не является (как это 
и должно быть) простой ссылкой на эту базовую таблицу. Вместо этого оно может 
содержать формулировку ограничения произвольной сложности. 
    •  Ограничение базовой таблицы в стандарте языка SQL всегда 
удовлетворяется, если базовая таблица является пустой, даже когда само 
ограничение гласит: "эта таблица не должна быть пустой"! 
    Более подробная информация о некоторых неудачных следствиях реализации 
перечисленных выше понятий уже приводилась в этой книге. 
    Далее в этом разделе основное внимание уделяется общим ограничениям. Они 
создаются с помощью утверждения CREATE ASSERTION, которое в большей или 
меньшей мере соответствует утверждению CREATE INTEGRITY RULE и имеет следующий синтаксис: 

    CREATE ASSERTION имя CHECK   ( условное выражение 1   ; 

    428	Часть IV. Защита данных 

    Здесь в параметре имя задается имя нового правила, а в параметре 
услов-ное_выражение — соответствующее условие ограничения (условные выражения 
языка SQL описаны в главе 8). Для отмены общего ограничения используется 
выражение DROP ASSERTION с приведенным ниже синтаксисом: 

    DROP ASSERTION имя ; 

    Обратите внимание, что в отличие от всех других форм выражения отмены, 
приведенных в этой книге, выражение DROP ASSERTION не содержит директив 
RESTRICT или CASCADE. 
    Вот несколько примеров утверждения CREATE ASSERTION. 
    1.  Каждый поставщик обладает статусом не менее 5. 

    CREATE ASSERTION IC13 CHECK 
    ( ( SELECT MIN ( S.STATUS ) FROM S ) > 4 ) ; 

    2.  Каждый товар имеет положительный вес. 

    CREATE ASSERTION IC18 CHECK 
    ( NOT EXISTS ( SELECT * FROM P 
    WHERE NOT ( P.WEIGHT > 0 ) ) ) ; 

    3.  Все красные товары должны храниться в Лондоне. 

    CREATE ASSERTION IC99 CHECK 
    ( NOT EXISTS ( SELECT * FROM P 
    WHERE P.COLOR = 'Red1 
    AND  P.CITY <> 'London' ) ) ; 

    4.  He допускаются поставки с общим весом (произведение количества товаров 
на их вес) более чем 20 000. 

    CREATE ASSERTION IC46 CHECK 
    ( NOT EXISTS ( SELECT * FROM P, SP WHERE P.P# = SP.P# AND ( P.WEIGHT * 
SP.QTY ) > 20000 ) ) ; 

    5.  Поставщикам со статусом меньше 20 нельзя поставлять товары в 
количестве более 500. 

    CREATE ASSERTION IC95 CHECK 
    ( NOT EXISTS ( SELECT * FROM S, SP WHERE S.STATUS < 20 AND  S.S# = SP.S# 
AND  SP.QTY > 500 ) ) ; 


    Откладываемая проверка 

    Для любого ограничения целостности в стандарте SQL можно указать либо 
директиву DEFERRABLE (откладываемая), либо NOT DEFERRABLE (неоткладываемая). 
Причем для DEFERRABLE могут быть заданы дополнительно директивы INITIALLY 
DEFERRED (исходно откладываемая) или INITIALLY IMMEDIATE (исходно 
исполняемая), которые определяют ее состояние в начале выполнения транзакции. 
Откладываемые ограничения могут быть заданы с помощью приведенного ниже 
синтаксиса, где в качестве параметра задается либо IMMEDIATE, либо DEFERRED. 

    SET CONSTRAINTS имя параметр ; 

    Примером может служить следующее утверждение: 

    SET CONSTRAINTS IC46, IC95 DEFERRED ; 

    При выполнении операции завершения транзакции (COMMIT) все ограничения 
целостности переходят в выполняемое состояние IMMEDIATE. Очевидно, что 
ограничения DEFERRABLE проверяются только тогда, когда они находятся в 
состоянии IMMEDIATE, а ограничения NOT DEFERRABLE всегда проверяются немедленно. 

    Глава 16. Целостность	429 


    16.11. Резюме 

    В этой и предыдущей главе обсуждались аспекты безопасности и целостности 
системы управления базами данных. Следует отметить некоторые различия. 
    •   Безопасность означает защиту базы данных от несанкционированных пользователей. 
    •   Целостность означает защиту базы данных от санкционированных пользователей. 
    Оба понятия, среди прочего, включают определение множества соответствующих 
ограничений целостности, формулировку того, что следует сделать в случае 
нарушения этих ограничений, а также отслеживание системой операций, 
выполняемых пользователем для обнаружения таких нарушений. В отношении 
обеспечения целостности были рассмотрены следующие вопросы: 
    •   Гипотетический язык описания ограничений целостности. 
    •   Имя, условие ограничения и реакция на нарушение ограничения, которыми 
в общем случае обладает каждое ограничение целостности. 
    •  Ограничения  домена,   которые,   по  сути,  лишь   перечисляют  
значения  этого домена. 
    •   Ограничения атрибута, идентифицирующие домен, на основе которого 
определяются значения этого атрибута. 
    •   Ограничения отношения, относящиеся только к данному отношению и 
задающие условия для значений, которые могут присутствовать в этом отношении. 
    •  Ограничения базы данных, относящиеся к произвольной комбинации 
отношений и задающие условия для значений, которые могут присутствовать в этой 
комбинации отношений. 
    В этой главе также разъяснялось, что приведение в действие ограничений 
базы данных может быть отложено, т.е. их проверку можно отложить до конца 
транзакции, тогда как проверку других ограничений можно выполнить немедленно. 
Кроме того, были даны определения концепций предиката отношения и предиката 
базы данных, которые соответствуют формальному смысловому значению некоторого 
отношения и некоторой базы данных. Причем в случае ограничений отношения и 
базы данных было также сделано различие между ограничениями состояния и 
ограничениями перехода. В дополнение к этому было сделано предположение о том, 
что с практической точки зрения желательно использовать сокращенную 
синтаксическую запись, особенно по отношению к потенциальным и внешним ключам. 
Затем обсуждение этих вопросов постепенно трансформировалось в краткое 
описание вопросов включаемых процедур. 
    Что касается стандарта языка SQL, то в нем предусмотрена поддержка 
ограничений домена, ограничений базовых таблиц и общих ограничений 
(утверждений). Основное внимание при этом уделялось общим ограничениям 
(поскольку остальные два случая были описаны ранее в этой книге). Однако 
следует подчеркнуть, что общие ограничения и ограничения базовых таблиц 
взаимозаменяемы, т.е. они, по сути, представляют собой два разных способа 
выполнения одной и той же задачи [16.6]. Кроме того, здесь кратко была описана 
поддержка откладываемой проверки целостности в стандарте языка SQL и 
использование утверждения SET CONSTRAINTS. 
    В заключение следует подчеркнуть, что хотя во многих СУБД, существующих на 
момент написания этой книги, достаточно хорошо реализованы методы обеспечения 
безопасности, ни одну из них нельзя считать удовлетворительной с точки зрения 
целостности. Остается только надеяться, что такое положение вещей не продлится 
достаточно долго. 

    430 Часть IV. Защита данных 

    Упражнения 

    В упр. 16.1-16.16 требуется на основе описанного в данной главе 
гипотетического языка записать ограничения целостности для перечисленных ниже 
условий, заданных для базы данных, содержащей информацию о поставщиках, 
товарах и проектах. 
    16.1. Допустимыми городами являются Лондон (London), Париж (Paris), Рим 
(Rome), Афины (Athens), Осло (Oslo), Стокгольм (Stockholm), Мадрид (Madrid) и 
Амстердам (Amsterdam). 
    16.2. Все красные товары весят меньше 50 фунтов. 
    16.3. Никакие два проекта не могут быть размещены в одном и том же городе. 
    16.4. В любой момент времени в Афинах может находиться не более одного поставщика. 
    16.5. Ни одна поставка по количеству не может превышать удвоенное среднее 
значение количества для всех поставок. 
    16.6. Поставщик с наибольшим статусом не может находиться в одном городе с 
поставщиком с наименьшим статусом. 
    16.7. Каждый проект должен находиться в городе, в котором есть хотя бы 
один поставщик. 
    16.8. Каждый проект должен находиться в городе, в котором есть хотя бы 
один поставщик этого проекта. 
    16.9. Должен существовать по крайней мере один товар красного цвета. 
    16.10. Среднее значение статуса поставщика должно быть больше 15. 
    16.11. Каждый поставщик из Лондона должен поставлять товар Р2. 
    16.12. Хотя бы один красный товар должен весить меньше 50 фунтов. 
    16.13. При однократном обновлении количество товаров для любой поставки не 
должно уменьшаться более чем вдвое от его текущего значения. 
    16.14. Поставщики из Лондона поставляют больше видов товаров, чем 
поставщики из Парижа. 
    16.15. Поставщики из Лондона в целом поставляют большее количество 
товаров, чем поставщики из Парижа. 
    16.16. Поставщики из Афин могут переехать только в Лондон или Париж, а 
поставщики из Лондона — только в Париж. 
    16.17. Для каждого из ответов на упр. 16.1-16.16 укажите, являются ли они 
ограничениями отношения или ограничениями базы данных. 
    16.18. Для каждого из ответов на упр. 16.1-16.16 укажите операции, которые 
должны отслеживаться в СУБД для того, чтобы накладываемые ограничения не 
нарушались. Предположим, что в случае ограничений базы данных проверка должна 
быть выполнена "заранее", т.е. когда выполнение отслеживаемой операции еще не завершено! 
    16.19. Один из вопросов, который еще не обсуждался в этой главе, связан с 
ситуацией, когда пользователь пытается разрушить некоторое отношение или 
домен, а также некоторое существующее ограничение целостности, заданное для 
этого отношения или домена. Что может произойти в такой ситуации? 
    16.20. Запишите решения упр. 16.1—16.16 на языке SQL. 

    Глава 16. Целостность	431 

    Как уже упоминалось в главе 15 (ссылка [15.16]), в этой статье впервые был 
представлен метод модификации запроса в системе INGRES. Этот метод был 
использован как для ограничений целостности, так и для правил безопасности. 
Ограничения целостности были определены на основе утверждения DEFINE INTEGRITY 
со следующим синтаксисом: 
    DEFINE INTEGRITY ON отношение IS условие 
    В качестве примера его использования можно предложить утверждение 
    DEFINE INTEGRITY ON S IS S.STATUS > 0 
    Допустим, что пользователь U пытается выполнить следующую операцию REPLACE: 
    REPLACE S ( STATUS = S.STATUS - 10 ) WHERE S.CITY = "London" 
    В системе INGRES она будет автоматически заменена транзакцией 
    REPLACE S ( STATUS = S.STATUS - 10 ) WHERE S.CITY = "London" AND ( 
S.STATUS - 10 ) > 0 
    Конечно, измененная таким образом операция не сможет нарушить ограничение 
целостности. (Как и при обеспечении безопасности, описанной в главе 15, 
процесс модификации пройдет "бесшумно".) Преимущества и недостатки этой схемы 
весьма похожи на те, которые упоминались при обсуждении метода обеспечения 
безопасности с помощью языка QUEL в главе 15. Обратите внимание, что не все 
ограничения целостности могут быть приведены в действие таким же простым 
способом. Фактически, в языке QUEL поддерживаются только такие ограничения, 
которые задаются на основе простого ограничивающего условия. Однако даже такую 
ограниченную поддержку целостности можно найти не во всех системах. 
    16.12. Walker A., Salveter S. С. Automatic Modification of Transactions to 
Preserve Data Base Integrity Without Undoing Updates: Technical Report 
81/026.— Stony Brook, N.Y.: State University of New York, 1981. 
    В работе описан метод автоматической модификации любого "шаблона 
транзакции" (т.е. исходного кода транзакции) в соответствующий безопасный 
шаблон, который является безопасным в том смысле, что ни один экземпляр 
транзакции, созданной согласно этому модифицированному шаблону, не сможет 
нарушить заданные ограничения целостности. Этот метод функционирует за счет 
добавления к исходному шаблону запросов и тестов для того, чтобы перед 
выполнением обновления можно было убедиться, что никакие ограничения 
целостности не будут нарушены. Если один из этих тестов во время выполнения 
даст неверный результат, транзакция будет отменена с выдачей сообщения об ошибке. 

    Ответы к некоторым упражнениям 

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

    16.1. CREATE DOMAIN CITY CHAR (15) 
    VALUES ( 'London', 'Paris', 'Rome', 
    'Athens', 'Oslo', 'Stockholm', 'Madrid', 'Amsterdam' ) ; 
    16.2. CREATE INTEGRITY RULE IR2 
    IF P.COLOR = 'Red' THEN P.WEIGHT < 50 ; 

    434	Часть IV. Защита данных 

    16.3. CREATE INTEGRITY RULE IR3 
    FORALL JX FORALL JY ( IF JX.J# * JY.Jtt THEN JX.CITY Ф JY.CITY } ; 
    16.4. CREATE INTEGRITY ROLE IR4 
    COUNT ( S WHERE S.CITY = 'Athens' ) < 2 ; 
    16.5. CREATE INTEGRITY RULE IR5 
    SPJX.QTY < 2 * AVG ( SPJY.QTY ) ; 
    16.6. CREATE INTEGRITY RULE IR6 
    IF SX.SATUS = MAX ( S.STATUS ) AND SY.SATUS = MIN ( S.STATUS ) AND 
SX.SATUS * SY.STATUS THEN SX.CITY * SY.CITY ; 
    В действительности понятия "поставщик с наибольшим статусом" и "поставщик 
с наименьшим статусом" не очень хорошо определены, поскольку значения статуса 
не являются уникальными. Заданное требование интерпретируется так, что если SX 
и SY — любые поставщики с "наибольшим статусом" и "наименьшим статусом" 
соответственно, то SX и SY не должны размещаться в одном городе. Также 
включена проверка того, что "наибольший статус" и "наименьший статус" не равны 
друг другу, иначе заданное требование не будет выполняться. 
    16.7. CREATE INTEGRITY RULE IR7 
    FORALL J EXISTS S ( S.CITY = J.CITY ); 
    16.8. CREATE INTEGRITY RULE IR8 
    FORALL J EXISTS S EXISTS SPJ ( J.J# = SPJ.J# AND 
    SPJ.S# = S.S# AND S.CITY = J.CITY ); 
    16.9. CREATE INTEGRITY RULE IR9 IF EXISTS P { true ) THEN EXISTS P ( 
P.COLOR = 'Red' ) ; 
    Заданное условие ("должен существовать по крайней мере один товар красного 
цвета") невозможно удовлетворить, если имеется в виду, что оно должно 
выполняться в любой момент времени. 
    16.10. CREATE INTEGRITY RULE IR10 
    ( IF EXISTS S { true ) THEN AVG (S, STATUS) ELSE 20 ) > 15 ; 
    Выражение в скобках вычисляет среднее значение статуса, если существует 
хотя бы один поставщик, в противном случае этому выражению присваивается 
значение 20, т.е. большее, чем 15. Замечание. В данном случае проверка 
существования поставщика необходима, поскольку функция AVG при отсутствии 
аргумента может вызвать появление исключительной ситуации. 
    16.11. CREATE INTEGRITY RULE IR11 IF S.CITY = 'London' THEN EXISTS SPJ ( 
SPJ.S# = S.S# AND SPJ.P# = 'P2' ) ; 
    16.12. CREATE INTEGRITY RULE IR12 
    IF EXISTS P ( P.COLOR = 'Red' ) 
    THEN EXISTS P ( P.COLOR = 'Red' AND P.WEIGHT < 50 ) ; 
    16.13. CREATE INTEGRITY RULE IR13 
    SP.QTY > 0.5 * SP'.CTY 
    16.14. CREATE INTEGRITY RULE IR14 
    COUNT ( P WHERE EXISTS SPJ EXISTS S ( P.P# = SPJ.P# AND SPJ.S* = S.S# AND 
S.CITY = 'London' ) ) > COUNT { P WHERE EXISTS SPJ EXISTS S ( P.P# = SPJ.Pt 
AND SPJ.S# = S.S# AND S.CITY = 'Paris' ) \ ; 

    Глава 16. Целостность	435 

    16.15. CREATE INTEGRITY RULE IR15 
    SUM ( SPJ WHERE EXISTS S 
    ( SPJ.SS = S.S# AND 
    S.CITY = 'London' ), GTY ) > SUM ( SPJ WHERE EXISTS S 
    { SPJ.Sff = S.S# AND S.CITY = 'Paris' ), QTY ) ; 
    16.16. CREATE INTEGRITY RULE IR16 IF S'.CITY = 'Athens' 
    THEN S.CITY IN ( 'Athens', 'London', 'Paris' ) AND 
    IF S'.CITY = 'London' THEN S.CITY IN ( 'London', 'Paris' ) ; 

    16.17. Ограничение IR1 является ограничением целостности домена, а не 
отношения или базы данных. Ограничения IR7, IR8, IR11, IR14 и IR15 являются 
офаничениями целостности базы данных, а остальные ограничения — ограничениями 
целостности отношения. 
    Здесь мы сделаем одно замечание: ведомственные издания, рекламные брошюры 
и т.д. очень часто используют термин "база данных", имея в виду СУБД 
(например, "поставщик базы данных X делает это лучше поставщика базы данных Y 
в два раза"). Такое употребление термина небрежное, вызывает осуждение, но 
очень часто используется. (Предостережение автора.) 
    16.18. Далее для новых решений будет принята нумерация 16.18.я, где 16.я— 
номер исходного упражнения. В качестве дополнительного упражнения запишите 
правила для операций, которые необходимо отслеживать в СУБД для приведения в 
соответствие с заданным ограничением целостности.     
    16.18.1. Операции вставки (INSERT) для отношений S, P и J, а также 
операции обновления (UPDATE) для атрибутов S.CITY, P.CITY и J.CITY. 
    16.18.2. Операции вставки (INSERT) для отношения Р, а также операции 
обновления (UPDATE) для атрибутов P.COLOR и P.WEIGHT. 
    16.18.3. Операции вставки (INSERT) для отношения J, операции обновления 
(UPDATE) для атрибутов J.J# и J.CITY. Однако при условии, что задана 
уникальность потенциального ключа J.J#, достаточно (это относится только к 
ограничению IR3) проверить только операции обновления (UPDATE) для атрибута J.CITY. 
    16.18.4. Операции вставки (INSERT) для отношений S, а также операции 
обновления (UPDATE) для атрибута S.CITY. 
    16.18.5. Операции вставки (INSERT) и удаления (DELETE) для отношения SPJ, 
a также операции обновления (UPDATE) для атрибута SPJ.QTY. 
    16.18.6. Операции вставки (INSERT) и удаления (DELETE) для отношения S, а 
также операции обновления (UPDATE) для атрибутов S.STATUS и S.CITY. 
    16.18.7. Операции вставки (INSERT) для отношения J, операции удаления 
(DELETE) для отношения S, а также операции обновления (UPDATE) для атрибутов 
S.CITY и J.CITY. 
    16.18.8. Операции вставки (INSERT) для отношения J, операции удаления 
(DELETE) для отношений S и SPJ, а также операции обновления (UPDATE) для 
атрибутов S.S#, S.CITY, J.J#, J.CITY, SPJ.S# и SPJ.J#. 
    16.18.9. Операции вставки (INSERT) и удаления (DELETE) для отношения Р, а 
также операции обновления (UPDATE) для атрибута P.COLOR. 
    16.18.10. Операции вставки (INSERT) и удаления (DELETE) для отношения S, а 
также операции обновления (UPDATE) для атрибута S.STATUS. 

    436	Часть IV. Защита данных 

    16.18.11. Операции вставки (INSERT) для отношения S, операции удаления 
(DELETE) для отношения SPJ, а также операции обновления (UPDATE) для атрибутов 
S.S#, S.CITY, SPJ.S# и SPJ.P#. 
    16.18.12. Операции вставки (INSERT) и удаления (DELETE) для отношения Р, а 
также операции обновления (UPDATE) для атрибутов P.COLOR и P.WEIGHT. 
    16.18.13. Операции обновления (UPDATE) для атрибута SP.QTY. 
    16.18.14. Операции вставки (INSERT) и удаления (DELETE) для отношений S, P 
и SPJ, а также операции обновления (UPDATE) для атрибутов S.S#, S.CITY, Р.Р#, 
SPJ.S# и SPJ.P#. 
    16.18.15. Операции вставки (INSERT) и удаления (DELETE) для отношений S и 
SPJ, а также операции обновления (UPDATE) для атрибутов S.S#, S.CITY, SPJ.S# и SPJ.QTY. 
    16.18.16. Операции обновления (UPDATE) для атрибута S.CITY. 
    16.20. Далее для решений будет принята нумерация 16.20.и, где 16.п— номер 
исходного упражнения. 
    16.20.1. CREATE DOMAIN CITY CHAR (15) 
    CONSTRAINT VALID_CITIES CHECK ( VALUE IN 
    ( 'London', 'Paris', 'Rome', 'Athens', 'Oslo1, 'Stockholm', 'Madrid', 
'Amsterdam' ) ) ; 
    16.20.2. CREATE ASSERTION IR2 CHECK 
    ( P.COLOR 0 'Red' OR P.WEIGHT < 50 ) ; 
    16.20.3. CREATE ASSERTION IR3 CHECK 
    ( NOT EXISTS ( SELECT * FROM J JX WHERE EXISTS ( SELECT * FROM J JY WHERE 
( JX.J# 0 JY.J# AND JX.CITY <> JY.CITY ) ) ) ) ; 
    16.20.4. CREATE ASSERTION IR4 CHECK 
    ( ( SELECT COUNT(*) FRCM S 
    WHERE S.CITY = 'Athens' ) < 2 ) ; 
    16.20.5. CREATE ASSERTION IR5 CHECK 
    ( NOT EXISTS ( SELECT * 
    FRCM SPJ, SPJX WHERE SPJX.OTY > 2 * 
    ( SELECT AVG ( SPJY.OTY ) FROM SPJ SPJY ) ) ) ; 
    16.20.6. CREATE ASSERTION IR6 CHECK 
    ( NOT EXISTS ( SELECT * FRCM S SX WHERE EXISTS ( SELECT * FRCM S SY WHERE 
    SX.SATUS = ( SELECT MAX ( S.STATUS ) 
    FRCM S ) AND SY.SATUS = ( SELECT MIN ( S.STATUS ) 
    FROM S ) AND 
    SX.SATUS О SY.STATUS AND SX.CITY <> SY.CITY ) ) ) ; 
    16.20.7. CREATE ASSERTION IR7 CHECK 
    ( NOT EXISTS ( SELECT * FROM J WHERE NOT EXISTS ( SELECT * FROM S WHERE 
S.CITY = J.CITY ) ) ) ; 
    16.20.8. CREATE ASSERTION IR8 CHECK 
    ( NOT EXISTS ( SELECT * FRCM J WHERE NOT EXISTS ( SELECT * FROM S WHERE 
S.CITY = J.CITY AND EXISTS ( SELECT * FRCM SPJ 
    WHERE SPJ.S# = S.S# 
    AND  SPJ.J# = J.J# ) ) ) ) ; 

    Глава 16. Целостность	437 

    16.20.9. CREATE ASSERTION IR9 CHECK 
    ( NOT EXISTS ( SELECT * FRCM P ) OR EXISTS ( SELECT * FRCM P 
    WHERE P.COLOR = 'Red' ) ) ; 
    16.20.10. CREATE ASSERTION IR10 CHECK 
    ( ( SELECT AVG (S.STATUS) FRCM S ) > 15 ) ; 
    Если таблица поставщиков пуста, то функция AVG языка SQL возвратит 
null-значение, условное выражение будет иметь неопределенное значение, а 
заданное ограничение не будет расцениваться как нарушенное. 
    16.20.11. CREATE ASSERTION IR11 CHECK 
    ( NOT EXISTS ( SELECT * FROM S 
    WHERE S.CITY = 'London' AND  NOT EXISTS 
    ( SELECT * FRCM SPJ WHERE SPJ.S# = S.S# AND  SPJ.P# = 'P21 ) ) ) ; 
    16.20.12. CREATE ASSERTION IR12 CHECK 
    ( NOT EXISTS ( SELECT * FRCM P 
    WHERE P.COLOR = 'Red' ) OR EXISTS ( SELECT * FRCM P 
    WHERE P.COLOR = 'Red' AND  P.WEIGHT < 50 ) ) ; 
    16.20.13. He может быть выполнено, поскольку в SQL не предусмотрена 
поддержка ограничений перехода. 
    16.20.14. CREATE ASSERTION IR14 CHECK 
    (( SELECT COUNT;*) FROM P 
    WHERE EXISTS ( SELECT * FRCM SPJ WHERE EXISTS ( SELECT * FRCM S WHERE ( 
P.P# = SPJ.P# AND SPJ.S# = S.S# AND 
    S.CITY = 'London' ) ) ) ) > ( SELECT COUNT(*) FRCM P 
    WHERE EXISTS ( SELECT * FRCM SPJ WHERE EXISTS ( SELECT * FRCM S WHERE ( 
P.P# = SPJ.P* AND SPJ.Stt = S.S# AND S.CITY = 'Paris' ))))); 
    16.20.15. CREATE ASSERTION IR15 CHECK 
    ( ( SELECT SUM ( SPJ.OTY ) FRCM SPJ WHERE ( SELECT S.CITY FRCM S 
    WHERE ( S.S# = SPJ.Stt ) = 'London' ) > ( SELECT SUM ( SPJ.QTY ) FRCM SPJ 
WHERE ( SELECT S.CITY FRCM S 
    WHERE ( S.S# = SPJ.SI ) = 'Paris' ) ) ; 
    16.20.16. He может быть выполнено, поскольку в SQL не предусмотрена 
поддержка ограничений перехода. 

    438	Часть IV. Защита данных 

