mysql外部キー制約が正しく形成されていないエラー


173

私は2つのテーブルを持って、table1列を持つ親テーブルであるIDtable2コラムでIDFromTable1私は上のFKを入れて(ない実際の名前)IDFromTable1IDtable1、私はエラーを取得しますForeign key constraint is incorrectly formed errortable1レコードが削除された場合、テーブル2のレコードを削除したいと思います。助けてくれてありがとう

ALTER TABLE `table2`  
   ADD CONSTRAINT `FK1` 
      FOREIGN KEY (`IDFromTable1`) REFERENCES `table1` (`ID`) 
      ON UPDATE CASCADE 
      ON DELETE CASCADE;

他に情報が必要な場合はお知らせください。mysqlは初めてです


4
テーブルにはどのエンジンを使用していますか?種類何table2.IDFromTable1とはtable1.ID
Romain、2011

5
また、両方のテーブルの文字セットが同じであることを確認してください。
Carsten

どちらのテーブルエンジンもinnoDBです。文字セットの場所がわからない、どちらも文字型です。IDはtable1の主キーです
user516883

2
table1とtable2のテーブル定義を入力してください。どのようにしてこのエラーが発生しましたか?ツールを使用して外部キーを作成しますか?MySQLのネイティブエラーではないようです。
Devart、2011

@ user516883-テーブル定義を取得するのに助けが必要ですか?HeidiSQLでは、[ 作成コード ]タブをクリックするだけです。
アルバロゴンザレス

回答:


422

HeidiSQLで同じ問題に遭遇しました。受け取るエラーは非常に不可解です。私の問題は、外部キー列と参照列が同じタイプまたは長さではないということでした。

外部キー列はSMALLINT(5) UNSIGNEDで、参照される列はでしたINT(10) UNSIGNED。両方をまったく同じタイプにすると、外部キーの作成は完全に機能しました。


58
または、参照された列が主キーではない可能性があります
nawfal

9
ちょっと似たような問題があります-参照されたテーブルはまだ存在していませんでした。おっと。
アマルゴビナス2014

5
私はJakeが行ったことを完全に経験しましたが、HeidiSQLで別のFK問題(異なるタイプ)に遭遇しました。varcharのFKは同じ照合である必要があります。それが将来誰かを助けることを願っています!
cbloss793 2015

10
私の場合、エンコーディングと照合順序が異なるためです。
カトリ

1
@nawfal-必ずしも主キーである必要はありませんが、インデックスが必要です。主キーは自動的にインデックス化されます。
板井

48

親テーブルがMyISAMエンジンを使用して作成されたときにも同じ問題が発生しました。それは私が修正した愚かな間違いです:

ALTER TABLE parent_table ENGINE=InnoDB;

本当にありがとう、これで頭がおかしくなりました。データベースがエンジンをテーブルに突然切り替える理由は何ですか?
ロバートフランクリン

28

列が(同じタイプの)同一primary_keyであることを確認し、参照列がでない場合は、同一であることを確認してくださいINDEXED


それも、(1でしたし、1、実際にはなかった)が、シンプルを追加した後、そこにはエラーがなかったが、外部キーが追加されていなかった、と私に起こったKEY referencing_column(referencing_column) 前に、両方の外部キーの定義これらは両方successfuly追加されました:)
jave.web

2
インデックスに登録されていないキーが私の問題でした。
Neil Masters

1
私にはこの問題があり、問題は二重列の主キーがあり、主キーの2列目を外部キーとして使用できないことでした。そのため、主キーの2列目に独自のインデックスを追加しただけで機能しました。
Firze

21

外部キーを定義するための構文は非常に寛容ですが、外部キーが「同じタイプ」でなければならないという事実は、データタイプや長さ、ビット署名だけでなく、照合にも当てはまります。

モデルで照合順序を混在させるわけではありませんが(そうするでしょうか?)、そうする場合は、プライマリキーと外部キーのフィールドがphpmyadminやHeidi SQLなどで使用する照合タイプと同じであることを確認してください。

これにより、4時間の試行錯誤が減り、コストがかかることを願っています。


1
ありがとう!私のオンラインホストはISAMエンジンを使用しており、ローカルの開発者はInnoDBを使用しています。ホストからローカルにテーブルをバックアップしたとき...ブーム。
ベン

MariaDBの最近のバージョンは、utf8_mb4をデフォルトの文字セットとして使用しているようです(サーバー構成で明示的に設定されていない場合)のでCOLLATE utf8mb4_unicode_ci、(開発マシンでの)(予期しない)問題でした。
JonnyJD 2017年

13

同じ問題がありましたが、解決しました。

「table1」の列「ID」に一意のインデックスがあることを確認してください!

そしてもちろん、これら2つのテーブルのタイプ「ID」と「IDFromTable1」の長さは同じでなければなりません。しかし、あなたはすでにこれについて知っています。


あなたは私の日を作りました。
kevenlolo

1
助けてくれてうれしい!;)
Renat Gatin 2018

詳細は不明ですが、列に個別の一意のインデックスを追加することで修正されるこのエラーのある複合キーがありました。
Halvor Holsten Strand

参照される列にはインデックスを付ける必要がありますが、一意である必要はありません(これは通常のケースです)。
Barmar

10

完成のために。

このエラーは、VARCHAR(..)を持つ外部キーがあり、参照されるテーブルの文字セットがそれを参照するテーブルと異なる場合にも当てはまります。

たとえば、Latin1テーブルのVARCHAR(50)は、UTF8テーブルのVARCHAR(50)とは異なります。


1
utf8_unicode_ciとutf8_general_ciでもエラーが発生している
leuchtdiode '29

10

mysqlエラーテキストはあまり役に立ちません。私の場合、列には「null以外」の制約があったため、「on delete set null」は許可されませんでした


7

すべて問題なければ->unsigned();、の最後に追加してくださいforegin key

機能しない場合は、両方のフィールドのデータ型を確認してください。それらは同じでなければなりません。


5

同じ問題がありました。両方の列がINT(11)NOT NULLでしたが、外部キーを作成できません。それを正常に実行するには、外部キーチェックを無効にする必要がありました。

SET FOREIGN_KEY_CHECKS=OFF;
ALTER TABLE ... ADD CONSTRAINT ...
SET FOREIGN_KEY_CHECKS=ON;

これが誰かを助けることを願っています。


4
実際はFOREIGN_KEY_CHECKS
Xmanoux

これはさらに合格するのに役立ちましたが、私の問題は列のプライマリインデックスが欠落していたことです
bumerang

4

このエラーの表示のもう1つの考えられる原因。テーブルを作成する順序が間違っていました。まだ作成されていないテーブルからキーを参照しようとしました。


4

(最後の再送信)フィールド名とデータ型は同じでも照合順序が同じでなくても、その問題が発生します。

例えば

    TBL名| データタイプ| 照合        

    ActivityID | INT |         latin1_general_ci     ActivityID | INT |         utf8_general_ci

に変えてみてください

    TBL名| データタイプ| 照合        

    ActivityID | INT |         latin1_general_ci     ActivityID | INT |         latin1_general_ci

....

これでうまくいきました。


3

テーブルエンジンを確認してください。両方のテーブルが同じエンジンである必要があります。


いい視点ね!私はMySQLのZen Cartデータベースを扱っています。そのデータベースのテーブルはすべてデフォルトでMyISAMエンジンにあります。InnoDBエンジンを使用してテーブルを追加し、外部キー制約をテーブルからコアのZen Cart制約に追加しようとしました。この不明瞭な「誤って形成された」エラーで失敗しました。あなたは、各テーブルのエンジン見ることができますSHOW TABLE STATUS LIKE 'table_name';
NEEK

2

同じ問題がありました。

問題は、参照列が主キーではないことです。

主キーにすると問題が解決します。


PKである必要はなく、UNIQUE NOT NULLでもかまいません。
philipxy

実際...私の場合は、通常のインデックスタイプに設定するだけです。
hendr1x 2018

2

他の回答は非常に役に立ちますが、私の経験も共有したかっただけです。

id他のテーブルで(データを使用して)外部キーとしてすでに参照されているテーブルを削除し、いくつかの追加の列を含むテーブルを再作成またはインポートしようとしたときに、問題に直面しました。

レクリエーションのクエリ(phpMyAdminで生成)は次のようになります。

