MySQL:テーブルを作成できません(エラー番号:150)


156

.sqlファイルをインポートしようとしていますが、テーブルの作成に失敗します。

失敗したクエリは次のとおりです。

CREATE TABLE `data` (
`id` int(10) unsigned NOT NULL,
`name` varchar(100) NOT NULL,
`value` varchar(15) NOT NULL,
UNIQUE KEY `id` (`id`,`name`),
CONSTRAINT `data_ibfk_1` FOREIGN KEY (`id`) REFERENCES `keywords` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;    

同じデータベースから.sqlをエクスポートしました。すべてのテーブルを削除しましたが、インポートしようとしましたが、なぜ失敗しますか?

MySQL:テーブル './dbname/data.frm'を作成できません(errno:150)


1
このエラーの本質的にすべての原因について、MySQLでerrno 150(およびerrno 121 /その他の外部キーエラー)を引き起こす原因についての包括的なリソースを以下に示します。
ジョンスミス

21
列が同一である必要があることを発見しました(符号なしフラグも一致する必要があります)。
Justin Skiles

3
@JohnSmith ...どこ?
Charles Wood

3
私はこのブログの記事を読んだことを示唆しているリスト10考えられる原因:verysimple.com/2006/10/22/...
マーク・アメリー

@CharlesWood:「ジョンスミス ... 13年4月6日19:29に見た」、これはコメントの約3か月前です。この鈍い世界の終わりまで「どこ」の謎が明らかにならないのではないかと恐れています!:>
trejder 2014年

回答:


167

MySQLから-FOREIGN KEY Constraints Documentation

削除されたテーブルを再作成する場合は、そのテーブルを参照する外部キー制約に準拠する定義が必要です。前述のように、正しい列名と型があり、参照されるキーにインデックスが必要です。これらが満たされない場合、MySQLはエラー1005を返し、エラーメッセージでエラー150を参照します。これは、外部キー制約が正しく形成されなかったことを意味します。同様に、エラー150が原因でALTER TABLEが失敗した場合、これは、変更されたテーブルの外部キー定義が誤って形成されることを意味します。


1
1つのテーブルの2つの列がPKである別のテーブルの1つの列を参照できますか?
ユージーン

1
@Eugene:2つの列はそれぞれ、別のテーブルのPKに対する外部キーの関係を持つことができます。両方の列が単一の外部キーの関係として持つことはできません。
OMGポニー2011年

1
@OMGPonies:!この質問に答えるためのおかげで..私はそれを探していた...私もここで質問をstackoverflow.com/questions/13487010/...私はいくつかの良い答えを持っていますが、私が準拠することにしたいが.... Whether its possible to write Nested Query for my problem?..私にも答えてくださいとお願いします!
Grijesh Chauhan、

19
私のエラーは、マスターテーブルにMyISAMと子テーブルのInnoDBエンジンがあったことです。現在のcreate.sqlスクリプトはすべてのテーブルにInnoDBを使用していましたが、最初のスクリプトがMyISAMを使用していた非常に古いインストールがありました。
Whome 2013

2
@Whome-うん、ここで同じ問題に遭遇しました。
aroth 2013年

96

エラー150は、外部キーに問題があることを意味します。おそらく、外部テーブルのキーは完全に同じ型ではありませんか?


15
おかげで:)私にとって、データ型はINTですが、一方は符号なしで、もう一方はそうではありません
Anh Nguyen

6
スキーマジェネレーターを使用しているときは、よくBIGINTvs INTに出会います。
Xeoncross 2014

外部キーがINT値ではないときに同じ問題に遭遇しました。外部キーが列を参照する場合、列はUNIQUEでなければなりません。
PhatHV 2015

62

実際のエラーメッセージを取得するには、実行してから出力をSHOW ENGINE INNODB STATUS;探しLATEST FOREIGN KEY ERRORます。

出典:同様の質問で別のユーザーからの回答


7
これは実際には非常に便利です。正確なエラーがわかります。
Csongor Fagyal 2014

ありがとう。MySQL Workbenchがこれを利用しないのは残念です。
scipilot 2014年

驚くばかり。これはとても役に立ちます。正確なエラーを通知します。私は、列をNULLABLEにしましたが、 "on delete set null"を設定していました。どうもありがとうございます。
Abhishek Saini 2016

