2009-08-27 5 views
1

私は8つのテーブルを持っている:私はテーブルからレコードを削除 レコードを他の接続されたテーブルからアーカイブする方法はありますか?

users: 
    uid 
users_removed: 
    uid 
messages: 
    mid 
    uid FK users (uid) 
messages_removed: 
    mid 
    uid 
comments: 
    cid 
    mid FK messages (mid) 
comments_removed: 
    cid 
    mid 
files: 
    fid 
    mid FK messages (mid) 
files_removed: 
    fid 
    mid 

「ユーザー」私は(ユーザーから削除する前に)users_removedテーブルに移動します。また、対応するすべてのメッセージ(およびファイルとコメント)を* _removeテーブルに移動することもできます。

私が使用したトリガ:

CREATE TRIGGER delete_user BEFORE DELETE ON users 
    FOR EACH ROW BEGIN 
     INSERT IGNORE INTO users_removed 
      SELECT * FROM users WHERE uid = OLD.uid; 
     DELETE FROM messages WHERE OLD.uid in (owner_id, author_id); 
    END 
| 

CREATE TRIGGER delete_message BEFORE DELETE ON messages 
    FOR EACH ROW BEGIN 
     INSERT IGNORE INTO messages_removed 
      SELECT * FROM messages WHERE mid = OLD.mid; 
     DELETE FROM comments WHERE mid = OLD.mid; 
     DELETE FROM files WHERE mid = OLD.mid; 
    END 
| 

CREATE TRIGGER delete_comment BEFORE DELETE ON comments 
    FOR EACH ROW BEGIN 
     INSERT IGNORE INTO comments_removed 
      SELECT * FROM comments WHERE cid = OLD.cid; 
    END 
| 

CREATE TRIGGER delete_file BEFORE DELETE ON files 
    FOR EACH ROW BEGIN 
     INSERT IGNORE INTO files_removed 
      SELECT * FROM files WHERE fid = OLD.fid; 
    END 
| 

しかし、それは> 50Kのユーザと非常に遅い動作しますが、> 1メートルのメッセージ、コメントやファイル。

これを行う方法はありますか?

+1

これはおそらくテーブルの列としてこれを持っています。 – sshow

答えて

1
  1. これを行う方法はありません。 InnoDBを使用していると仮定すると、テーブルエントリを作成し、テーブルエントリ参照を削除してから、InnoDBは2番目のクリーンアップを実行して実際に削除します(削除は高価です)。その後、データベースにこれらの穴があると、最終的には時間の経過とともに多くのユーザーを削除するとパフォーマンスが低下する可能性があります。

  2. ユーザ情報を保存している場合は、単に「アクティブ」という列をenum(true、false)で追加するだけではどうですか?

+1

まあ...私は積極的にそのテーブルを使用し、別のフィルタ(アクティブ=真)を追加すると、読み込み時に非常に遅くなるので、私は 'アクティブ'フィールドを使用することはできません。 OK。だから私はそれが速くなることを望んでいないと仮定します。それは私がテーブルロックを取得しないために十分です。これにはいくつかの方法がありますか? – dryobates

+0

開始。/*仕事はここで起こる* /;コミット。 InnoDBを使用しています。 –

関連する問題