Ограничение деферрабильности на простом английском языке [дубликат]

Разница в том, что OrElse и AndAlso будут замыкаться на короткое замыкание на основе первого условия, что означает, что если первое условие не пройдет, второе (или более) условие не будет оценено. Это особенно полезно, когда одно из условий может быть более интенсивным, чем другое.

Пример, где Or является точным (оба условия оцениваются):

If Name = "Fred" Or Name = "Sam" Then

Это действительно doesn «независимо от того, каким образом они оцениваются

. Следующая AndAlso полезна, потому что второе условие может потерпеть неудачу

If Not SomeObject Is Nothing AndAlso CheckObjectExistsInDatabase(SomeObject) Then

Это позволяет первому условию проверить, является ли объект был установлен, и только если он был установлен, пойдет и проверит базу данных (или другую задачу). Если это было простое ключевое слово And, оба будут оцениваться.

62
задан Pieter 14 March 2011 в 15:56
поделиться

4 ответа

С помощью DEFERRABLE INITIALLY IMMEDIATE вы можете отложить ограничения по требованию, когда вам это нужно.

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

Синтаксис, как отложить ограничения, различен для разных СУБД.

С NOT DEFERRABLE вы никогда не будете способный отложить проверку до момента фиксации.

50
ответ дан Arturo Herrero 20 August 2018 в 22:15
поделиться
  • 1
    Я должен указать, что я еще должен хорошо использовать NOT DEFERRABLE. Все, что он делает, вызывает проблемы. Я рекомендую использовать DEFERRABLE INITIALLY IMMEDIATE по умолчанию. – Roman Starkov 13 December 2011 в 18:29
  • 2
    @romkyns: DEFERRABLE заявляет намерение дизайнера о том, что отсрочка ограничения является стоящим или необходимым действием. Это не относится к подавляющему большинству ограничений базы данных и маркировке всех, поскольку DEFERRABLE потеряет это полезное различие. – onedaywhen 21 December 2011 в 17:44
  • 3
    @oneday, когда мой коллега с тех пор указал на хорошую обоснованную причину: на самом деле вы можете полагаться на непредусмотренные ограничения в любой точке любой транзакции, но отложенные только определенно наблюдаются в начале транзакции. – Roman Starkov 21 December 2011 в 18:28
  • 4
    @romkyns: Я в целом согласен :) – onedaywhen 22 December 2011 в 09:34

NOT DEFERRABLE - вы не можете изменить проверку ограничений, oracle проверяет ее после каждого утверждения (т. е. непосредственно после инструкции insert).

DEFERRABLE INITIALLY IMMEDIATE - проверка оракула после каждого утверждения. НО, вы можете изменить его после каждой транзакции (т. Е. После фиксации):

set constraint pk_tab1 deferred;
2
ответ дан hajili 20 August 2018 в 22:15
поделиться

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

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

23
ответ дан Ryan 20 August 2018 в 22:15
поделиться

Помимо других (правильных) ответов, необходимо указать, что:

  • с NOT DEFERRABLE каждая строка проверяется со временем вставки / обновления
  • с DEFERRABLE ( в настоящее время IMMEDIATE) все строки проверяются в конце вставки / обновления
  • с DEFERRABLE (в настоящее время DEFERRED) все строки проверяются в конце транзакции

So неверно сказать, что ограничение DEFERRABLE действует как NOT DEFERRABLE, когда оно установлено в IMMEDIATE.


Давайте рассмотрим эту разницу:

CREATE TABLE example(
    row integer NOT NULL,
    col integer NOT NULL,
    UNIQUE (row, col) DEFERRABLE INITIALLY IMMEDIATE
);

INSERT INTO example (row, col) VALUES (1,1),(2,2),(3,3);

UPDATE example SET row = row + 1, col = col + 1;

SELECT * FROM example;

Это правильно выходы:

Но если мы удалим инструкцию DEFERRABLE INITIALLY IMMEDIATE,

ОШИБКА: дублирующее значение ключа нарушает уникальные constraint "example_row_col_key" DETAIL: Key ("row", col) = (2, 2) уже существует. ********** Ошибка **********

ОШИБКА: дублирующее значение ключа нарушает уникальное ограничение "example_row_col_key" Состояние SQL: 23505 Detail: Key ("row" , col) = (2, 2).


ADDENDUM (12 октября 2017 г.)

Это поведение действительно документально здесь , раздел «Совместимость»:

Кроме того, PostgreSQL проверяет неотменяемые ограничения уникальности сразу, а не в конце инструкции, как предполагает стандарт.

16
ответ дан Teejay 20 August 2018 в 22:15
поделиться
  • 1
    Интересно. Мне кажется, что в принципе нет оснований предпочитать «НЕ ДЕФЕРЕНТИРОВАННЫЙ». поведения к "IMMEDIATE" и что Postgres имеет смысл быть более прощающим и делать НЕ ДЕФЕРЕНЦИАЛЬНЫМ, как «IMMEDIATE». Порядок, в котором строки обновлены в инструкции UPDATE, даже не документирован или не определен, насколько я знаю, так ли поведение этой проверки ограничения среднего оператора хотя бы частично не определено? Я не понимаю, почему кто-то хотел бы этого поведения, но, возможно, для этого есть разумный случай использования, которого мне не хватает воображения. – Mark Amery 11 October 2017 в 15:23
  • 2
    Да, в основном единственная причина, чтобы предпочесть NOT DEFERRABLE - скорость ( см. Здесь , раздел Неотложные ограничения единственности , "Имейте в виду, что это может быть значительно медленнее, чем немедленная проверка уникальности "). – Teejay 12 October 2017 в 10:58
  • 3
    Кроме того, ограничение DEFERRABLE не может ссылаться на внешние ключи в других таблицах ( см. Здесь , раздел Параметры , ". Столбцы, на которые есть ссылки, должны быть столбцами неотделяемое единственное ограничение или ограничение первичного ключа в ссылочной таблице "). – Teejay 12 October 2017 в 10:59
  • 4
    Итак, как правило, если это не имеет большого значения для бизнес-логики при проверке ограничения, то следует ли мне по умолчанию использовать NOT DEFERRABLE просто потому, что он работает лучше? – dtgq 12 October 2017 в 11:03
  • 5
    В нашем ORM мы теперь используем следующие правила: 1) если ограничение является PK, мы используем NOT DEFERRABLE 2), если хотя бы один FK ссылается на ограничение, мы также используем NOT DEFERRABLE 3), в других случаях мы используйте DEFERRABLE INITIALLY IMMEDIATE. Это может немного снизить производительность этих ограничений, но обеспечивает максимальную совместимость с другими СУБД, которые мы используем (Oracle, SqlServer). PK и FK не являются проблемой, потому что мы никогда не обновляем их ценности (что, я думаю, является хорошей привычкой к программированию для БД). – Teejay 12 October 2017 в 11:12
Другие вопросы по тегам:

Похожие вопросы: