sql >> データベース >  >> RDS >> Mysql

MySQL errnoを与える外部キーを使用したテーブルの作成:150

    ALTER TABLE ADD FOREIGN KEYでも同じ問題が発生しました 。

    1時間後、エラー150が発生しないようにするには、これらの条件が満たされている必要があることがわかりました。

    1. 親テーブルは、それを参照する外部キーを定義する前に存在している必要があります。テーブルを正しい順序で定義する必要があります。最初に親テーブル、次に子テーブルです。両方のテーブルが相互に参照している場合は、FK制約なしで1つのテーブルを作成し、次に2番目のテーブルを作成してから、ALTER TABLEを使用して最初のテーブルにFK制約を追加する必要があります。 。

    2. 2つのテーブルは、両方とも外部キー制約をサポートしている必要があります。つまり、ENGINE=InnoDB 。他のストレージエンジンは外部キー定義を黙って無視するため、エラーや警告は返されませんが、FK制約は保存されません。

    3. 親テーブルで参照される列は、キーの左端の列である必要があります。親のキーがPRIMARY KEYの場合に最適です またはUNIQUE KEY

    4. FK定義は、PK定義と同じ順序でPK列を参照する必要があります。たとえば、FK REFERENCES Parent(a,b,c)の場合 その場合、親のPKを(a,c,b)の順序で列に定義してはなりません。 。

    5. 親テーブルのPK列は、子テーブルのFK列と同じデータ型である必要があります。たとえば、親テーブルのPK列がUNSIGNEDの場合 、必ずUNSIGNEDを定義してください 子テーブルフィールドの対応する列。

      例外:文字列の長さが異なる場合があります。例:VARCHAR(10) VARCHAR(20)を参照できます またはその逆。

    6. 文字列タイプのFK列は、対応するPK列と同じ文字セットと照合を使用する必要があります。

    7. 子テーブルにすでにデータがある場合、FK列のすべての値は、親テーブルのPK列の値と一致する必要があります。次のようなクエリでこれを確認してください:

      SELECT COUNT(*) FROM Child LEFT OUTER JOIN Parent ON Child.FK = Parent.PK 
      WHERE Parent.PK IS NULL;
      

      これは、ゼロ(0)の一致しない値を返す必要があります。明らかに、このクエリは一般的な例です。テーブル名と列名を置き換える必要があります。

    8. 親テーブルも子テーブルもTEMPORARYにすることはできません テーブル。

    9. 親テーブルも子テーブルもPARTITIONEDにすることはできません テーブル。

    10. ON DELETE SET NULLを使用してFKを宣言する場合 オプションの場合、FK列はnull許容である必要があります。

    11. 外部キーの制約名を宣言する場合、制約名は、制約が定義されているテーブルだけでなく、スキーマ全体で一意である必要があります。 2つのテーブルには、同じ名前の独自の制約がない場合があります。

    12. 新しいFKを作成しようとしている同じフィールドを指している他のテーブルに他のFKがあり、それらが不正な形式(つまり、異なる照合)である場合は、最初に一貫性を保つ必要があります。これは、SET FOREIGN_KEY_CHECKS = 0;での過去の変更の結果である可能性があります 誤って定義された一貫性のない関係で利用されました。これらの問題のあるFKを特定する方法については、以下の@andrewdotnの回答を参照してください。

    これがお役に立てば幸いです。



    1. VPS/専用サーバーでPostgreSQLを入手する方法

    2. より高速なSQLビューを作成するために知っておく必要のあるトップ3のヒント

    3. SQL Serverで行レベルのロックを強制することは可能ですか?

    4. あるSQLServerから別のSQLServerにテーブルデータをエクスポートする