Q:
MySQL InnoDBで外部キーを設定しています。この外部キーの参照先カラムは、参照先テーブルで一意でないカラム(または、カラムの組み合わせ)を参照しています。ON DELETEの処理としてCASCADEを設定しています。
参照先テーブルで 〜 のデータを削除した時、参照元テーブルのデータが意図に反して削除されました(または、意図に反して削除されませんでした)。
どのように外部キーを設定すれば、意図に沿ったCASCADE処理になりますか?
A:
次のいずれかが有効でしょう。
- 外部キーを削除して、CASCADE処理を諦める
- 外部キーの参照先カラムを主キーや一意インデックスに変更して、CASCADE処理を正しく機能させる
なお、あなたの現在の(一意でないカラムを参照している)外部キーには、公式に保証されたDELETE CASCADE動作は存在しません(注1)。その外部キーを変更せずに、あなたの意図に沿った挙動を行わせる方法は無い、という前提で検討を進めた方が良いでしょう。
注1:
UNIQUE でないキーを参照する FOREIGN KEY 制約は、標準 SQL ではなく InnoDB の拡張機能です。 一方、NDB ストレージエンジンでは、外部キーとして参照される任意のカラムに明示的な一意キー (または主キー) が必要です。
一意でないキーまたは NULL 値を含むキーへの外部キー参照の処理は、UPDATE や DELETE CASCADE などの操作に対して適切に定義されていません。 UNIQUE (PRIMARY を含む) および NOT NULL キーのみを参照する外部キーを使用することをお勧めします。