CREATE TABLE `the_table` (
  `id` int(11) NOT NULL,            /* No PRIMARY KEY index */  
  `name` varchar(255) NOT NULL,
  `name_fa` varchar(255) NOT NULL,
  `name_pa` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

... /* SOME DATA DUMP OPERATION */

ALTER TABLE `the_table`
  ADD PRIMARY KEY (`id`), /* PRIMARY KEY INDEX */
  ADD UNIQUE KEY `uk_acu_donor_name` (`name`);

お気づきかもしれませんが、PRIMARY KEYインデックスは作成(およびデータの挿入)後に設定されたため、問題が発生していました。

解決

解決策は、外部キーとして参照されPRIMARY KEYidいたのテーブル定義クエリにインデックスを追加すると同時にALTER TABLE、インデックスが設定されている部分からインデックスを削除することでした。

CREATE TABLE `the_table` (
  `id` int(11) NOT NULL PRIMARY KEY,            /* <<== PRIMARY KEY INDEX ON CREATION */  
  `name` varchar(255) NOT NULL,
  `name_fa` varchar(255) NOT NULL,
  `name_pa` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

それは私のために働いた。私は自分のソフトウェアを再インストールする必要があると心配しました;)
Dewlance


1

以下を実行してみてください:

show create table Parent

// myISAMやinnoDBなど、両方のテーブルのタイプが同じかどうかを確認します
//このエラーメッセージで確認するその他の側面:外部として使用される列 
キーにはインデックスを付ける必要があり、同じタイプである必要があります 
(一方がsmallint(5)型で、もう一方がsmallint(6)型の場合、 
それは動作しません)、そしてそれらが整数の場合、それらは符号なしであるべきです。

//または文字セットを確認します
「character_set_database」などの変数を表示します。
「collat​​ion_database」などの変数を表示します。

//編集済み:このようなものを試してください
ALTER TABLEテーブル2
制約を追加fk_IdTable2
FOREIGN KEY(Table1_Id)
参照Table1(Table1_Id)
更新時のカスケード 
削除時のカスケード;

9
SHOW ENGINE INNODB STATUSを実行して、エラーの詳細を確認してください
Sudhir Bastakoti

@SudhirBastakoti-+1!それは私のためにそれをしました。詳細は参考になります。問題を迅速に修正することができました。
ポールカールトン

1

Symfony 2.8でも同じ問題が発生しました。

外部キーのint長などに同様の問題がなかったため、最初はわかりませんでした。

最後に、プロジェクトフォルダーで次の操作を行う必要がありました。(サーバーの再起動は役に立ちませんでした!)

app/console doctrine:cache:clear-metadata app/console doctrine:cache:clear-query app/console doctrine:cache:clear-result


1

ありがとうS Doerin:

「完了のためだけです。このエラーは、VARCHAR(..)を含む外部キーがあり、参照されるテーブルの文字セットがそれを参照するテーブルと異なる場合にも当てはまる可能性があります。たとえば、Latin1テーブルのVARCHAR(50)はUTF8テーブルのVARCHAR(50)とは異なります。」

テーブルの文字の種類を変更して、この問題を解決しました。作成にはlatin1があり、正しいのはutf8です。

次の行を追加します。デフォルトの文字セット= utf8;


1

Alter tableを使用して2つのテーブルの間に外部キーを追加する際に問題があり、外部キー関係を追加しようとしている各列にインデックスが付けられていることを確認するのに役立ちました。PHP myAdminでこれを行うには:テーブルに移動し、構造タブをクリックします。スクリーンショットに示すように、インデックスオプションをクリックして、目的の列にインデックスを付けます。

ここに画像の説明を入力してください

外部キーで参照しようとした両方の列にインデックスを付けたら、変更テーブルを正常に使用して外部キー関係を作成できました。以下のスクリーンショットのように、列にインデックスが付けられていることがわかります。

ここに画像の説明を入力してください

両方のテーブルでzip_codeがどのように表示されるかに注意してください。


1

「照合」を含め、すべてのプロパティが同じであることを確認する必要があります


1

私はHeidiSQLを使用しており、この問題を解決するために、すべての列が参照されるように、参照されるテーブルにインデックス作成する必要がありました

テーブルHeidisqlにインデックスを追加する


mysqlでも同じです。InnoDBには外部キーと参照キーのインデックスが必要なため、外部キーのチェックが高速になり、テーブルスキャンが不要になります。
hendr1x 2018

1

今、同じ問題に遭遇しました。私の場合、外部キーで参照しているテーブルが現在のテーブルの前に(コード内で)作成されていることを確認するだけで済みました。したがって、変数(x * 5)を参照している場合、システムはxが何であるかを知っている必要があります(xはコードの前の行で宣言する必要があります)。これで私の問題は解決しました。他の人の役に立つことを願っています。


MariaDB v10.3.18でも同じ問題が発生しました。以前にMySQLを使用しており、外部キーが存在しないテーブルを指していることを警告していました。
MarthyM

0

MariaDB 10.1でのLaravel 5.1移行スキーマビルダーでも同じ問題が発生しました。

問題はunignedunsigned(の代わりに入力したことでしたs、列を設定しているとき文字が欠落していた)。

入力ミスを修正した後、私のために修正されました。


0

mysqlとliquibaseで同じ問題が発生しました。これが問題です。他のテーブルの列を参照するテーブルが、データ型の場合またはデータ型のサイズの点で異なります。

Error appears in below scenario:
Scenario 1:
Table A has column id, type=bigint
Table B column referenced_id type varchar(this column gets the value from the id column of Table A.)
Liquibase changeset for table B:

    <changeset id="XXXXXXXXXXX-1" author="xyz">
            <column name="referenced_id" **type="varchar"**>
        </column>
            </changeset>
    <changeSet id="XXXXXXXXXXX-2" author="xyz">
                <addForeignKeyConstraint constraintName="FK_table_A"
                    referencedTableName="A" **baseColumnNames="referenced_id**"
                    referencedColumnNames="id" baseTableName="B" />
    </changeSet>

Table A changeSet:

    <changeSet id="YYYYYYYYYY" author="xyz">
     <column **name="id"** **type="bigint"** autoIncrement="${autoIncrement}">
                    <constraints primaryKey="true" nullable="false"/>
                </column>
    </changeSet>

Solution: 
correct the type of table B to bigint because the referenced table has type bigint.

Scenrario 2:
The type might be correct but the size might not.
e.g. :
Table B : referenced column type="varchar 50"
Table A : base column type ="varchar 255"

Solution change the size of referenced column to that of base table's column size.

0

テーブルの名前が適切なケースで指定されていることを確認します(データベースでテーブル名の大文字と小文字が区別される場合)。私の場合、私は変えなければなりませんでした

 CONSTRAINT `FK_PURCHASE_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`id`) ON UPDATE CASCADE ON DELETE CASCADE

 CONSTRAINT `FK_PURCHASE_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `CUSTOMER` (`id`) ON UPDATE CASCADE ON DELETE CASCADE

customer変更されてCUSTOMERいることに注意してください。


0

または、データベースを作成し、FKを使用してそれらをリンクするグラフィカルインターフェイスを持つDBDesigner4を使用することもできます。テーブルを右クリックし、「テーブルSQL作成のコピー」を選択してコードを作成します。

ここに画像の説明を入力してください


0

古い話題ですが、何か発見しました。MySQLワークベンチの構築中に、他のテーブルの関係も取得します。あなたが関係している柱を残してください。自動的に追加された他の列をクリアします。これは私にとってはうまくいきます。


0

私の場合は、参照された列にタイプミスがあったことです。

MariaDB [blog]> alter table t_user add FOREIGN KEY ( country_code ) REFERENCES t_country ( coutry_code );
ERROR 1005 (HY000): Can't create table `blog`.`t_user` (errno: 150 "Foreign key constraint is incorrectly formed")

エラーメッセージは非常に不可解であり、列のタイプ、照合順序、エンジンなどの検証など、すべてを試しました。

タイプミスに気づくのにしばらく時間がかかり、修正後はすべてうまくいきました。

MariaDB [blog]> alter table t_user add FOREIGN KEY ( country_code ) REFERENCES t_country ( country_code );
Query OK, 2 rows affected (0.039 sec)              
Records: 2  Duplicates: 0  Warnings: 0

0

この問題は、主キーを次のような別のデータ型に配置すると発生します。

表1:

 Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->string('product_name');
        });

表2:

Schema::create('brands', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('brand_name');
        });

2番目のテーブルのIDのデータ型はインクリメントである必要があります


0

問題は非常に簡単に解決できます

例:ユーザー投稿の名前を持つ2つのテーブルがあり、外部キーを作成したい postsテーブルに phpMyAdminを使用する

1)でポストテーブルを追加新しい列名前 | use_id:タイプ:のようなIDでのユーザーテーブル| 長さ:のようなIDでのユーザーテーブル| デフォルト:NULLを|属性:符号なし|インデックス:INDEXを)

2)構造タブで関係ビューに移動します制約名:phpmyAdminによって自動設定| 列名:select user_id | テーブル:users | IDをキー:ID、...)

簡単に解決された

javad mosaviイラン/ urmia

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.