1

2 つのテーブルが 2 つの fk で構築された 1 つの制約を含む 3 番目のテーブルによってリンクされている場合、on delete カスケードまたは join delete を使用することをお勧めしますか?

create T1 (
id1 ...
...
CONSTRAINT pk_id1 PRIMARY KEY (id1) );

create T2 (
id2 ...
...
CONSTRAINT pk_id2 PRIMARY KEY (id2) );

create T3 (
id1 ...,
id2 ...,
CONSTRAINT pk_T3 PRIMARY KEY (id1, id2),
CONSTRAINT fk_T3_1 FOREIGN KEY (id2)
  REFERENCES T2 (id2) MATCH SIMPLE
  ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT fk_T3_2 FOREIGN KEY (id1)
  REFERENCES T1(id1) MATCH SIMPLE
  ON UPDATE CASCADE ON DELETE CASCADE )

削除カスケードで使用するのは危険だと言う人もいますが、結合削除はそれほど危険ではありませんか?

編集:削除する正しいクエリが見つかりませんでした:
もしそうなら

delete from T1 where id1=$id1

次に、行 $id1 が T1 から削除され、行 $id1,$id2 が T3 から削除されますが、T2 から $id2 は削除されません。
私が行った場合

delete from T3 where id1=$id1 and id2=$id2  

次に、行 $id1 は T1 で削除されず、行 $id2 は T2 で削除されず、対 ($id1,$id2) は T3 で削除されます。
1 つのクエリで削除するにはどうすればよいですか?
編集:次のように、T2 テーブルの制約の 1 つを移動することでトリックを見つけることを考えました:

 create T1 (
id1 ...
...
CONSTRAINT pk_id1 PRIMARY KEY (id1) );

create T2 (
id2 ...
...
CONSTRAINT pk_id2 PRIMARY KEY (id2) ),
CONSTRAINT fk_T2 FOREIGN KEY (id2)
  REFERENCES T3 (id2) MATCH SIMPLE
  ON UPDATE CASCADE ON DELETE CASCADE);

create T3 (
id1 ...,
id2 ...,
CONSTRAINT pk_T3 PRIMARY KEY (id1, id2),

CONSTRAINT fk_T3_2 FOREIGN KEY (id1)
  REFERENCES T1(id1) MATCH SIMPLE
  ON UPDATE CASCADE ON DELETE CASCADE );  

しかし、「参照された T3 テーブルには一意の制約がありません」というメッセージが表示されます。

4

1 に答える 1

3

オン デリート カスケードは、無知なクエリが思ったよりも多くを削除する可能性があるという意味で、「危険」と呼ばれることがあります。不適切な where 句 (ツリー内のルート ノードを誤って削除した) が、カスケード削除によって予想以上のヒープ (つまり、それらのルート ノードのサブツリー) を削除してしまうケースを少なくとも 1 つ見たことがあります。

この意味で、結合削除はそれほど危険ではありません。

SQL を学習しているユーザーに時折提案されることは、カスケード削除をまったく使用しないことです。これにより、where句が正しくない場合に便利なエラーメッセージが表示されるため、何をどの順序で削除するかを気にする必要があります. しかし、結合削除の使用について心配するほど SQL に慣れている場合は、その点をはるかに超えている可能性があります。

于 2013-06-08T15:28:47.137 に答える