サーバーの権限を持っている場合:(
Christopher Smit


25

私はこれらのすべての答えは正しいが質問を誤解させると思います。

実際の答えは、外部キーを含むダンプファイルを復元する場合、復元を開始する前にこれです。

SET FOREIGN_KEY_CHECKS=0;

当然のことながら、外部テーブルが存在する前に、復元によっていくつかの制約が作成されます。


これを実行してもうまくいきませんでしたが、それでもエラーが発生します。何か案は?
Joseph Astrahan

24

場合によっては、関連するテーブル間に異なるエンジンがあると、このエラーメッセージが表示されることがあります。たとえば、他のテーブルがMyISAMを使用している間に、テーブルがInnoDBを使用している場合があります。両方が同じである必要があります


ありがとう-これは私の問題でした。
scipilot 2014年

それが私の問題でした。ありがとう
thed0ctor 2014

これは、mysqldumpを使用してinnodbテーブルのsqlファイルを作成し、代わりにmyisam talbesとしてエクスポートした場合に発生する可能性があります。
アマドマルティネス

11

エラー番号。150は、外部キー制約の失敗を意味します。外部キーが依存するテーブル(テーブルkeywords)の前にこのテーブルを作成している可能性があります。最初にそのテーブルを作成すると、正常に機能するはずです。

含まれていない場合は、外部キーステートメントを削除し、テーブルの作成後に追加してください。特定の制約の失敗に関するより意味のあるエラーメッセージが表示されます。


10

errno 150を引き起こす可能性のあるものはかなりいくつかあるので、このトピックを検索している人にとって、これが完全なリストに近いと私が思うものです(ソースCauses of Errno 150):

errno 150またはerrno 121の場合、単にSHOW ENGINE INNODB STATUSと入力すると、「LATEST FOREIGN KEY ERROR」というセクションがあります。その下では、非常に役立つエラーメッセージが表示され、通常は問題がすぐにわかります。これを実行するにはSUPER権限が必要なので、それがない場合は、次のシナリオをテストする必要があります。

1)データ型が一致しない:列の型は同じである必要があります

2)インデックス付けされていない親列(または間違った順序でインデックス付けされている)

3)列の照合順序が一致しない

4)NOT NULL列でのSET NULLの使用

5)テーブルの照合順序が一致しない:列の照合順序が一致しても、一部のMySQLバージョンではこれが問題になる場合があります。

6)親列が実際に親テーブルに存在しない。スペルをチェックします(列の最初または最後にスペースがある可能性があります)

7)いずれかの列のインデックスの1つが不完全であるか、列が長すぎて完全なインデックスを作成できません。MySQL(微調整しない限り)の最大単一列キー長は767バイトです(これはvarchar(255)UTF列に対応します)。

errno 121が発生する場合、いくつかの原因があります。

1)選択した制約名はすでに使用されています

2)一部のシステムでは、ステートメント名とテーブル名に大文字と小文字の違いがある場合。これは、あるケースから別のケース処理ルールを持つ別のサーバーに移動する場合にかみつくことがあります。


一部のバージョンでは、テーブルがinnodbでない場合にerrno 150を取得しますが、一部のバージョンでは、黙って失敗するだけです。
juacala

ありがとう、これは素晴らしかった:| ------------------------ | 最新の外部キーエラー| ------------------------ | |の一部を使用してSET NULL条件を定義しました。列はNOT NULLとして定義されます。
Sam Critchley

8

時々MySQLは非常に愚かです-私は外部キーの理由の原因を理解できます。しかし、私の場合、データベース全体を削除したばかりで、それでもエラーが発生します...なぜですか?つまり、データベースはもうありません...そして、使用しているsql-userはサーバー上の他のデータベースにアクセスできません...つまり、サーバーは現在のユーザーに対して「空」であり、それでも取得しますこのエラー?申し訳ありませんが、MySQLは私に嘘をついていると思います...しかし、私はそれを処理することができます:)次の2行のSQLを面倒なステートメントの周りに追加するだけです。

SET FOREIGN_KEY_CHECKS = 0;
# some code that gives you errno: 150
SET FOREIGN_KEY_CHECKS = 1;

これでsqlを実行する必要があります...外部キーの問題が本当にある場合は、チェックを再度有効にする行が表示されます-これは失敗します。しかし、私のサーバーは静かです:)


列とそれが参照している列の間に実際の違いがある場合、これは問題を引き起こす可能性があります。例えば。参照される列がvarchar(200)で、参照元がvarchar(50)であるとすると、カスケードが試行されると、奇妙な動作が発生する可能性があります。データの不一致が原因でerrno 150が発行される問題には遭遇していません。
juacala

興味深い洞察@juacala :)私にとって面白いのは、これに遭遇したときはいつでも、私のアプローチは常にそれを修正しました...少なくとも今日まで:Dしかし、私たちは学習を止めることはありません;)
jebbie

これは実際にスクリプトリキベースを生成するのに役立ちました。スクリプトはMySQL> 5.5では問題なく実行されましたが、バージョン5.1では失敗しました。
delbertooo 2015年

4

上記の回答を調べて少し実験した後、これはMySQLの外部キーエラー(1005-エラー150)を解決する効果的な方法です。

外部キーが適切に作成されるために、MySQLが要求するのは次のとおりです。

  • 参照されるすべてのキーには、PRIMARYまたはUNIQUEインデックスが必要です。
  • 再度参照する列は、参照される列と同じデータ型を持つ必要があります。

これらの要件を満たせば、すべて順調になります。


4

WindowsアプリケーションをLinuxに移植したときに、このエラーが発生しました。Windowsではデータベーステーブル名は大文字と小文字が区別されませんが、Linuxではファイルシステムの違いが原因で大文字と小文字が区別されます。したがって、WindowsのテーブルTable1はと同じでtable1REFERENCES両方table1Table1機能します。Linuxでは、データベース構造を作成するときではtable1なくアプリケーションを使用するとTable1、エラー#150が表示されました。Table1リファレンスで大文字と小文字を区別すると、Linuxでも動作し始めました。したがって、他に何も役に立たないREFERENCES場合は、Linuxでテーブル名に大文字と小文字を正しく使用してください。


これも私の場合でした!スクリプトを大文字と小文字を区別しない(OS X)から大文字と小文字を区別するmysqlバージョン(Debian)に移動します。
mircealungu

3

テーブルのエンジンを変更し、innoDBのみが外部キーをサポートする


3

PKテーブルが1つのCHARSETで作成され、FKテーブルを別のCHARSETで作成した場合、このエラーも発生する可能性があります...このエラーも発生しましたが、文字セットをPK文字セットに変更すると、エラーなしで実行されました。

create table users
(
------------
-------------
)DEFAULT CHARSET=latin1;


create table Emp
(
---------
---------
---------
FOREIGN KEY (userid) REFERENCES users(id) on update cascade on delete cascade)ENGINE=InnoDB, DEFAULT CHARSET=latin1;

3

このエラーは、2つのテーブルに参照がある場合(たとえば、1つのテーブルがStudentで、別のテーブルがEducationであり、EducationテーブルにStudentテーブルの外部キー参照がある場合)に発生する可能性があります。この場合、両方のテーブルの列のデータ型は同じである必要があります。そうでない場合、エラーが発生します。


3

ほとんどの場合、問題はENGINE dIfferenceが原因です。親がInnoDBによって作成されている場合、参照されているテーブルはMyISAMによって作成され、その逆も同様です。


3

私の場合。ホスティングサーバーが設定を変更し、新しいテーブルがMyISAMだったのでエンジンと文字セットに問題がありましたが、古いテーブルはInnoDBです。ちょうど私が変わった。


私が作成したのではないデータベースを変更していたので、これは私にとって正しいことでした。
FonzTech 2018年

3

通常、外部キーと主キーの不一致によりエラーが発生します:150。

外部キーは、同じ持っている必要がありますデータ型として主キーを。また、主キー署名されていない場合、外部キー署名されていない必要があります。


3

同じ問題がありました。これは、テーブルの列の照合順序文字セットに関連していた。2つのテーブルの両方の列で文字セット照合順序が同じであることを確認してください。その上に外部キーを設定したい場合。例-usersテーブルのuserID列を参照するuserImageテーブルのuserID列に外部キーを配置する場合。照合は、テーブルの両方の列でutf8_general_ciおよび文字セットutf8と同じでなければなりません。一般に、テーブルを作成すると、mysqlはサーバー設定からこれらの2つの構成を取得します。


