Подтвердить что ты не робот

Почему СУБД не поддерживает утверждение

Итак, я недавно узнал об ASSERTION в моем курсе баз данных, и мой проф отметил, что основные базы данных не поддерживают его, даже если он находится в стандарте SQL-92. Я попробовал поиск в Google, чтобы узнать, почему, но, похоже, не было обсуждения по этой теме.

Итак, почему не поддерживается ASSERTION подавляющим большинством пакетов реляционных баз данных? Является ли это проблемой производительности или есть что-то внутренне жесткое?


Если вы можете, обратите внимание на любые пакеты баз данных, которые его реализуют (пример: если есть учебная/обучающая БД). Кроме того, почему так мало обсуждений по этому вопросу? он даже не упоминается на странице Википедии для SQL или SQL-92). Но сначала ответьте на главный вопрос или ответьте в комментариях.

Я не ищу, как реализовать его с помощью триггеров или чего-то еще.

4b9b3361

Ответ 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-подобной модели под крышками для реализации ограничение.

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

Ответ 2

Мои 2 пенни:

  • Concurrency: Если вы берете "ограничение CHECK с использованием решения" скалярный udf с доступом к таблице "для SQL Server, это просто небезопасно. Утверждение, вероятно, будет таким же в механизмах типа Sybase/SQL Server

Изменить: что я имею в виду, описано в этих ссылках: Скалярные UDF, завернутые в ограничения CHECK, очень медленные и могут терпеть неудачу для многократных обновлений и из Тони Роджерсон

  • Производительность. Вставка 10 тыс. строк потребует выполнения 10 тыс. udf-стилей, каждый из которых имеет доступ к таблице. Уч. Учитывая, что УКАЗАТЕЛЬ относится к каждой строке, тогда он должен действовать. Если он может работать для "всех строк в INSERT", то он проще в качестве триггера, нет?

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

Ответ 3

(Non-SQL, обычно считается академическим, не называется ASSERTION) D (ака. Учебник D) имеет CONSTRAINT, который может быть произвольное ограничение на базу данных. Одна реализация называется Rel

Ответ 4

В Oracle 10g есть рудиментарная поддержка:

http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/d_assert.htm

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

<assertion definition> ::=
          CREATE ASSERTION <constraint name> <assertion check>
          [ <constraint attributes> ]

<assertion check> ::=
          CHECK <left paren> <search condition> <right paren>

См. главу 11.34 http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt

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

Ответ 5

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

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

Чтобы обеспечить удобный способ, СУБД реализовали TRIGGER и CHECK s. Таким образом, никто не нуждается в утверждениях.

Ответ 6

"Если вы можете, обратите внимание на любые пакеты баз данных, которые также реализуют его"

SIRA_PRISE полностью поддерживает эту функцию. Раскрытие информации: Я автор.

(Что касается фактического вопроса "почему не поставщики СУБД, предлагающие это": вам действительно нужно спросить поставщиков, но (а) это чрезвычайно сложная проблема для решения даже в действительно реляционной системе ( б) эта сложность сильно усугубляется тем фактом, что SQL нигде не близка к истинно реляционной, и (с) очень вероятно, что большинство программистов считают себя достаточно компетентными, чтобы добиться того же эффекта, что и декларативные УКАЗАНИЯ, используя триггеры, а это не гораздо более высокая стоимость разработки.)

Ответ 7

Oracle рассматривает это как возможное усовершенствование для следующей версии после 12c Release 2, см. этот пост с мая 2016 года Toon Koppelaars.

Если вы заинтересованы в этой функции, я предлагаю ее активировать.