MySQLは外部キー制約を作成できません


84

mysqlデータベースの既存のテーブルへの外部キーの作成に問題があります。

私はテーブルを持っていますexp

+-------------+------------------+------+-----+---------+-------+
| Field       | Type             | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+-------+
| EID         | varchar(45)      | NO   | PRI | NULL    |       |
| Comment     | text             | YES  |     | NULL    |       |
| Initials    | varchar(255)     | NO   |     | NULL    |       |
| ExpDate     | date             | NO   |     | NULL    |       |
| InsertDate  | date             | NO   |     | NULL    |       |
| inserted_by | int(11) unsigned | YES  | MUL | NULL    |       |
+-------------+------------------+------+-----+---------+-------+

そしてsample_df、以下を使用して、これを参照するという新しいテーブルを作成したくありません。

CREATE TABLE sample_df (
df_id mediumint(5) unsigned AUTO_INCREMENT primary key,
sample_type mediumint(5) unsigned NOT NULL,
df_10 BOOLEAN NOT NULL,
df_100 BOOLEAN NOT NULL,
df_1000 BOOLEAN NOT NULL,
df_above_1000 BOOLEAN NOT NULL,
target INT(11) unsigned NOT NULL,
assay MEDIUMINT(5) unsigned zerofill NOT NULL,
insert_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
inserted_by INT(11) unsigned NOT NULL,
initials varchar(255),
experiment VARCHAR(45),
CONSTRAINT FOREIGN KEY (inserted_by) REFERENCES user (iduser),
CONSTRAINT FOREIGN KEY (target) REFERENCES protein (PID),
CONSTRAINT FOREIGN KEY (sample_type) REFERENCES sample_type (ID),
CONSTRAINT FOREIGN KEY (assay) REFERENCES assays (AID),
CONSTRAINT FOREIGN KEY (experiment) REFERENCES exp (EID)
);

しかし、エラーが発生します:

ERROR 1215 (HY000): Cannot add foreign key constraint

私がしたいくつかのより多くの情報を得るために:

SHOW ENGINE INNODB STATUS\G

私が得たもの:

FOREIGN KEY (experiment) REFERENCES exp (EID)
):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.

どちらもvarchar(45)であるため、私には列タイプが一致しているように見えます(experiment列をnull以外に設定しようとしましたが、修正されませんでした)したがって、問題はそれであるに違いないと思いCannot find an index in the referenced table where the referenced columns appear as the first columnsます。しかし、これが何を意味するのか、またはそれをチェック/修正する方法はよくわかりません。誰か提案がありますか?そして、どういう意味first columnsですか?


11
回答や質問のどこにも、文字セットの違いが原因でこのエラーが発生する可能性があることを見つけることができませんでした。ありがとう..乾杯!!!
proprius 2016

3
また、列の照合順序を再確認してください。テーブルはutf8mb4である可能性がありますが、列は異なる照合順序を持つことができます!
ワトソン

私の場合は@Watson文字セットですが、あなたは私に考えさせるための私の賛成を得ます。
user2910265

回答:


153

考えられる原因の組み合わせにこれを投げ込むだけで、参照テーブルの列が同じ「タイプ」を持っていたが、同じ署名を持っていなかったときにこれに遭遇しました。

私の場合、参照されるテーブル列はTINYINT UNSIGNEDであり、参照するテーブル列はTINYINTSIGNEDでした。両方の列を揃えることで問題が解決しました。


1
@ austen-hoogenによって提案された解決策は私の問題を解決しました。しかし、評判スコアが低いため、彼の解決策に投票したりコメントしたりすることはできません。私の場合、主キーは整数、自動インクリメント、符号なしでした。ただし、外部キー(参照テーブルの列)は符号付きタイプでした。署名なしに変更し、リレーションを正常に作成できるようにしました。
Bal Singh

はい、同じ問題が発生しました。私の主キーはBIGINT(20)であり、別のテーブルで参照されているキーはINT(10)unsignedでした。それらがすべて一致することを確認する必要があります。すなわち。BIGINT(20)、および参照される表にもBIGINT(20)が必要です
Manjunath Reddy 2018

ありがとうございました!この解決策は私の問題も解決しました!int2番目のテーブルに外部キーとbigintを設定する予定のテーブルにいました。
aleksej_Shherbak

36

このエラーは、参照テーブルと現在のテーブルの文字セットが同じでない場合にも発生する可能性があります。


3
参照表のように文字セットを設定したlatin後、3時間後に再び呼吸を開始しました。
Abhishek Kamal

24

http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.htmlによると

