他のテーブルへのID列がいくつかあるテーブルがあります。
外部キーにデータを入れた場合にのみ整合性を強制したい。後で更新してその列にデータを入力する場合は、制約もチェックする必要があります。
(これはデータベースサーバーに依存している可能性があります。MySQLとInnoDBテーブルタイプを使用しています)
これは妥当な期待だと思いますが、間違っていた場合は訂正してください。
他のテーブルへのID列がいくつかあるテーブルがあります。
外部キーにデータを入れた場合にのみ整合性を強制したい。後で更新してその列にデータを入力する場合は、制約もチェックする必要があります。
(これはデータベースサーバーに依存している可能性があります。MySQLとInnoDBテーブルタイプを使用しています)
これは妥当な期待だと思いますが、間違っていた場合は訂正してください。
回答:
はい、値がNULLでない場合にのみ制約を適用できます。これは、次の例で簡単にテストできます。
CREATE DATABASE t;
USE t;
CREATE TABLE parent (id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (id INT NULL,
parent_id INT NULL,
FOREIGN KEY (parent_id) REFERENCES parent(id)
) ENGINE=INNODB;
INSERT INTO child (id, parent_id) VALUES (1, NULL);
-- Query OK, 1 row affected (0.01 sec)
INSERT INTO child (id, parent_id) VALUES (2, 1);
-- ERROR 1452 (23000): Cannot add or update a child row: a foreign key
-- constraint fails (`t/child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY
-- (`parent_id`) REFERENCES `parent` (`id`))
にNULLを挿入するため、最初の挿入は成功しますparent_id
。parent
テーブルに存在しない値を挿入しようとしたため、2番目の挿入は外部キー制約のために失敗します。
int
代わりにibatisまたは他のORMを使用してプリミティブを使用するとInteger
、デフォルトはnullにならず、0になり、制約に失敗します。
挿入するとき、null列の値は特にNULLとして宣言する必要があることを発見しました。そうでない場合、(空の文字列ではなく)制約違反エラーが発生します。
INSERT INTO {table} {list_of_columns}
か?それは私にも当てはまるからです。列の言及を省略するとエラーが発生しますが、NULLを含めて明示的にNULLに設定するとエラーが修正されます。私が正しければ、@ Garyのコメントは当てはまらないと思います(空の文字列を意味しなかったためです)が、@ Kevin Coulombeのコメントは役に立ちます...
はい、期待どおりに動作します。残念ながら、MySQLのマニュアルでこれに関する明示的な説明を見つけるのに苦労しているようです。
外部キーは、値が他のテーブルに存在する必要があることを意味します。NULLは値が存在しないことを意味するため、列をNULLに設定する場合、その列に制約を適用しようとしても意味がありません。
上記は機能しますが、機能しません。ON DELETE CASCADEに注意してください
CREATE DATABASE t;
USE t;
CREATE TABLE parent (id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (id INT NULL,
parent_id INT NULL,
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
) ENGINE=INNODB;
INSERT INTO child (id, parent_id) VALUES (1, NULL);
-- Query OK, 1 row affected (0.01 sec)
これを回避する別の方法は、他のテーブルにDEFAULT要素を挿入することです。たとえば、他のテーブルでuuid = 00000000-0000-0000-0000-000000000000への参照は、アクションがないことを示します。また、コードロジックに影響を与えないように、そのIDのすべての値を「中立」に設定する必要があります。たとえば、0、空の文字列、nullです。
この問題にもこだわりました。しかし、私は外部キーをと定義するだけで解決しましたunsigned integer
。以下の例を見つけてください
CREATE TABLE parent (
id int(10) UNSIGNED NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (
id int(10) UNSIGNED NOT NULL,
parent_id int(10) UNSIGNED DEFAULT NULL,
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
) ENGINE=INNODB;