2017-05-11 5 views
1

特定のIDの子を削除し、子が削除された後に子の親がもう子をもはや持っていない場合は、親を削除したいと考えています。 CASCADE DELETEは削除された親の子を削除するのに最適ですが、これは私の意図ではありません。外部キーの制約が強制され、一時的に無効にすることは望ましくありません。私はむしろトリガーまたはストアドプロシージャを使用しないでください。例えば子と親の両方のSQLレコードを削除する

CREATE TABLE IF NOT EXISTS parents (
    id INT NOT NULL, 
    data VARCHAR(45) NULL, 
    PRIMARY KEY (id)) 
ENGINE = InnoDB; 

CREATE TABLE IF NOT EXISTS children (
    id INT NOT NULL, 
    data VARCHAR(45) NULL, 
    parentsId INT NOT NULL, 
    PRIMARY KEY (id), 
    INDEX fk_children_parents_idx (parentsId ASC), 
    CONSTRAINT fk_children_parents 
    FOREIGN KEY (parentsId) 
    REFERENCES parents (id) 
    ON DELETE CASCADE 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 

サンプルデータ

parents 
id data 
1 foo1 
2 foo2 

children 

id parentId data 
1   1 bar1 
2   2 bar3 
3   2 bar3 

、上記のデータを用いて、子#1を削除すると、親#1を削除する必要があり、しかし、子#2を削除するか(ないと)#3を削除しないでください親#2。

私は3つのクエリでそれを行うことができます(1.親を取得する、2.子供を削除する、3.子供がいない場合は親を削除する)。

私は以下のようなものを考えていましたが、正しくありません。

DELETE c, p FROM children c 
LEFT OUTER JOIN parents p ON p.id=c.parentsId AND c.id!=123 
WHERE c.id=123 AND p.id IS NULL; 

これは1つまたは最大2つのクエリでどのように実行できますか?

+0

1つのクエリの問題は、子と親を同時に削除するとクエリがそれ以上の子があるかどうかわからないため、beacuaseはまだ削除されていません。 – Whencesoever

+0

@Whencesoeverサブクエリで子が削除され、サブクエリから子IDが渡されない場合を除き、同意しますか? – user1032531

+1

最高の賭けは本当にトリガーです。 mysqlには共通のテーブル式がないので、2つのクエリを使って考えることができる唯一の方法はパフォーマンスが非常に悪いです。アウェイ、あなたのショーの作成テーブルといくつかのデータを投稿してみませんか? – e4c5

答えて

2

3段階の設計に問題はありません。

このデザインは単純明快で効果的です。禁止的に非効率的であると疑う理由はありません。

これにはいくつかのステップを実行する方法がありますが、すべて「複雑なもの」を実行する必要があり、開発が難しく直感的ではないという欠点があります。

あなたは「良い/良い」と思うかもしれませんが、代替案を探求するのは素晴らしいですが、あなたの提案したデザインよりも優れたものは見当たりません。

+1

ありがとうダン、私は満足しています。私はちょうど良いことをすることができます/ときに何かをしたくない。私はそれをそのまま保ち、夜はよく眠ります。再度、感謝します! – user1032531

+0

@ user1032531それは良いことをするように動かされたことは素晴らしいことです。そのトリックは、そのドライブがあなたを過剰設計に導いていることを知っていることです(私はその機会に間違いを犯したので知っています:))。 –

+0

機会にのみ?私はいつもそれをすると思います!しかし、結局、私は自分の方法のエラーを発見:) – user1032531

関連する問題