web-dev-qa-db-ja.com

MySQL:テーブルを作成できません(errno:150)

.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)

148
gtilx

MySQL - FOREIGN KEY制約ドキュメント から:

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

160
OMG Ponies

エラー150は、あなたの外部キーに問題があることを意味します。おそらく、外部テーブルのキーはまったく同じ型ではないのでしょうか。

96
Dan McGrath

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

ソース: 同じような質問で他のユーザーからの回答

59

データ型は完全に一致する必要があります。 varchar型を扱っている場合、テーブルは同じ照合を使用しなければなりません。

28

私はこれらの答えすべてが正しい間、質問に誤解を招くと思います。

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

SET FOREIGN_KEY_CHECKS=0;

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

24
colin

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

20
pi.

エラー番号150は外部キー制約の失敗を意味します。おそらく、このテーブルは外部キーが依存するテーブル(テーブルkeywords)の前に作成しています。最初にそのテーブルを作成すればそれはうまくいくはずです。

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

11
Eran Galperin

Errno 150を引き起こす可能性があるものはたくさんありますので、このトピックを検索する人々にとって、これが私が徹底的なリストに近いと思うものです(source 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)システムによっては、ステートメント名とテーブル名に大文字と小文字の違いがある場合。あなたが1つのサーバから別のケースハンドリングルールを持っている別のものへ行くなら、これはあなたを悩ますことができます。

10
juacala

時々MySQLはただ超愚かである - 私は外部キーの原因を理解することができる。つまり、データベースはもう存在しません...そして、私が使用しているSQLユーザーは、サーバー上の他のデータベースにアクセスすることができません。このエラー?申し訳ありませんが、MySQLが嘘をついているのではないかと思いますが、対処することができます。

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

SQLを実行する必要があります...もしあなたが本当に外部キーの問題を抱えているのなら、チェックを再び有効にする行であなたに現れるでしょう - これは失敗するでしょう。

8
jebbie

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

4
Vitaliy

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

外部キーが正しく作成されるためには、すべてのMySQLが要求します。

  • すべての参照キーはPRIMARYまたはUNIQUEインデックスを持たなければなりません。
  • 参照元の列は、参照先の列と同じデータ型を持つ必要があります。

これらの要件を満たしていれば、すべてうまくいくでしょう。

4
Davies Malesi

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

3

通常、外部キーと主キーの不一致が原因でエラーが発生します。150。

外部キーは、主キーと同じデータ型を持つ必要があります。また、主キー符号なしの場合、外部キー- )にする必要があります。符号なし

3
Rakesh

あなたのテーブルのエンジンを変更してください、唯一のinnoDBは外部キーをサポートします

3
Lappies

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

3
Sushilkumar

PKテーブルが1つのCHARSETで作成され、次に別のCHARSETでFKテーブルを作成すると、このエラーが発生する可能性があります。その後、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
tinku

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

3

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

3
manzarul haque

私は同様の問題を抱えていましたが、私はデータを持っている既存のテーブルに新しいフィールドを追加していて、新しいフィールドは親テーブルから別のフィールドを参照していました。 - うまく動かなかったのは、なぜだと思いました。

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

データベースを前もって計画し、データ挿入の前に制約を実装した場合、通常の状況でこの特定のシナリオは避けられることを覚えておくことが重要です

この問題を回避するためのより簡単なアプローチは

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

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

2
chitwarnold

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

2

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

2
Basit

テキストファイルから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
Dharani Dharan

本当のEdgeの場合は、データベースの名前を変更するためにMySQLツール(私の場合はSequel Pro)を使用したことです。その後、同じ名前のデータベースを作成しました。

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

これがSequel Proのバグなのか、それともいくつかのユースケースでこの動作が必要なのかどうかはわかりませんが、朝の大部分はコストがかかります。

2
chim

単一のテーブルでDjango mysqlデータベースをダンプするとき、私は同様の問題を抱えていました。データベースをテキストファイルにダンプし、emacsを使用して問題のテーブルをファイルの末尾に移動し、変更されたSQLダンプファイルを新しいインスタンスにインポートすることで、問題を解決できました。

HTHウーベ

1
hoover

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

1
Dila Ram Gurung

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

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

1
ronIT

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

1
joksy82

おそらく this が助けになるでしょうか?主キー列の定義は、外部キー列とまったく同じでなければなりません。

1
Mukus

変数がnullを受け入れるようにすることで問題を修正しました

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

私は同じエラーがあった、それから私は最初に参照テーブルを作成してから参照テーブル

たとえば、従業員表のdept_noに従業員表と部署表を割り当てる外部制約がある場合、部署表が作成され、dept_noに主キー制約が割り当てられていることを確認します。

これは私のために働いた...

1
pooja patil

外部キーなしでテーブルを作成してから、外部キーを個別に設定します。

1
stuckhelper

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

0
Piyush Agarwal