0

私はいくつかのハイボリュームを扱っていますが、それほど変更可能なデータではupdate_historyなく、現在のデータを保持するテーブル ( と呼びます) と同様に、変更のテーブル ( と呼びます) を維持したいと考えていますcurrent_data

  • current_data次を含む: id(一意)、value(tstamp現在のタイムスタンプ)
  • update_history次が含まれます: id(これも一意です), value, tstamp(すべての更新に対して),delete

= 1の特定のデータがあるとしidます。時間 0 で 10 に初期化され、時間 5 で 2 に変更され、時間 8 で削除され、時間 10 で再び 10 に設定されます。update_history含有すること:

Id Value Stamp Delete 
1    10     0     0
1     2     5     0
1     2     8     1
1    10    10     0

update_historyテーブルを変更するたびに選択できますがcurrent_data、値が変更されたかどうか、または ID が削除されたかどうかを確認して行を挿入すると、やや過剰に思えます。

これを 1 つか 2 つのクエリでまとめて行う方法を探しています。id具体的には、 inupdate_historyごとidに対応する in をチェックし、最新またはincurrent_dataの値の不一致が見つからない場合、, , , =0 で行を挿入するクエリを探しています。tstampidupdate_historyidvaluestampdelete

どんな助けでも大歓迎です。

4

1 に答える 1

1

これを継続的に行う場合は、MySQL のTRIGGERSについて調べてください。

それ以外の場合、これが 1 回限りのタスクであれば、2 つのクエリで実行できます。最初に、履歴の最後の値とは異なる値を持つ現在のテーブルのすべての行を識別し、履歴に新しい行を挿入します

INSERT INTO update_history SELECT cd.id,cd.value,UNIX_TIMESTAMP(),0
FROM current_data cd 
INNER JOIN update_history uh1 ON ( cd.id=uh1.id AND cd.value!=uh1.value AND uh1.delete=0)
WHERE uh1.stamp = (
SELECT MAX(stamp) 
FROM update_history uh2
WHERE uh2.id=cd.id
)

次に、履歴にエントリがない現在の行を特定します

INSERT INTO update_history SELECT cd.id,cd.value,UNIX_TIMESTAMP(),0
FROM current_data cd 
LEFT JOIN update_history uh1 ON cd.id=uh1.id 
WHERE uh1.id IS NULL

あなたのデザインにはいくつかの欠陥があると思います。たとえば、2 つの変更が (タイムスタンプに関して) 同時に発生した場合はどうなりますか? どちらが「最初」であったかをどのように識別しますか? 履歴テーブルで一意の ID が必要になる場合があります。

于 2012-04-18T18:21:04.043 に答える