O MySQL Foreign_key_checks afeta todo o banco de dados?

201

Quando executo este comando no MySQL:

SET FOREIGN_KEY_CHECKS=0;

Isso afeta todo o mecanismo ou é apenas minha transação atual?

Sean Nguyen
fonte
15
teste: efetue login no mysql: mostre variáveis ​​como '% FOREIGN%'; SET FOREIGN_KEY_CHECKS = 0; Depois disso, entre no mysql usando um console diferente. Eu posso ver que variáveis ​​de exibição como '% FOREIGN%' estão ativadas em vez de desativadas.
Sean Nguyen

Respostas:

98

Na verdade, existem duas foreign_key_checksvariáveis: uma variável global e uma variável local (por sessão). Após a conexão, a variável de sessão é inicializada com o valor da variável global.
O comando SET foreign_key_checksmodifica a variável da sessão.
Para modificar a variável global, use SET GLOBAL foreign_key_checksou SET @@global.foreign_key_checks.

Consulte as seguintes seções do manual:
http://dev.mysql.com/doc/refman/5.7/en/using-system-variables.html
http://dev.mysql.com/doc/refman/5.7/en/server -system-variable.html

Ron Inbar
fonte
1
A configuração de estrang_chave_chave em cada solicitação é cara? Eu tenho um script para atualizar o banco de dados e não gostaria que mais ninguém pudesse substituir as verificações de chave estrangeira por padrão durante essa atualização. Então, eu faria milhões de consultas e me perguntava se um SET seria significativo ou não?
Aki
@Aki Se você estiver atualizando o banco de dados, diria que é melhor bloquear o acesso de todos os outros. Pelo menos para escrever. Caso contrário, você pode esperar todos os tipos de problemas de acesso simultâneo.
tishma 13/05
1
Ótima resposta e distinção. É importante perceber as consequências de como isso funciona. Isso significa que você não pode definir o GLOBAL foreign_key_checkse, na mesma sessão, espera que ele ignore as restrições de chaves estrangeiras. Você precisa definir a variável não global.
Tyler Collier
12

Como explicado por Ron, existem duas variáveis, local e global. A variável local é sempre usada e é a mesma que global na conexão.

SET FOREIGN_KEY_CHECKS=0;
SET GLOBAL FOREIGN_KEY_CHECKS=0;

SHOW Variables WHERE Variable_name='foreign_key_checks'; # always shows local variable

Ao definir a variável GLOBAL, a local não é alterada para nenhuma conexão existente. Você precisa reconectar ou definir a variável local também.

Talvez não seja intuitivo, o MYSQL não aplica chaves estrangeiras quando FOREIGN_KEY_CHECKS é reativado. Isso possibilita a criação de um banco de dados inconsistente, mesmo com chaves estrangeiras e verificações ativadas.

Se você deseja que suas chaves estrangeiras sejam completamente consistentes, adicione-as enquanto a verificação estiver ativada.

Bouke Versteegh
fonte
1
Você pode elaborar sobre .... "Se você deseja que suas chaves estrangeiras sejam completamente consistentes, é necessário adicioná-las enquanto a verificação estiver ativada."
user2782001
4
Digamos que você tenha uma tabela com IDs de referência, mas alguns registros referenciados estão ausentes. Se você adicionar a chave estrangeira (FK) enquanto FOREIGN_KEY_CHECKS estiver LIGADO, o Mysql gerará um erro e se recusará a adicionar o FK, devido à referência quebrada. Quando você adiciona a chave estrangeira enquanto FOREIGN_KEY_CHECKS está DESLIGADO, o mysql continua sem erros. Mesmo quando você ativar as verificações posteriormente, não haverá erro. Agora você tem uma tabela com dados inconsistentes, mesmo que exista um FK. Como tal, a existência de um FK não garante a consistência do banco de dados, a menos que tenha sido adicionado enquanto as verificações do FK estavam ativadas.
Bouke Versteegh
10
# will get you the current local (session based) state.
SHOW Variables WHERE Variable_name='foreign_key_checks';

Se você não definiu GLOBAL, apenas sua sessão foi afetada.

Mike Karras
fonte
1

Eu tive o mesmo erro quando tentei migrar o banco de dados Drupal para um novo servidor apache local (estou usando o XAMPP na máquina Windows). Na verdade, não sei o significado desse erro, mas depois de tentar as etapas abaixo, importei o banco de dados sem erros. Espero que isso possa ajudar:

Alterando o php.ini em C: \ xampp \ php \ php.ini

max_execution_time = 600
max_input_time = 600
memory_limit = 1024M
post_max_size = 1024M

Alterando my.ini em C: \ xampp \ mysql \ bin \ my.ini

max_allowed_packet = 1024M
Saeed cr7
fonte
-2

No caso de usar o navegador de consulta Mysql, SET FOREIGN_KEY_CHECKS=0;não tem nenhum impacto na versão 1.1.20. No entanto, ele funciona bem no navegador de consultas Mysql 1.2.17

user2682955
fonte