2016-07-29 12 views
0

Qt CreatorにSQLiteデータベース接続を使用してC++アプリケーションを作成しています。私が達成したいのは、テーブルから行を削除すると、それを参照する他のテーブルの行も削除されるということです。したがって私のケースでは、バスケットから行を削除すると、コンピュータから行を参照することも削除され、サブタブテーブル、サブスクライバ、規制などから最後まで削除されます。ここでbefore delete trigger低性能

は私のデータベース・ダイアグラムである:

DB Diagram

私は別のテーブルとの外部キー参照を持つ各テーブルのトリガーを作成しました。

CREATE TRIGGER delete_fk BEFORE DELETE ON Basket 
FOR EACH ROW BEGIN 
    DELETE FROM Computer WHERE computer.basket = old.id_basket; 
END 

CREATE TRIGGER delete_fk_comp BEFORE DELETE ON computer 
FOR EACH ROW BEGIN 
    DELETE FROM subsystemtable WHERE subsystemtable.computer = id.id_computer; 
END 

CREATE TRIGGER delete_fk_subscriber_map BEFORE DELETE ON subscriber 
FOR EACH ROW BEGIN 
    DELETE FROM mappingtable WHERE mappingtable.subscriber = old.id_subscriber; 
END 

CREATE TRIGGER delete_fk_subscriber_indirect BEFORE DELETE ON subscriber 
FOR EACH ROW BEGIN 
    DELETE FROM indirectsubscriber WHERE indirectsubscriber.subscriber = old.id_subscriber; 
END 

CREATE TRIGGER delete_fk_subscriber BEFORE DELETE ON subscriber 
FOR EACH ROW BEGIN 
    DELETE FROM reserve WHERE reserve.subscriber = old.id_subscriber; 
END 

CREATE TRIGGER delete_fk_subscriber_res BEFORE DELETE ON subscriber 
FOR EACH ROW BEGIN 
    DELETE FROM reserve WHERE reserve.subscriber_res = old.id_subscriber; 
END 

CREATE TRIGGER delete_fk_subs BEFORE DELETE ON subsystem 
FOR EACH ROW BEGIN 
    DELETE FROM subsystemtable WHERE subsystemtable.subsystem = old.id_subsystem; 
END 

CREATE TRIGGER delete_fk_substable_reg BEFORE DELETE ON subsystemtable 
FOR EACH ROW BEGIN 
    DELETE FROM regulations WHERE regulations.subsystem = old.id; 
END 

CREATE TRIGGER delete_fk_substable BEFORE DELETE ON subsystemtable 
FOR EACH ROW BEGIN 
    DELETE FROM subscriber WHERE subscriber.subsystem = old.id; 
END 

私は欲しかったものを得ました。それはまさに私が望んでいたように機能します。しかし、今私の問題は低いパフォーマンスです。私のデータベースでは、各バスケットに約20台のコンピュータがあり、各コンピュータに約5台のサブシステム、各サブシステムに100台のサブスクライバがあります。私が1つの単一バスケットを削除すると、全体の手順は約400ミリ秒かかります。一度に3つのバスケットを削除する必要があります、それはすでに3秒以上かかるでしょう。

私はこれをより速く動作させる方法を見つける必要があります。約200〜300ミリ秒で制限されています。そして私はそれをどうやって行うことができるかについての提案が必要です。

+1

他の成熟したデータベースシステムを使用しますか?例えば、PostgreSQL。または、外部キーを適切に使用してください(https://www.sqlite.org/foreignkeys.html#fk_actions)。 'カスケード'。 – maxik

答えて

2

外部キーを手動で実装しています。 これは必須ではありません。 ON DELETE actionsを使用して、DBに適切な変更をさせることができます。

外部キーを手動で実装する場合でも、DBの助けを借りて実装する場合でも、indexes on certain key columnsを作成する必要があります。または、関連する行を見つけるために必要なルックアップがすべて遅くなります。

+0

特に、外部キー制約を作成するときは、 'ON DELETE CASCADE'オプションを使うべきです。たとえば、 'Computer'は' Basket'を参照しているので、 'id_basket'に外部キー定数を追加する必要があります。 'Basket'の行が削除された場合、' Computer'の 'id_basket'が参照されている行も自動的に削除されます。トリガーをまったく混乱させる必要はありません。 –

+0

何らかの理由でDELETE CASCADEが動作しません。この質問を参照してください:http://stackoverflow.com/questions/38588039/sqlite3-on-delete-cascade-does-not-work私はSQliteしか使用できません。 @ Alvin –

+0

@EgorChubarov:問題が何であるか不明です。 DBへの新規接続を確立するたびに 'プラグマforeign_keys = on'を実行していて、DBに接続するすべてのプラグマがこのプラグマを実行していますか? –

関連する問題