過去の事実が損なわれる例
例1:料率の変更
消費税率を5%→8%に変更する対応をするために設定マスタの値を変更したとします。
消費税変更前に、購入があった本を返品する処理が動きました。その際に、8%で返品の計算が行われるため売り上げがずれることになります。
例2:ステータスの変更
以下、二つのステータス更新処理はプロセスが異なりますが、最終結果は同じです。途中経過がわからなくなってしまいます。
- 発注済→キャンセル→再注文→発送完了
- 発注済→発送完了
問題点
上記の例でば、正常時は全く問題ないですが、トラブルが起きたときに問題が起きやすくなります。
対策
対策1:履歴を持たせる。
消費税率 | 開始日 | 終了日 |
---|---|---|
0.05 | 1997-04-01 | 2014-03-31 |
0.08 | 2014-04-01 | null |
対策2:購入商品自体に履歴を持たせる。
商品名 | 売上日 | 消費税率 |
---|---|---|
ノート | 2014-03-31 | 0.05 |
鉛筆 | 2014-04-01 | 0.08 |
対策3:ステータステーブルを作り最新レコードを今のステータスとしてみる。
売上ID | ステータス | 日時 |
---|---|---|
1 | 発注済み | 2014-03-31 11:00 |
1 | キャンセル | 2014-03-31 12:00 |
1 | 発送済み | 2014-03-31 13:00 |
履歴を保存するデメリット
基本的にはパフォーマンスに影響が出ます。
- レコードの保存量が増えてテーブルサイズが大きくなる。
- テーブルサイズが増えると集計が遅くなる。(単純な主キー検索じゃなくなるため)
これらのさらなる対策
- マテリアライズドビューを利用する。
- 集計済み結果を保存したサマリーテーブルを用意する。
パフォーマンスを考慮してあえて履歴テーブルを持たせない
この選択をする場合もあります。その場合は必ず別手段で対応するようにしましょう。
- 遅延レプリケーションを使う。
- アプリケーションログとしてElasticsearchなどの分析ツールに保存する。
遅延レプリケーションとは?
指定した時間分、スレーブDBに対して、マスタDBからのレプリケーションを遅延させることができる機能です。例えば、2日遅れや3時間遅れのスレーブDBを作ったりすることができます。
メリット
DBに対して柔軟な設計を与えてくれます。
ユースケース
- マスタDB上で行われた誤った作業から保護してくれる。
- システムデバッグ時の再現手法となる。
注意点
バグなどでデータが壊れてしまった場合に遅延予定時間を超えると戻せなくなる。
バックアップは必ず取るようにすること。
この記事へのコメントはありません。