MySQL foreign_key_checks influisce sull'intero database?


201

Quando eseguo questo comando in MySQL:

SET FOREIGN_KEY_CHECKS=0;

Interessa l'intero motore o è solo la mia transazione corrente?


15
test: accedi a mysql: mostra variabili come '% FOREIGN%'; SET FOREIGN_KEY_CHECKS = 0; Dopodiché accedi a mysql usando una console diversa. Vedo che mostrare variabili come '% FOREIGN%' è ON anziché OFF.
Sean Nguyen,

Risposte:



98

In realtà, ci sono due foreign_key_checksvariabili: una variabile globale e una variabile locale (per sessione). Al momento della connessione, la variabile di sessione viene inizializzata sul valore della variabile globale.
Il comando SET foreign_key_checksmodifica la variabile di sessione.
Per modificare la variabile globale, utilizzare SET GLOBAL foreign_key_checkso SET @@global.foreign_key_checks.

Consultare le seguenti sezioni del manuale:
http://dev.mysql.com/doc/refman/5.7/en/using-system-variables.html
http://dev.mysql.com/doc/refman/5.7/en/server -Sistema-variables.html


1
L'impostazione di Foreign_key_checks su ogni richiesta è costosa? Ho uno script per aggiornare il DB e non vorrei che nessun altro potesse sovrascrivere i controlli delle chiavi esterne per impostazione predefinita durante quell'aggiornamento. Quindi farei milioni di domande e mi chiedevo se un SET sarebbe stato significativo o no?
Aki,

@Aki Se stai aggiornando il DB, direi che è meglio bloccare l'accesso per tutti gli altri. Almeno per la scrittura. Altrimenti, puoi aspettarti tutti i tipi di problemi di accesso simultaneo.
tishma,

1
Ottima risposta e distinzione. È importante rendersi conto delle conseguenze di come funziona. Significa che non è possibile impostare GLOBAL foreign_key_checkse in quella stessa sessione aspettarsi che ignori i vincoli delle chiavi esterne. Devi impostare la variabile non globale.
Tyler Collier,

12

Come spiegato da Ron, ci sono due variabili, locale e globale. La variabile locale viene sempre utilizzata ed è uguale a globale al momento della connessione.

SET FOREIGN_KEY_CHECKS=0;
SET GLOBAL FOREIGN_KEY_CHECKS=0;

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

Quando si imposta la variabile GLOBAL, quella locale non viene modificata per nessuna connessione esistente. È necessario ricollegare o impostare anche la variabile locale.

Forse non intuitivo, MYSQL non impone le chiavi esterne quando vengono riattivati ​​FOREIGN_KEY_CHECKS. Ciò consente di creare un database incoerente anche se le chiavi esterne e i controlli sono attivi.

Se vuoi che le tue chiavi esterne siano completamente coerenti, devi aggiungere le chiavi mentre il controllo è attivo.


1
Puoi approfondire ... "Se vuoi che le tue chiavi esterne siano completamente coerenti, devi aggiungere le chiavi mentre il controllo è attivo."
user2782001

4
Supponiamo che tu abbia una tabella con ID di riferimento, ma mancano alcuni record di riferimento. Se aggiungi la chiave esterna (FK) mentre FOREIGN_KEY_CHECKS sono ON, Mysql genererà un errore e rifiuterà di aggiungere l'FK, a causa del riferimento rotto. Quando aggiungi la chiave esterna mentre FOREIGN_KEY_CHECKS sono OFF, mysql continua senza errori. Anche quando si abilitano i controlli in seguito, non si verificheranno errori. Ora hai una tabella con dati incoerenti, anche se c'è un FK. Pertanto, l'esistenza di un FK non è garanzia della coerenza del database, a meno che non sia stato aggiunto mentre i controlli FK erano attivi.
Bouke Versteegh

10
# will get you the current local (session based) state.
SHOW Variables WHERE Variable_name='foreign_key_checks';

Se non hai impostato GLOBAL, solo la tua sessione è stata interessata.


1

Ho avuto lo stesso errore quando ho provato a migrare il database Drupal su un nuovo server Apache locale (sto usando XAMPP su computer Windows). In realtà non conosco il significato di questo errore, ma dopo aver provato i passaggi seguenti, ho importato il database senza errori. Spero che questo possa aiutare:

Modifica php.ini in C: \ xampp \ php \ php.ini

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

Modifica di my.ini in C: \ xampp \ mysql \ bin \ my.ini

max_allowed_packet = 1024M

-2

In caso di utilizzo del browser di query Mysql, SET FOREIGN_KEY_CHECKS=0;non ha alcun impatto nella versione 1.1.20. Tuttavia, funziona perfettamente con il browser di query Mysql 1.2.17

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.