MySQLでは、外部キーのチェックを高速化し、テーブルスキャンを必要としないように、外部キーと参照キーのインデックスが必要です。参照テーブルには、外部キー列が同じ順序で最初の列としてリストされているインデックスが必要です。

InnoDBは、外部キーが任意のインデックス列または列のグループを参照することを許可します。ただし、参照されるテーブルには、参照される列が同じ順序で最初の列としてリストされるインデックスが必要です。

したがって、参照されるテーブルのインデックスが存在し、それが複数の列で構成されていて、目的の列が最初でない場合、エラーが発生します。

エラーの原因は、次のルールの違反によるものでした。

外部キーと参照キーの対応する列は、同様のデータ型である必要があります。整数型のサイズと符号は同じでなければなりません。文字列タイプの長さは同じである必要はありません。非バイナリ(文字)文字列列の場合、文字セットと照合順序は同じである必要があります。


19

@Antonで述べたように、これはデータ型が異なることが原因である可能性があります。私の場合、主キーBIGINT(20)があり、INT(10)で8つのキーを設定しようとしました。


2
ありがとうございました!INT(11)とINT(11)を使用していたが、一方が主キーであり、もう一方が署名されている間に署名されていないという同様の問題!
マイケルスコットカスバート2017

@MichaelScottCuthbert Same
Germa Vinsmoke


6

私の問題は、参照されているテーブルと作成されるテーブルの間の照合の問題であったため、参照しているキーの照合タイプを明示的に設定する必要がありました。

  • まず、参照されるテーブルでクエリを実行して、照合タイプを取得しました
show table STATUS like '<table_name_here>';
  • 次に、照合タイプをコピーし、作成クエリでemployee_idの照合タイプを明示的に指定しました。私の場合はutf8_general_ciでした
CREATE TABLE dbo.sample_db
(
  id INT PRIMARY KEY AUTO_INCREMENT,
  event_id INT SIGNED NOT NULL,
  employee_id varchar(45) COLLATE utf8_general_ci NOT NULL,
  event_date_time DATETIME,
  CONSTRAINT sample_db_event_event_id_fk FOREIGN KEY (event_id) REFERENCES event (event_id),
  CONSTRAINT sample_db_employee_employee_id_fk FOREIGN KEY (employee_id) REFERENCES employee (employee_id)
);

2

精密主キー順序も、間に余分な列がないように一致する必要があります。

列の順序が主キーの設定でした実際に一致が、問題は、参照テーブルの外部キーの一部ではない余分な列が主キーに含まれていたことでした。

例)表2、列(a、b、c)->表1、列(a、b、d、c)-これは失敗します

主キー列を同じように並べ替えるだけでなく、中央に余分な列がないように並べ替える必要がありました。

例)表2、列(a、b、c)->表1、列(a、b、c、d)-この成功


2

場合によっては、参照フィールドを主キーとして定義するだけでなく、一意にする必要がありました。

しかし、それを一意として定義しなくても、すべての場合に問題が発生するわけではないことがわかりました。しかし、私はシナリオを理解することができませんでした。おそらくnull許容の定義と関係があります。


FKの紹介やマニュアルを読んだことがありますか?FKはUNIQUEを参照します。PKはUNIQUENOTNULLを意味します。
philipxy

2

私の場合、IDに整数を使用して作成され、参照テーブルはデフォルトでbigintを使用して外部キーを作成していました。

移行が失敗したため、これは私のRailsアプリに大きな悪夢を引き起こしましたが、フィールドは実際にはDBで作成されたため、DBには表示されましたが、Railsアプリのスキーマには表示されませんでした。


1

同じ制約で同じ列を複数回参照するとCannot find an index in the referenced table、このエラーも発生しますが、大きなテーブルで見つけるのは難しい場合があります。制約を分割すると、期待どおりに機能します。


1

私にもこのエラーがありました。答えはどれも私には関係ありませんでした。私の場合、GUIは、プライマリ一意識別子が「未割り当て」のテーブルを自動的に作成します。外部キーを作成しようとすると失敗し、まったく同じエラーが発生します。主キーを割り当てる必要があります。

SQL自体をそのように記述した場合、id int unique auto_incrementこの問題は発生しませんが、何らかの理由で私のGUIが代わりにこれを実行しid int unassigned unique auto_incrementます。

これが将来の誰かに役立つことを願っています。


1

私にとっては、DBの文字セットと照合だけでした。utf8_unicode_ciに変更して動作します


1
現在の文字セット/照合順序を確認する方法の例を教えてください。
thelr
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.