大規模な(スキーマとデータの両方の)MySQLデータベースに多くの外部キー制約が設定されています。最近、特定の名前のキーがすでに存在するため、一部のスクリプトがテーブルを作成できないことを発見しました。
私は問題を次のように追跡しました:
このようなものを実行すると:
CREATE TABLE `foo` (
`bar` int UNSIGNED NOT NULL,
CONSTRAINT `BAZ` FOREIGN KEY (`bar`) REFERENCES `qux` (`bar`) ON DELETE CASCADE ON UPDATE CASCADE
);
私は得ています:
エラー1022(23000):書き込みできません。テーブル 'foo'の重複キー
しかし、私が:
SELECT *
FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = "my_db"
AND CONSTRAINT_NAME LIKE "BAZ";
空のセットを取得しています。
また、スキーマをダンプして「BAZ」を検索しようとしましたが、何も見つかりませんでした。
"BAZ"以外の外部キーの名前を付けたテーブルを作成します。
それはどうでしょうか?
DBの他のいくつかのテーブルに外部キーのインデックスがある可能性があります。これは、同じ制約名を持ち、名前空間の衝突を引き起こしています。
すべてのInnoDBテーブルを使用している場合(2017年と同じように)、これを試して問題のテーブルを見つけます。
SELECT t.name
FROM information_schema.innodb_sys_indexes i
JOIN information_schema.innodb_sys_tables t
USING (table_id)
WHERE i.name = 'BAZ';
または、これもうまくいくかもしれません:
SELECT *
FROM information_schema.innodb_sys_foreign
WHERE id REGEXP 'BAZ$';
大文字と小文字を区別しないように設定されている可能性はありますか?
以下はレコードを返しますか?
SELECT CONSTRAINT_SCHEMA,
CONSTRAINT_NAME
FROM information_schema.REFERENTIAL_CONSTRAINTS
where lower(CONSTRAINT_SCHEMA) like "my_db"
and lower(CONSTRAINT_NAME) like "baz";
いくつかの参照: