« 「DB構造の前にUIを決める」というアンチパターン | トップページ | アジャイルの人たちは自分の優秀さに気づいていない »

2011.08.10

古いデータの一括削除処理を設計する

 自作の開発用プラットフォームであるXEAD Driverには、基本設計ライブラリのひとつ「CONCEPTWARE/販売管理」の実装版がサンプルとして添付されている。「サンプル」と言っても本格的なシステムなので、XEAD Driverは「実行可能な仕様書」を実現した開発用プラットフォームであると同時に、堂々たる販売管理パッケージでもある。

 じつは「CONCEPTWARE/販売管理」上では記述されていてまだ実装されていない一群の機能が残っている。「パージ処理」、すなわち古いトランザクションデータの一括削除処理である。これが近日公開版で付加されるので、モデルの実装がようやく完了する。

 システムを長期間使っていると大量のデータが溜まってくる。その影響でレスポンスも悪くなる。どこかのタイミングで古いデータを捨ててデータサイズを圧縮する必要がある。「パージ処理」は、古いトランザクションデータを一挙に削除するための、地味だが運用上重要な処理だ。本番環境にはふつうは数年前までのトランザクションデータが残っていればじゅうぶんで、それよりも過去のデータに関してはバックアップされたほうのデータベースを適宜開くようにすればよい。

 素朴な疑問として、通常の機能を使ってこまめに削除すればよいのではないかと思われるかもしれないが、それではうまくいかない。たとえば後述する「出荷売上明細」の古いデータを、もう要らないからといって通常のユーザ機能を使って削除すると「赤伝処理」が起こる。つまり、その取引が計上した分の売上がなかったかのような残高更新が起きてしまう(注)。これを避けるために、削除に際して「もう不要だから削除」なのか「間違って登録したから削除」なのかを指定できるようにするやり方もあるのだが、ユーザはこの違いを案外区別できない。ゆえに、赤伝処理を起こさずに不要データを一括削除するための専用機能が必要になる。

 パージ処理をメニューから起動すると、確認ダイアログが開くので、ユーザ(システム管理者)が「パージ基準日付」を指定して実行ボタンを押す。この日付とトランザクションデータ上の日付を比較して削除処理がなされるわけだが、そのロジックは意外とややこしい。
Zu0_110810 削除されるべきデータは大別して「売上系」、「仕入系」、「受払系」、「セッションログ系」の4種類(前三者については重なる部分もある)。ここでは「売上系」だけを取り上げるが、他のものについても同様な事情があると考えてもらっていいい。まずはデータモデルを見てほしい。

Zu1_110810

 売上系データといってもいろいろあって、この図では省略されているが受注や請求関連のテーブルも含まれる。それらも処理対象になるが、最終目標は、基準日より古い「売上日」を持つ「売上実績」のレコードを削除することだ。

 ところが、モデルにあるように、売上実績はさまざまなテーブル(受領明細、出荷売上明細、売上振替、特殊売上)と関連している。すべての売上関連取引を抽象化したデータが、売上実績テーブルには記録されるためだ。たとえば取引区分が"出荷返品"であれば、「特殊売上テーブル」上の特定レコードが「売上の元ネタ」として参照されるようになっている。取引区分が"出荷売上"であれば、その「売上の元ネタ」は「出荷売上明細テーブル」上に存在することになる。これらのテーブル上に有効データが存在する状態で、それを「売上の元ネタ」として参照する売上実績データを削除すれば、データベースとしての整合性が失われてしまう。

 したがって、正しい削除手順としては、

1.売上系テーブルについて、基準日よりも古いレコードを削除する
2.売上実績テーブルについて、基準日よりも古いレコードを削除する

となりそうだ。「特殊売上」のように単体テーブルで完結している取引ばかりであれば、これで問題ない。ところが「出荷売上明細」についてはこう簡単にはいかない。次のモデルを見てほしい。

Zu2_110810

 このように、出荷売上明細は他のテーブルと複雑な関連をなしている。出荷売上明細だけを眺めて設計すれば、他のテーブル上のデータとの整合性が失われる破壊的パージ処理が開発されてしまう。モデルの広がりをしっかり眺めることで、削除手順は次のように設計される。

1.出荷見出しについて、出荷日(売上計上日)が基準日よりも古くかつ「出荷完了」であるようなレコードを検索し、これに関連する出荷明細レコードを出荷売上明細とともに削除する。当該の出荷見出しレコードも削除する
2.基準日よりも古い受注日を持つ受注見出しを検索し、子である受注明細について、関連する出荷明細がゼロ件であればこれを削除する。結果的に受注明細が0件となれば、当該の受注見出しについても削除する。

 なにやらややこしいが、重要な点は、基準日よりも古いとみなされる出荷売上明細レコードであっても、理屈の上では必ずしも削除されるわけではないという点だ。したがって、前掲の売上実績の削除手順は次のように修正される。

1.売上系テーブルについて、基準日よりも古いレコードを(可能であれば)削除する
2.売上実績テーブルについて、基準日よりも古く、かつ「売上の元ネタ」が存在しないようなレコードを削除する

 つまり、パージ処理は「基準日よりも古いデータであればとにかく削除する」といった単純強引な処理ではなく、「基準日よりも古いデータが削除可能とみなせるのであれば削除する」という配慮に満ちた処理として設計されなければならない。そして、パージ処理を適切に設計するためにもデータモデルが必要なのは言うまでもない。

注.そもそも、古いデータを削除しようとすれば「当年度の売上処理としては認められない」という意味のエラーが出て削除は許可されないのがふつうではある。

|

« 「DB構造の前にUIを決める」というアンチパターン | トップページ | アジャイルの人たちは自分の優秀さに気づいていない »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: 古いデータの一括削除処理を設計する:

« 「DB構造の前にUIを決める」というアンチパターン | トップページ | アジャイルの人たちは自分の優秀さに気づいていない »