Eu li sobre a palavra-chave SQL DEFERRABLE
em Database Systems - The Complete Book .
O último [NOT DEFERRABLE] é o padrão e significa que toda vez que uma instrução de modificação do banco de dados é executada, a restrição é verificada imediatamente depois, se a modificação puder violar a restrição de chave estrangeira.
No entanto, se declararmos uma restrição como DEFERRABLE , temos a opção de esperar até que uma transação seja concluída antes de verificar a restrição.
Seguimos a palavra-chave DEFERRABLE por INITIALLY DEFERRED ou INITIALLY IMMEDIATE . No primeiro caso, a verificação será adiada para pouco antes de cada confirmação de transação. Neste último caso, a verificação será feita imediatamente após cada declaração.
Como é NOT DEFERRABLE
diferente de DEFERRABLE INITIALLY IMMEDIATE
? Em ambos os casos, ao que parece, todas as restrições são verificadas após cada declaração individual.
DEFERRABLE
declara a intenção do designer de que adiar a restrição é uma ação válida ou necessária. Este não é o caso para a grande maioria das restrições de banco de dados e rotulagem de todos, poisDEFERRABLE
perderia essa distinção útil.NOT DEFERRABLE
geralmente é o mais rápido.Além das outras respostas (corretas), quando se fala em PostgreSQL , deve-se afirmar que:
com NOT DEFERRABLE, cada linha é verificada no momento da inserção / atualização
com DEFERRABLE (atualmente IMMEDIATE ) todas as linhas são verificadas no final da inserção / atualização
com DEFERRABLE (atualmente DEFERRED ) todas as linhas são verificadas no final da transação
Portanto , não é correto dizer que uma restrição DEFERRABLE age como uma NOT DEFERRABLE quando definida como IMMEDIATE.
Vamos elaborar essa diferença:
Isso resulta corretamente:
Mas se removermos a instrução DEFERRABLE INITIALLY IMMEDIATE,
ADENDO (12 de outubro de 2017)
Este comportamento está realmente documentado aqui , seção "Compatibilidade":
fonte
NOT DEFERRABLE
é a velocidade ( veja aqui , a seção Restrições de exclusividade não adiadas , "Esteja ciente de que isso pode ser significativamente mais lento do que a verificação de exclusividade imediata" ).DEFERRABLE
restrição não pode ser referenciada como chaves estrangeiras em outras tabelas ( veja aqui , seção Parâmetros , "As colunas referenciadas devem ser as colunas de uma restrição de chave primária ou única não diferível na tabela referenciada" ).NOT DEFERRABLE
simplesmente porque tem um desempenho melhor?NOT DEFERRABLE
2) se pelo menos um FK referenciar a restrição, usamosNOT DEFERRABLE
também 3) nos outros casos, usamosDEFERRABLE INITIALLY IMMEDIATE
. Isso pode diminuir ligeiramente o desempenho dessas restrições, mas garante a compatibilidade máxima com outros DBMS que usamos (Oracle, SqlServer). PK e FK não são um problema porque nunca atualizamos seus valores (o que eu acho um bom hábito de programação para bancos de dados).Além do óbvio de ser capaz de adiar, a diferença é realmente o desempenho. Se não houvesse uma penalidade de desempenho, não haveria necessidade de ter a opção de escolher diferível ou não - todas as restrições seriam simplesmente postergáveis.
A penalidade de desempenho tem a ver com otimizações que o banco de dados pode realizar dado o conhecimento de como os dados são restritos. Por exemplo, o índice criado para apoiar uma restrição exclusiva no Oracle não pode ser um índice exclusivo se a restrição for postergável, pois a permissão temporária de duplicatas deve ser permitida. No entanto, se a restrição não for postergável, o índice pode ser exclusivo.
fonte
Estou muito atrasado para a festa, mas gostaria de acrescentar que - em dezembro de 2018 - apenas dois bancos de dados que eu conheço (pode haver mais) oferecem algum nível de implementação desse recurso SQL padrão :
* 1 Embora o Oracle 12c aceite o
NOT DEFERRABLE
estado de restrição , ele realmente o ignora e o faz funcionar comoDEFERRABLE INITIALLY IMMEDIATE
.Como você pode ver, o Oracle não implementa o primeiro tipo (
NOT DEFERRABLE
) e é por isso que os desenvolvedores que usam o Oracle (o OP, neste caso) podem ficar confusos e considerar os primeiros dois tipos equivalentes.Curiosamente, o Oracle e o PostgreSQL têm um tipo padrão diferente. Talvez tenha implicações de desempenho.
fonte
NOT DEFERRABLE - você não pode alterar a verificação de restrição, o oracle verifica após cada instrução (ou seja, diretamente após a instrução insert).
DEFERRABLE INITIALLY IMMEDIATE - o oracle verifica a restrição após cada instrução. MAS, você pode alterá-lo para após cada transação (ou seja, após o commit):
fonte