なぜこの詩を見たことがないのか!?私は1時間かけて根本的な原因を解明しました。それは私の場合の文字セットでした。参照されるテーブルと参照するテーブルの文字セットは同じである必要があります。
Sujit Joshi 2018

2

主キー列と参照列の両方が同じデータ型と属性(符号なし、バイナリ、符号なしゼロフィルなど)を持っていることを確認してください。


2

実際のエッジケースは、MySQLツール(私の場合はSequel Pro)を使用してデータベースの名前を変更した場合です。次に、同じ名前のデータベースを作成しました。

これにより、同じデータベース名に対する外部キー制約が保持されたため、名前が変更されたデータベース(my_db_renamedなど)には、新しく作成されたデータベース(my_db)に外部キー制約がありました。

これがSequel Proのバグかどうか、またはいくつかのユースケースでこの動作が必要かどうかはわかりませんが、朝の一番の費用がかかります:/


2

同じエラーが発生しました。私の場合、エラーの理由は、制約にON DELETE SET NULLステートメントがあり、その定義に制約を置いたフィールドにNOT NULLステートメントがあったためです。フィールドでNULLを許可することで問題は解決しました。


2

テキストファイルからDBを作成しているときに、この種の問題に直面しました。

mysql -uroot -padmin < E:\important\sampdb\createdb.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\insert_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\insert_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\load_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\load_absence.sql 

私は上記の行を書きました Create.bat batファイルを実行しました。

私の間違いは、SQLファイルの実行順序にあります。主キーと外部キーを使用してテーブルを作成しようとしました。実行中は参照テーブルを検索しますが、テーブルはありません。したがって、このようなエラーが返されます。

外部キーを使用してテーブルを作成する場合は、参照テーブルが存在するかどうかを確認してください。また、参照テーブルとフィールドの名前も確認してください。


つまり、まだ存在しない別のテーブルを指す外部キーを持つテーブルを作成しようとしました。問題を解決するには、テーブルを正しい順序で作成します。
ビンセント

2

私にも同様の問題がありましたが、私のデータは、既存のテーブルにデータが含まれている新しいフィールドを追加していて、新しいフィールドが親テーブルの別のフィールドを参照していて、DEFINEにNOT NULLがあり、DEFAULT VALUESがないためでした。-うまくいかなかった理由は、

  1. 新しいフィールドでは、制約を適用する前に、空白のフィールドに各レコードの親テーブルの値を自動入力する必要がありました。制約が適用されるたびに、テーブルデータの整合性を維持する必要があります。制約(外部キー)を実装していても、親テーブルの値を持たないデータベースレコードがいくつかあるため、データが破損しているため、MySQLは制約を強制しません。

データベースを事前に十分に計画し、データを挿入する前に制約を実装した場合、通常の状況ではこの特定のシナリオは回避されることに注意してください。

この問題を回避する簡単な方法は、

  • データベーステーブルデータを保存する
  • テーブルデータ(およびテーブルアーティファクト、つまりインデックスなど)を切り捨てます
  • 制約を適用する
  • データをインポートする

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


1

おそらくこれは役に立ちますか?主キー列の定義は、外部キー列とまったく同じでなければなりません。


1

すべてのテーブルが外部キーをサポートできることを確認してください-InnoDBエンジン


1

子テーブルから参照しているPARENTテーブルの列は一意である必要があります。そうでない場合は、エラー150を引き起こします。


おそらく、もう少し詳細を追加する価値があるでしょう-たとえば、特定の列名とテーブル名
Jonathan

1

Django mysqlデータベースを単一のテーブルでダンプするときにも同様の問題がありました。データベースをテキストファイルにダンプし、emacsを使用して問題のテーブルをファイルの最後に移動し、変更したSQLダンプファイルを新しいインスタンスにインポートすることで、問題を解決できました。

HTH Uwe


1

変数を受け入れるようにして問題を修正しました null

ALTER TABLE `ajout_norme` 
CHANGE `type_norme_code` `type_norme_code` VARCHAR( 2 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL

1

一連のMySQLコマンドを実行すると、同じ問題が発生しました。鉱山は、まだ作成されていない他のテーブルへの外部キーを参照するときに、テーブルの作成中に発生します。参照する前のテーブルの存在順序です。

解決策:外部キーを持つ子テーブルを作成する前に、まず親テーブルを作成します。


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