2011-09-22 7 views
17

私は2つのテーブルを持っています.1つは「ユーザー」で、もう1つは「注文」です。ここで、注文テーブルにはユーザーIDテーブルへの外部キー参照があります。 (私はこのケースでは、ユーザIDとしてメールアドレスを使用しています。)MySql外部キー:ONアクションを削除するbehavour - 参照フィールドに情報を残す方法?

を私は何を達成したいことはこれです:ユーザーテーブルIDが更新されると

  1. (=電子メールアドレスが変更された)、この参照される注文表のuser_idフィールドに反映されます。 (これはON UPDATE CASCADE指令を使用してうまくいきます - ここでは問題ありません)

  2. ユーザがユーザテーブルから削除された場合、参照されているuser_idを保持しています。

    私が参照されるユーザIDフィールドにDELETE CASCADE ON使用している場合

    、注文行が削除もちろんです:

私は第二の目標に問題を抱えています。

私はON DELETE NO ACTIONを使用すると、ユーザーを削除しようとするとエラーが発生します。 (#1451 - 親行を削除または更新できません:外部キー制約は失敗します)

ON DELETE SET NULLを使用すると、ユーザー行は削除できますが、参照される情報はnullに設定されていますその注文をした人を追跡してください...

参照テーブルの参照されたuser_id情報を保持したまま、ユーザーテーブルからユーザーを削除する方法はありますか?

答えて

20

つのオプション:

  • は、実際にユーザを削除しないでくださいdeletedフィールドを設定することにより、削除済みとして、ちょうどそれらをマーク。

か:

  • 外部キー制約を削除します。

私は最初のオプションをお勧めします。 2番目のオプションを使用すると、データの不一致が発生する可能性があります。また、他のテーブルに対応するデータがないキーの値を持っているだけでは、あまり助けにならないでしょう。

+0

ありがとう、マーク!それは、私が純粋な外来語の定義で求めたものを達成することは不可能であることを意味します。 – Cambiata

+2

@Cambiata:そうです、純粋な外部キー定義では不可能です。 "外部キー" *は、値が別のテーブルに存在することを意味します。実際に他のテーブルから参照された行を削除する場合は、a)行全体を削除する(ON DELETE CASCADE)か、またはb)FK値をNULLに設定する(ON DELETE SET NULL)か、 。 –

+3

私は参照してください。私はNO ACTION alternatvieが意味することを望んでいた。現在の値は変更されず、通常のnon-fk値のように動作します。明らかにそうではありません!ありがとう、マーク! – Cambiata

0

実際には別の方法があります。ユーザーテーブルの電子メールアドレスキーをautoincrement INTに置き換えます。

次に、ユーザー属性(醜い非正規化)を注文にコピーすることができます(注文時の注文ユーザーの電子メールアドレスであると見なすことができます)。

次に、ON DELETE SET NULLは外部キーINTをリセットできますが、コピーされた属性(電子メールアドレス)はリセットできません。

関連する問題