243

私はちょっと奇妙な問題を抱えています。別のテーブルを参照する 1 つのテーブルに外部キーを追加しようとしていますが、何らかの理由で失敗しています。私の MySQL に関する知識が限られているため、疑わしい可能性があるのは、参照しようとしているテーブルを参照している別のテーブルに外部キーがあることだけです。

SHOW CREATE TABLE両方のテーブルでクエリを実行しましsourcecodes_tagsた。外部キーを持つテーブルでsourcecodesあり、参照されるテーブルです。

CREATE TABLE `sourcecodes` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `user_id` int(11) unsigned NOT NULL,
 `language_id` int(11) unsigned NOT NULL,
 `category_id` int(11) unsigned NOT NULL,
 `title` varchar(40) CHARACTER SET utf8 NOT NULL,
 `description` text CHARACTER SET utf8 NOT NULL,
 `views` int(11) unsigned NOT NULL,
 `downloads` int(11) unsigned NOT NULL,
 `time_posted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`),
 KEY `user_id` (`user_id`),
 KEY `language_id` (`language_id`),
 KEY `category_id` (`category_id`),
 CONSTRAINT `sourcecodes_ibfk_3` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `sourcecodes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `sourcecodes_ibfk_2` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

CREATE TABLE `sourcecodes_tags` (
 `sourcecode_id` int(11) unsigned NOT NULL,
 `tag_id` int(11) unsigned NOT NULL,
 KEY `sourcecode_id` (`sourcecode_id`),
 KEY `tag_id` (`tag_id`),
 CONSTRAINT `sourcecodes_tags_ibfk_1` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1

これは、エラーを生成するコードです。

ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE
4

21 に答える 21

229

テーブルに存在しなくなった値がsourcecodes_tagsテーブルに含まれている可能性が非常に高いです。まずそれらを取り除く必要があります。sourcecode_idsourcecodes

これらの ID を見つけることができるクエリを次に示します。

SELECT DISTINCT sourcecode_id FROM 
   sourcecodes_tags tags LEFT JOIN sourcecodes sc ON tags.sourcecode_id=sc.id 
WHERE sc.id IS NULL;
于 2009-08-10T07:38:52.130 に答える
105

私のMySQLデータベースにも同じ問題がありましたが、最終的に私にとってはうまくいく解決策を得ました.
私のテーブルでは、mysqlの観点からはすべて問題ありませんでした(両方のテーブルでInnoDBエンジンを使用し、各列のデータ型は外部キー制約に参加する同じ型である必要があります)。
私がした唯一のことは、外部キーチェックを無効にし、後で外部キー操作を実行した後に有効にすることでした。
私が取った手順:

SET foreign_key_checks = 0;
alter table tblUsedDestination add constraint f_operatorId foreign key(iOperatorId) references tblOperators (iOperatorId); Query
OK, 8 rows affected (0.23 sec) Records: 8  Duplicates: 0  Warnings: 0
SET foreign_key_checks = 1;
于 2012-02-04T07:29:54.733 に答える
56

制約が制約NOT INしている場所を見つけるために使用します。

SELECT column FROM table WHERE column NOT IN 
(SELECT intended_foreign_key FROM another_table)

したがって、より具体的には:

SELECT sourcecode_id FROM sourcecodes_tags WHERE sourcecode_id NOT IN 
(SELECT id FROM sourcecodes)

編集: INandNOT IN演算子は、演算子よりもはるかに高速であるJOINだけでなく、構築と繰り返しがはるかに簡単であることが知られています。

于 2011-05-31T20:16:01.843 に答える
23

テーブルを切り詰めてから、FK Constraint を追加してみてください

この解決策は少し扱いに​​くいと思いますが、100% うまくいきます。しかし、これが問題に対処するための理想的な解決策ではないことに同意しますが、役立つことを願っています.

于 2013-05-29T04:31:21.273 に答える
17

私にとって、この問題は少し異なり、確認と解決が非常に簡単でした。

テーブルの両方が InnoDB であることを確認する必要があります。テーブルの 1 つ、つまり参照テーブルが MyISAM の場合、制約は失敗します。

    SHOW TABLE STATUS WHERE Name =  't1';

    ALTER TABLE t1 ENGINE=InnoDB;
于 2013-03-29T18:32:54.550 に答える
16

これは、child.column の値がすでに 0 で、parent.id の値が 0 でない場合に、parent.id に外部キーを child.column に設定するときにも発生します。

各 child.column が NULL であるか、parent.id に存在する値を持っていることを確認する必要があります。

そして、nos が書いた声明を読んだ今、それは彼が検証していることです。

于 2011-10-21T20:42:54.003 に答える
14

今日も同じ問題がありました。私は4つのことをテストしました.それらのいくつかはすでにここで言及されています:

  1. 親列に存在しない子列に値がありますか (子列が null 許容の場合は NULL 以外に)

  2. 子列と親列のデータ型は同じですか?

  3. 参照している親列にインデックスはありますか? MySQL はパフォーマンス上の理由からこれを必要とするようです ( http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html )

  4. そして、これは私のためにそれを解決しました:両方のテーブルに同一の照合がありますか?

UTF-8 のテーブルと iso-something のテーブルがありました。それはうまくいきませんでした。iso-table を UTF-8 照合に変更した後、問題なく制約を追加できました。私の場合、phpMyAdmin は、外部キー制約を作成するためのドロップダウンで、iso エンコードの子テーブルを表示しませんでした。

于 2013-04-24T10:27:39.153 に答える
9

列行 0 に有効な外部キーではない無効な値があるようです。そのため、MySQL は外部キー制約を設定できません。

次の手順を実行できます。

  1. FK 制約を設定しようとした列を削除します。

  2. 再度追加して、デフォルト値を NULL に設定します。

  3. 外部キー制約をもう一度設定してみてください。

于 2015-08-13T05:38:13.620 に答える
5

同じ問題が発生しました。テーブルの行を確認したところ、外部キーを定義したいフィールドの値との互換性がないことがわかりました。これらの値を修正して再試行すると、問題は解決しました。

于 2012-12-23T00:56:55.930 に答える
4

テーブル内のすべてのデータを削除して、alter を再度実行します。できます。素晴らしいものではありませんが、多くの時間を節約できます。特に、アプリケーションはまだ開発段階にあり、顧客データはありません.

于 2012-01-09T09:49:27.603 に答える
2

私はこれとまったく同じ問題を3回ほど経験しました。いずれの場合も、私のレコードの 1 つ (または複数) が新しい外部キーに準拠していなかったことが原因でした。キー自体を追加する前に、既存のレコードを更新して、外部キーの構文制約に従うことをお勧めします。次の例では、通常、問題のあるレコードを特定する必要があります。

SELECT * FROM (tablename)
    WHERE (candidate key) <> (proposed foreign key value) 
        AND (candidate key) <> (next proposed foreign key value)

AND (candidate key) <> (next proposed foreign key value)外部キーの値ごとにクエリ内で繰り返します。

大量のレコードがある場合、これは困難な場合がありますが、テーブルが適度に小さい場合は、それほど長くはかからないはずです。私は SQL 構文にそれほど優れているわけではありませんが、これは常に問題を切り分けてきました。

于 2012-08-28T14:04:10.093 に答える
2

両方のテーブルのデータを空にして、コマンドを実行します。それが動作します。

于 2015-04-23T08:59:23.450 に答える
2

Laravel と eloquent を使用しているときにこのエラーが発生しました。外部キー リンクを作成しようとすると 1452 が発生します。問題は、リンクされたテーブルにデータが不足していたことです。

例については、こちらを参照してください: http://mstd.eu/index.php/2016/12/02/laravel-eloquent-integrity-constraint-violation-1452-foreign-key-constraint/

于 2016-12-02T11:42:25.863 に答える
0
UPDATE sourcecodes_tags
SET sourcecode_id = NULL
WHERE sourcecode_id NOT IN (
  SELECT id FROM sourcecodes);

これらの ID を取り除くのに役立つはずです。nullが許可されていない場合はsourcecode_id、それらの行を削除するか、欠落している値をsourcecodesテーブルに追加します。

于 2016-02-23T14:29:26.167 に答える