Ответ 1
Существует четыре уровня ограничений: уровень уровня столбца, уровня строки, уровня таблицы и уровня схемы.
Уровень таблицы может, например, включать целевую таблицу, отличную от исходной таблицы, на которой он был объявлен, но проверяется только при изменении исходной таблицы. Теоретически ограничение на уровне схемы будет проверяться для каждого изменения в каждой таблице схемы, но на практике оптимизатор сможет обнаруживать изменения более гранулированным образом; следовательно, если ваша СУБД имела поддержку ограничения уровня схемы, то на практике вы бы не нашли большого смысла для ограничений на уровне таблиц.
Нет текущего продукта SQL поддерживает ограничения уровня схемы, т.е. CREATE ASSERTION
. По-видимому, Rdb действительно поддерживал его, когда он был рассмотрен DEC, но это уже не так. - UPDATE: в личном сообщении мне сообщили, что Sybase SQL Anywhere поддерживает CREATE ASSERTION
, но с серьезными ошибками, которые иногда допускают такие ограничения!
Единственный SQL-подобный продукт, который я использовал, который в настоящее время поддерживает подзапросы в CHECK
ограничениях, которые позволяют ограничения на уровне таблиц, - это механизм базы данных Access (ACE, Jet, любой). У этого есть проблемы. Во-первых, нет поддержки функциональности SQL-92 (или эквивалента) для отсрочки проверки ограничений. Во-вторых, ограничения на уровне таблиц проверяются для каждой затронутой строки, а не при завершении оператора в соответствии с требованиями стандарта SQL-92. Излишне говорить, что обходной путь очень неуклюж. отмените ограничение и при этом заблокируйте таблицу, выполните обновление, заново создайте ограничение. Ограничения на уровне схемы, возможно достижимые путем добавления того же ограничения ко всем таблицам, которые он использует, практически неработоспособны.
Возможно, по этим причинам команда доступа никогда не публиковала свои функции ограничения CHECK
по всем параметрам начальные объявления для Jet 4.0 ( он по-прежнему отсутствует в справке Access). Все, что было сказано, для ограничений внутри таблицы (например, секвенсорный ключ в временной таблице истории "истории" ) работает хорошо, особенно если учесть, что Access получил только триггерную функциональность (хотя и не основанную на SQL) год.
SQL, конечно, имеет ограничения UNIQUE
и ограничения ссылочной целостности, которые, конечно, являются табличными, но это особые случаи. Таким образом, все ограничения, с которыми вы столкнетесь "в дикой природе", будут либо colum-, либо row-level.
Имейте в виду MySQL, что, хотя использование CHECK()
в SQL DDL будет анализироваться без ошибок, оно не будет иметь никакого эффекта. То, как пользователи могут терпеть SQL-продукт без ограничений CHECK
вообще, вне меня! PostgreSQL имеет отличную модель ограничений, подсказка подсказки:)
Итак, почему ограничения между таблицами так разрешены? Одна из причин должна быть обусловлена историческими обстоятельствами. Поскольку @gbn корректно идентифицирует (под заголовком Concurrency), семейство SQL-систем Sybase/SQL Server основано на модели, которая не может справиться с проверкой ограничений между таблицами и что это не то, что может когда-либо измениться.
Подумайте об этом по-другому: если бы вы создавали SQL-продукт сегодня, включили бы вы CREATE ASSERTION
? Если бы вы это сделали, вам также необходимо было бы реализовать ограничения DEFERRABLE
(хотя множественное присвоение, возможно, является лучшей моделью). Но вы могли бы использовать гораздо больше исследований и опыта, если бы пошли по пути создания "традиционного" оптимизатора. И, возможно, вы обнаружите, что коммерческий спрос на ограничения уровня схемы не требуется (если MySQL может получить все равно без ограничений CHECK...) Если PostgreSQL этого не делает, я не думаю, что кто-либо когда-либо будет.
Я думаю, что настоящая шоу-стоппер состоит в том, что большинство продуктов промышленной прочности уже разработали триггерную функциональность, которая позволяет пользователям писать "ограничения" произвольной сложности (плюс может намного больше, например, отправить электронное письмо, чтобы сообщить что-то случилось). Конечно, они скорее процедурные, чем декларативные, кодер должен сделать много дополнительной работы, которую система позаботится с истинными ограничениями, а производительность, как правило, невелика. Но факт заключается в том, что они существуют в реальных продуктах сегодня и предоставляют карту "выйти из тюрьмы бесплатно" для поставщиков. Почему они должны пытаться реализовать достойные функции, если клиенты не били таблицу для них?
Что касается академических/обучающих языков, так как @Damien_The_Unbeliever правильно идентифицирует, Tutorial D CONSTRAINT
всегда являются "схемами" уровня, следовательно, по определению определяют глобальные ограничения произвольной сложности. Если вы хотите создать свою собственную СУБД (!!) с такой функциональностью, вам следует рассмотреть возможность реализации спецификации D при использовании существующей СУБД SQL для хранения, поскольку Dataphor.
Вопрос беспокоил меня: учитывая, что существующие SQL-сущности SQL "Industrial strength" поддерживают триггеры, почему они не просто отображают декларативный CREATE ASSERTION
триггер под обложками? Я давно подозревал, что ответ заключается в том, что они знают, что производительность будет ужасной, учитывая их унаследованную технологию.
Более удовлетворительный ответ предоставляется в Прикладная математика для профессионалов баз данных Лексом де Хааном, Toon Koppelaars, глава 11. Они определяют различное исполнение модели, которые следует использовать при использовании триггеров для принудительного применения ограничений с несколькими кортежами. Самая сложная (хотя и очень высокопроизводительная) модель, которую они называют EM6, включает в себя следующие шаги:
- Переведите формальную спецификацию в запрос проверки ограничений.
- Разработка кода для сохранения эффектов перехода.
- Запросить эффект перехода (TE), который гарантирует, что запрос проверки ограничений выполняется только при необходимости (например, Могу ли я ограничить проверку только обновленными строками? Может ли DELETE нарушать это ограничение? Существуют ли только определенные столбцы, которые должен включать UPDATE, чтобы потребовать проверки ограничения? и т.д.]
- Узнайте, как оптимизировать запрос проверки ограничений, запросив TE запрос, который можно использовать в запросе проверки.
- Придумайте и добавьте стратегию сериализации в код целостности данных (DI). [Т.е. решить проблему concurrecy, когда транзакция не может прочитать "плохие" данные, которые пишет другая транзакция].
Затем они утверждают (каламбур не предназначен!):
Поскольку мы считаем, что поставщику СУБД не представляется возможным программировать алгоритм, который принимает произвольно сложный предикат и затем вычисляет эффективные запросы эффекта перехода (TE), минимальные запрос проверки и оптимальный код сериализации для реализации модели исполнения EM6, мы не должны ожидать полной поддержки множественных кортежей ограничения - практичным, удобным и приемлемым способом - из этих поставщиков в будущем. Самое лучшее, на что мы можем надеяться, это то, что база данных исследователи сначала придумали более общие классы ограничений и разработайте для них удобные сокращения. Поставщики СУБД в своих поворот, должен затем предоставить нам новые декларативные конструкции, в соответствии с этими сокращениями, указать эти общие классы легко ограничивается СУБД. Учитывая такую общую декларацию класса, поставщик СУБД должен иметь возможность программировать алгоритм, который обеспечивает мы с моделью EM6-подобной модели под крышками для реализации ограничение.
Одним из таких общих классов ограничений базы данных является внешний ключ, который уже широко реализован, конечно.