2008 г.
Базы данных. Вводный курс
Сергей Кузнецов
Назад Содержание Вперёд
21.3.3. Раздел WITH CHECK OPTION определения представления
Пусть в базе данных имеется упрощенная таблица EMP
, содержащая следующее множество строк (как в примере с GROUP BY ROLLUP
разделе 20.2. Возможности формулирования аналитических запросов лекции 20):
EMP
EMP_NO | DEPT_NO | EMP_BDATE | EMP_SAL |
---|
2440 | 1 | 1950 | 15000.00 |
2441 | 1 | 1950 | 16000.00 |
2442 | 1 | 1960 | 14000.00 |
2443 | 1 | 1960 | 19000.00 |
2444 | 2 | 1950 | 17000.00 |
2445 | 2 | 1950 | 16000.00 |
2446 | 2 | 1960 | 14000.00 |
2447 | 2 | 1960 | 20000.00 |
2448 | 3 | 1950 | 18000.00 |
2449 | 3 | 1950 | 13000.00 |
2450 | 3 | 1960 | 21000.00 |
2451 | 3 | 1960 | 22000.00 |
Предположим, что в базе данных имеется представление RICH_EMP
, определенное следующим образом:
CREATE VIEW RICH_EMP AS
SELECT *
FROM EMP
WHERE EMP_SAL > 18000.00;
Понятно, что в соответствии с правилами SQL (и здравым смыслом) над этим представлением можно выполнять операции обновления. Как видно, в таблице EMP
содержится строка, которая соответствует служащему с номером 2447
, получающему зарплату в размере 20000
руб. Естественно, эта строка будет присутствовать в виртуальной таблице RICH_EMP
. Поэтому можно было бы выполнить, например, операцию
UPDATE RICH_EMP
SET EMP_SAL = EMP_SAL – 3000
WHERE EMP_NO = 4452;
Но если выполнение такой операции действительно допускается, то в результате строка, соответствующая служащему с номером 2447
, исчезнет из виртуальной таблицы RICH_EMP
! Аналогичный эффект возникнет при выполнении операции вставки
INSERT INTO RICH_EMP (EMP_NO) 2452;
В базовой таблице EMP
появится строка, в которой значением столбца EMP_NO
будет 2452
, а значения остальных столбцов будут установлены по умолчанию. В частности, значением столбца EMP_SAL
будет 10000.00
. Тем самым, если подобная операция вставки действительно допустима, то мы вставили в виртуальную таблицу RICH_EMP
строку, которую в этой виртуальной таблице увидеть невозможно.
Чтобы избежать такого противоречивого поведения представляемых таблиц, нужно включать в определение представления раздел WITH CHECK OPTION
. При наличии этого раздела до реального выполнения операций модификации или вставки строк через представление для каждой строки будет проверяться, что она соответствует условиям представления. Если данное условие не выполняется хотя бы для одной модифицируемой или вставляемой строки, то операция полностью отвергается. В некотором смысле (при наличии раздела WITH CHECK OPTION
) условие выборки, содержащееся в выражении запросов представления, можно считать ограничением целостности этого представления.
Режимы проверки CASCADED и LOCAL
Вспомним теперь, что в полном виде синтаксис раздела WITH CHECK OPTION
может включать ключевые слова CASCADED
или LOCAL
(см. подраздел 17.3.7. Представляемые таблицы, или представления (VIEW) лекции 17). Обсудим их смысл. Предположим, что представление V2
определяется над представлением V1
следующим образом:
CREATE VIEW V2 AS
SELECT ...
FROM V1
WHERE ...
[ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
Пусть над V2
выполняется некоторая операция O
обновления базы данных. Тогда:
- если представление
V2
определялось без раздела WITH CHECK OPTION
, то при выполнении операции O
будут проверяться все условия, определяющие ограничения целостности V1
(если в определении V1
присутствовал раздел WITH CHECK OPTION
), но никаким образом не будут учитываться условия выборки, содержащееся в выражении запросов представления V2
; - если в определении представления
V2
содержался раздел WITH LOCAL CHECK OPTION
, то при выполнении операции O
будут проверяться все условия, определяющие ограничения целостности V1
, и все условия, содержащееся в выражении запросов представления V2
; - наконец, если в определении представления
V2
содержался раздел WITH CASCADED CHECK OPTION
, то при выполнении операции O
будут проверяться все условия, определяющие ограничения целостности V1
(так, как если бы в определении V1
присутствовал раздел WITH CASCADED CHECK OPTION
). Тем самым, будут проверяться все ограничения целостности, установленные для всех базовых таблиц, на которых основывается определение V1
; все условия всех представлений, определенных над этими базовыми таблицами; и, конечно, все условия, содержащиеся в выражении запросов представления V2
.
Примеры результатов действия раздела WITH CHECK OPTION
Чтобы пояснить результаты действия раздела WITH CHECK OPTION
, допустим, что в базе данных присутствуют определения двух представлений MIDDLE_RICH_EMP
и MORE_RICH_EMP
:
CREATE VIEW MIDDLE_RICH_EMP AS
SELECT *
FROM EMP
WHERE EMP_SAL < 20000.00
[ WITH [ CASCADED | LOCAL ] CHECK OPTION ];
CREATE VIEW MORE_RICH_EMP AS
SELECT *
FROM MIDDLE_RICH_EMP
WHERE EMP_SAL > 18000.00
[ WITH [ CASCADED | LOCAL ] CHECK OPTION ];
Очевидно, что в тело (материализованного) представления MIDDLE_RICH_EMP
будут входить следующие строки базовой таблицы EMP
:
MIDDLE_RICH_EMP
EMP_NO | DEPT_NO | EMP_BDATE | EMP_SAL |
---|
2440 | 1 | 1950 | 15000.00 |
2441 | 1 | 1950 | 16000.00 |
2442 | 1 | 1960 | 14000.00 |
2443 | 1 | 1960 | 19000.00 |
2444 | 2 | 1950 | 17000.00 |
2445 | 2 | 1950 | 16000.00 |
2446 | 2 | 1960 | 14000.00 |
2448 | 3 | 1950 | 18000.00 |
2449 | 3 | 1950 | 13000.00 |
В тело (материализованного) представления MORE_RICH_EMP
будут входить следующие строки представляемой таблицы MIDDLE_RICH_EMP
:
MORE_RICH_EMP
EMP_NO | DEPT_NO | EMP_BDATE | EMP_SAL |
---|
2443 | 1 | 1960 | 19000.00 |
В каждом из представлений MIDDLE_RICH_EMP
и MORE_RICH_EMP
может отсутствовать или присутствовать (в одном из двух видов) раздел WITH CHECK OPTION
. В совокупности возможен один из девяти случаев:
MORE_RICH_EMP | none | LOCAL | CASCADED |
---|
MIDDLE_RICH_EMP |
---|
none | Случай 1 | Случай 2 | Случай 3 |
LOCAL | Случай 4 | Случай 5 | Случай 6 |
CASCADED | Случай 7 | Случай 8 | Случай 9 |
Чтобы рассмотреть каждый из возможных случаев по отдельности, обсудим, что будет происходить в каждом случае при выполнении следующих двух операций модификации строк (будем называть эти операции U1
и U2
соответственно)160):
UPDATE MORE_RICH_EMP
SET EMP_SAL = EMP_SAL + 7000.00;
UPDATE MORE_RICH_EMP
SET EMP_SAL = EMP_SAL – 7000.00;
Случай 1. Ни в одном из представлений не содержится раздел WITH CHECK OPTION
.
Первый неожиданный результат состоит в том, что после выполнения операции U1
тело представления MORE_RICH_EMP
оказывается пустым. Действительно, у единственной строки таблицы EMP
(со значением EMP_NO
, равным 2443
), одновременно удовлетворяющей условиям обоих представлений, столбец EMP_SAL
принимает значение 26000.00
. После этого строка перестает удовлетворять условию представления MIDDLE_RICH_EMP
и исчезает из результирующей таблицы MORE_RICH_EMP
. Этот результат может быть особенно неожиданным для пользователей базы данных, которым известно, что условие представления MORE_RICH_EMP
имеет вид EMP_SAL > 18000.00
, и соблюдение этого условия должно сохраняться при увеличении размера зарплаты.
Выполнение операции U2
также приведет к опустошению тела MORE_RICH_EMP
(в базовой таблице EMP
не останется ни одной строки, удовлетворяющей условию этого представления). Возможно, это будет достаточно естественно для пользователей представления MORE_RICH_EMP
, которым известно условие представления, но те, кто работает с представлением MIDDLE_RICH_EMP
, с удивлением обнаружат в теле результирующей таблицы новые строки.
Случай 2. В определении представления MIDDLE_RICH_EMP
содержится раздел WITH LOCAL CHECK OPTION
, а в определении MORE_RICH_EMP
раздел WITH CHECK OPTION
отсутствует.
В этом случае, в соответствии с первыми двумя правилами проверки корректности выполнения операций обновления над представлениями, операция U1
должна быть отвергнута системой (поскольку ее выполнение нарушает условие представления MIDDLE_RICH_EMP
). Но заметим, что такое поведение системы будет совершенно неожиданным и непонятным для тех пользователей базы данных, которым известно только определение «верхнего» представления MORE_RICH_EMP
, поскольку операция U1
явно не может нарушить видимое ими ограничение.
С другой стороны, операция U2
будет успешно выполнена и по-прежнему приведет к опустошению тела результирующей таблицы представления MORE_RICH_EMP
.
Случай 3. В определении представления MIDDLE_RICH_EMP
содержится раздел WITH CASCADED CHECK OPTION
, а в определении MORE_RICH_EMP
раздел WITH CHECK OPTION
отсутствует.
В этой ситуации будут проверяться условия, содержащиеся в определении представления MIDDLE_RICH_EMP
, а также все ограничения целостности таблицы EMP
и всех других представлений, определенных над этой базовой таблицей. В результате операция U1
будет отвергнута системой, а операция U2
будет «успешно» выполнена. Другими словами, повторится Случай 2.
Случай 4. В определении представления MIDDLE_RICH_EMP
раздел WITH CHECK OPTION
отсутствует, а в определении MORE_RICH_EMP
содержится раздел WITH LOCAL CHECK OPTION
.
Понятно, что в этом варианте операция U2
не сработает (ее выполнение не будет допущено условием «ограничения целостности» представления MORE_RICH_EMP
). Но операция U1
(увеличение размера зарплаты служащих) будет успешно выполнена, поскольку она не противоречит локальным ограничениям представления MORE_RICH_EMP
.
Случай 5. В определениях представлений MIDDLE_RICH_EMP
и MORE_RICH_EMP
содержится раздел WITH LOCAL CHECK OPTION
.
Выполнение обеих операций U1
и U2
будет справедливо отвергнуто. На первый взгляд все в порядке. Но если над представлением MORE_RICH_EMP
будет определено еще одно представление V
, то мы можем получить ситуацию Случая 2, где V
будет играть роль MORE_RICH_EMP
, а MIDDLE_RICH_EMP
– роль MORE_RICH_EMP
.
Случай 6. В определении представления MIDDLE_RICH_EMP
содержится раздел WITH CASCADED CHECK OPTION
, а в определении MORE_RICH_EMP
содержится раздел WITH LOCAL CHECK OPTION
.
Снова, если над представлением MORE_RICH_EMP
будет определено еще одно представление V
, то мы можем попасть в ситуацию Случая 2, где V
будет играть роль MORE_RICH_EMP
, а MIDDLE_RICH_EMP
– роль MORE_RICH_EMP
.
Случай 7. В определении представления MIDDLE_RICH_EMP
раздел WITH CHECK OPTION
отсутствует, а в определении MORE_RICH_EMP
содержится раздел WITH CASCADED CHECK OPTION
.
Если над представлением MORE_RICH_EMP
будет определено еще одно представление V
, то мы можем попасть в ситуацию Случая 3, где V
будет играть роль MORE_RICH_EMP
, а MIDDLE_RICH_EMP
– роль MORE_RICH_EMP
.
Случай 8. В определении представления MIDDLE_RICH_EMP
содержится раздел WITH LOCAL CHECK OPTION
, а в определении MORE_RICH_EMP
– раздел WITH CASCADED CHECK OPTION
.
Если над представлением MORE_RICH_EMP
будет определено еще одно представление V
, то мы можем получить ситуацию Случая 3, где V
будет играть роль MORE_RICH_EMP
, а MIDDLE_RICH_EMP
– роль MORE_RICH_EMP
.
Случай 9. В определениях представлений MIDDLE_RICH_EMP
и MORE_RICH_EMP
содержится раздел WITH CASCADED CHECK OPTION
.
Только в этом случае операции обновления будут выполняться корректно, независимо от того, имеются ли в базе данных представления, определенные над MORE_RICH_EMP
или между MORE_RICH_EMP
, MIDDLE_RICH_EMP
и EMP
.
Очевидный вывод из приведенного анализа заключается в том, что единственным способом обеспечить корректность выполнения операций обновления через представления (допускающие операции обновления) является включение в определение каждого представления раздела WITH CASCADED CHECK OPTION
. В этом случае поведение системы будет оставаться корректным при введении дополнительных представлений над представлением MORE_RICH_EMP
, между представлениями MORE_RICH_EMP
и MIDDLE_RICH_EMP
или между представлением MIDDLE_RICH_EMP
и базовой таблицей EMP
, если в определениях всех этих представлений присутствует раздел WITH CASCADED CHECK OPTION
.
21.3.4. Исторический очерк
Завершим обсуждение возможностей применения операций обновления к виртуальным таблицам небольшим экскурсом в историю. На протяжении более чем тридцатилетней истории реляционных баз данных вопрос о возможности однозначной интерпретации операций обновления баз данных через виртуальные таблицы интересовал многих исследователей. Причины этого интереса состоят в следующем.
Во-первых, как отмечалось в лекции 4, одной из наиболее привлекательных черт реляционной алгебры является замкнутость относительно понятия отношения. В любой алгебраической операции, операндом которой является отношение, в качестве операнда можно использовать алгебраическое выражение. С другой стороны, имеется явное неравноправие по отношению к операциям обновления. Мы можем вставлять, модифицировать и удалять кортежи в базовых отношениях, но не можем (в общем случае) применять эти операции к алгебраическим выражениям. Хотелось максимальным образом устранить подобное неравноправие.
Во-вторых, на первый взгляд задача не является слишком трудной (по крайней мере, если оставаться в пределах реляционной алгебры). Действительно, базовых операций совсем немного, и каждая базовая операция очень проста.
К сожалению, это ощущение простоты проблемы оказалось обманчивым. Было выполнено множество исследований, опубликовано множество статей (нам кажется нецелесообразным приводить список этих статей в данном курсе), но так и не удалось обнаружить полное множество алгебраических выражений, для которых возможна однозначная интерпретация операций обновления. На мой взгляд, данная ситуация оказала заметное влияние на подход к решению проблемы применимости операций обновления к виртуальным таблицам, которым руководствуются разработчики языка SQL.
В двух первых международных стандартах (SQL/89 и SQL/92) к виду таких виртуальных таблиц предъявлялись чрезмерно строгие требования. Это показывают даже те простые примеры, которые приводились в начале данного раздела. И конечно, наличие таких ограничений в стандарте языка приводило к тому, что в реализациях SQL появлялось много расширений, которые поддерживались только отдельными компаниями-производителями СУБД. Создается впечатление, что когда более десяти лет назад был инициирован проект нового стандарта SQL-3 (который в конце концов привел к появлению SQL:1999), разработчики находились в состоянии растерянности.
Кстати, одна из идей, включавшихся в ранние варианты проекта SQL-3, состояла в том, чтобы расширить определение представляемой таблицы средствами, позволяющими явно специфицировать действия, которые нужно предпринимать при выполнении над представлением операций INSERT
, UPDATE
и DELETE
. Другими словами, предлагалось переложить решение проблемы на плечи пользователей СУБД. Конечно, это радикальный подход, но, с другой стороны, он мог бы привести к полной анархии.
Как можно заметить, в официально принятом стандарте SQL:1999 используется некоторый компромиссный подход. В стандарте не фиксируются жесткие правила, ограничивающие вид виртуальных таблиц, к которым применимы операции обновления. Вместо этого сформулирован ряд рекомендаций, которыми следует руководствоваться производителям СУБД. Нельзя утверждать, что такое решение является идеальным, но более удачного решения найти не удалось.
160 Будем считать, что тем, кто пользуется представлением MORE_RICH_EMP
, неизвестно ограничение EMP_SAL < 20000.00
, на котором основывается представление MIDDLE_RICH_EMP
.
Назад Содержание Вперёд