Dies scheint ein häufiger Fehler zu sein, aber für mein Leben kann ich das nicht verstehen.
Ich habe eine Reihe von InnoDB-Benutzertabellen in MySQL, die über einen Fremdschlüssel miteinander verbunden sind. die übergeordnete user
-Tabelle und eine Reihe von untergeordneten Tabellen, in denen E-Mail-Adressen, Aktionen usw. gespeichert werden. Diese sind alle durch einen Fremdschlüssel user
an die übergeordnete uid
-Tabelle gebunden, wobei alle übergeordneten und untergeordneten Schlüssel int(10)
sind.
Alle untergeordneten Tabellen haben einen uid
-Wert mit einer Fremdschlüsseleinschränkung, die auf user.uid
zeigt und auf ON DELETE CASCADE
und ON UPDATE CASCADE
eingestellt ist.
Wenn ich einen Benutzer aus user
lösche, werden alle untergeordneten beschränkten Einträge entfernt. Wenn ich jedoch versuche, einen user.uid
-Wert zu aktualisieren, führt dies zu dem folgenden Fehler, anstatt die uid
-Änderung in die untergeordneten Tabellen zu verschieben:
#1452 - Cannot add or update a child row: a foreign key constraint fails (`accounts`.`user_email`, CONSTRAINT `user_email_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE)
Ich habe das Gefühl, dass mir hier offensichtlich etwas fehlt. Das Entfernen der Schlüsseleinschränkung mit user_email
und der Versuch, den Wert in user
zu aktualisieren, führt zu demselben Fehler, jedoch für die nächste alphabetische user
-untergeordnete Tabelle. Ich glaube nicht, dass es sich um einen tabellenspezifischen Fehler handelt.
BEARBEITEN:
Hinzufügen in den Ergebnissen von SHOW ENGINE INNODB STATUS
:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
121018 22:35:41 Transaction:
TRANSACTION 0 5564387, ACTIVE 0 sec, process no 1619, OS thread id 2957499248 updating or deleting, thread declared inside InnoDB 499
mysql tables in use 1, locked 1
17 lock struct(s), heap size 2496, 9 row lock(s), undo log entries 2
MySQL thread id 3435659, query id 24068634 localhost root Updating
UPDATE `accounts`.`user` SET `uid` = '1' WHERE `user`.`uid` = 306
Foreign key constraint fails for table `accounts`.`user_email`:
,
CONSTRAINT `user_email_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE
Trying to add in child table, in index `uid` Tuple:
DATA Tuple: 2 fields;
...
A bunch of hex code
But in parent table `accounts`.`user`, in index `PRIMARY`,
the closest match we can find is record:
...
A bunch of hex code
Vor kurzem habe ich unsere MySQL-Datenbank in MySQL Workbench aufgerufen, und als ich die Tabellenbeziehungen für die obigen Tabellen sah, bemerkte ich "Duplikate" und/oder falsche Beziehungen, die ich vorher irgendwie vermisst hatte wird in PHPMyAdmin FWIW nicht angezeigt). Durch das Entfernen dieser zusätzlichen Beziehungen wurde das Problem sofort gelöst.
Ich löste meine ' Fremdschlüsselbedingung-Fehler ' - Probleme, indem ich den folgenden Code am Anfang des SQL-Codes anfügte (dies war das Importieren von Werten in eine Tabelle)
SET @[email protected]@CHARACTER_SET_CLIENT;
SET @[email protected]@CHARACTER_SET_RESULTS;
SET @[email protected]@COLLATION_CONNECTION;
SET NAMES utf8;
SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @[email protected]@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
SET @[email protected]@SQL_NOTES, SQL_NOTES=0;
Dann fügen Sie diesen Code am Ende der Datei ein
SET [email protected]_SQL_MODE;
SET [email protected]_FOREIGN_KEY_CHECKS;
SET [email protected]_UNIQUE_CHECKS;
SET [email protected]_CHARACTER_SET_CLIENT;
SET [email protected]_CHARACTER_SET_RESULTS;
SET [email protected]_COLLATION_CONNECTION;
SET [email protected]_SQL_NOTES;
Da Sie keine Tabellendefinitionen angegeben haben, ist es schwer zu erraten. Es sieht jedoch so aus, als würden Sie versuchen, den Fremdschlüssel in der untergeordneten Tabelle zu ändern. AFAIK, das ist illegal, Sie können es vom übergeordneten Element aus ändern, nicht jedoch von der untergeordneten Tabelle.
Betrachten Sie dieses Beispiel:
CREATE TABLE parent (
parent_id INT NOT NULL,
parent_data int,
PRIMARY KEY (parent_id)
) ENGINE=INNODB;
CREATE TABLE child1 (
child1_id INT,
child1_data INT,
fk_parent_id INT,
INDEX par_ind1 (fk_parent_id),
FOREIGN KEY (fk_parent_id)
REFERENCES parent(parent_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=INNODB;
CREATE TABLE child2 (
child2_id INT,
child2_data INT,
fk_parent_id INT,
INDEX par_ind2 (fk_parent_id),
FOREIGN KEY (fk_parent_id)
REFERENCES parent(parent_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=INNODB;
INSERT INTO parent
(parent_id, parent_data)
VALUES
(1, 11),
(2, 12);
INSERT INTO child1
(child1_id, child1_data, fk_parent_id)
VALUES
(101, 1001, 1),
(102, 1002, 1),
(103, 1003, 1),
(104, 1004, 2),
(105, 1005, 2);
INSERT INTO child2
(child2_id, child2_data, fk_parent_id)
VALUES
(106, 1006, 1),
(107, 1007, 1),
(108, 1008, 1),
(109, 1009, 2),
(110, 1010, 2);
Dann ist das erlaubt:
UPDATE parent
SET parent_id = 3 WHERE parent_id = 2;
SELECT * FROM parent;
SELECT * FROM child1;
SELECT * FROM child2;
Dies ist jedoch nicht der Fall, da die übergeordnete Datei fk aus der untergeordneten Tabelle geändert wird:
UPDATE child1
SET fk_parent_id = 4 WHERE fk_parent_id = 1;
Es wird ein Fehler angezeigt, der Ihrem Fehler sehr ähnlich ist:
Cannot add or update a child row: a foreign key constraint fails (`db_2_b43a7`.`child1`, CONSTRAINT `child1_ibfk_1` FOREIGN KEY (`fk_parent_id`) REFERENCES `parent` (`parent_id`) ON DELETE CASCADE ON UPDATE CASCADE):
Ich war mit dem gleichen Problem konfrontiert, als ich auf dem Tisch fremde Einschränkungen aufstellte. Die einfachste Möglichkeit, dieses Problem zu lösen, besteht darin, zunächst eine Sicherung der übergeordneten und untergeordneten Tabelle zu erstellen, dann die untergeordnete Tabelle abzuschneiden und erneut eine Beziehung herzustellen. Ich hoffe, das löst das Problem.
Ein solcher Fehler bei der Aktualisierung kann durch den Unterschied in Zeichensatz und Sortierfolge verursacht werden. Stellen Sie daher sicher, dass sie für beide Tabellen gleich sind.
Obwohl dies ziemlich alt ist, möchte ich nur sagen, dass in @ Sidupacs Antwort der FOREIGN_KEY_CHECKS=0
Nützlich ist.
Diese Antwort ist keine Option, wenn Sie etwas verwenden, das das Datenbankschema für Sie verwaltet (in meinem Fall JPA), aber das Problem kann sein, dass Ihre Tabelle "verwaiste" Einträge enthält (die auf einen Fremdschlüssel verweisen, der möglicherweise nicht vorhanden ist).
Dies kann häufig vorkommen, wenn Sie eine MySQL-Tabelle von MyISAM nach InnoDB konvertieren, da die referenzielle Integrität bei der ersteren nicht wirklich eine Rolle spielt.