販売とは別に出荷管理をしているという前提では、データの保持だけはなく、出荷残数を求める方法も確立しておかないといけないということで、前回は銀行口座方式を紹介しました。もちろん、それはそれでうまく行くでしょうけど、データ編集にロジックが絡む点が、複雑さを発生させることも紹介しました。今回は、この応用で、一定期間ごとに残数のキャッシュを作る方法を紹介しましょう。前回の手法の応用なのですが、いくつか利点が増えます。
早速スキーマと、表を示します。スキーマの基本的な形は前回と同じです。顧客と商品に紐づいた受注出荷集計という新たな表が加わりました。初期状態はレコードなしです。ここでは1つの期を1ヶ月とします。1ヶ月に納品書2枚ということはないでしょうけど、考えやすくするために小規模にデータ発生を考えます。2枚の納品書、3回の出荷予定があった場合、その気の受注数、出荷数、そしてここでは出荷残数もフィールドに求めています。
![](https://blog.msyk.net/wp-content/uploads/2022/05/blog_figs-20-1-1005x1024.png)
この状態で次の月になって、新たに納品書と出荷が作られ、月末になって集計するとします。とりあえず、受注出荷集計には、月末にレコードを追加する、つまり、期ごと、商品ごと、顧客ごと、という3つの分類軸で受注数、出荷数、出荷残を求めることにします。
![](https://blog.msyk.net/wp-content/uploads/2022/05/blog_figs-20-2-1024x739.png)
こうなると、例えば、12月の途中では、11月までの集計結果を受注出荷集計から取り出し、12月1日以降の納品書、出荷予定の明細分の増減を行うことで、ある時点での出荷残が得られます。当初は出荷残を求めるために、明細をデータの蓄積を始めた最初の段階からチェックすることになってしまいましたが、期を決めて、期末以降をチェックすれば良いという方法であれば、データが増えてもその月のデータを舐めるだけで済むのので、年々線形的にパフォーマンスが悪くなることもまずはないと思われます。ただ、SQLのビュー等で残数を得られるようにすることになるでしょうけど、ビューの定義はちょっと込み入りそうです。
そして、銀行口座の残高のように、明細が発生するたびに残高を更新する方法だと、競合の問題や、ロジックを実施しないとデータが正しくなくなるなどの問題がありましたが、この方法だと、販売明細や出荷明細を作る上での追加のロジックはなく、いずれもレコードを作るだけで処理対象に加わります。もちろん、帳票を作成途中の場合はどうするというワークフローに関わる問題はありますが、編集に関わるロジックはかなりシンプルです。お客さんが勝手にレイアウトを作っても、きちんと出荷残の計算には明細が絡んでくるでしょう。
受注出荷集計のレコード追加は、期末あるいは期首に、バッチ処理を動かすことになります。もちろん、バッチ処理が正しく動くこと、そして、バッチ処理が失敗した時の対処など、バッチ処理の開発は大変ですが、ともかく、利用者が簡単にさわれないところにロジックがあるのはある意味、開発側からすると管理しやすいとも言えます。
受注出荷集計が多数のレコードになって重くないかという心配もあるかもしれませんが、過去に渡ってデータを舐めることはないので、あまり心配はいりません。どうしても心配なら、最新の期のデータ以外は削除するという方針でもいいでしょう。現状の出荷残を求めるということだけのためなら、過去の期のデータは不要になります。
棚卸し調整は、バッチ処理を動かした直後に、フィールド値を手作業で直すというのが1つの方法です。棚卸しについては、前回と手法的には同じになります。なお、期は一定である方がいいかもしれませんが、仕組み上は受注出荷集計のレコードは、気が向いた時に作ってもいいくらいのものです。要するに、明細の全部を舐めることを避けるための手法ということになります。
前回の「受注出荷数」は、出荷残のフィールドがなく、計算で求めることにしました。しかしながら、今回の「受注出荷集計」には出荷残フィールドがあります。これも、それぞれのロジックを作るときに「おそらくこう考えるだろうな」という意図が込められています。前回の銀行口座方式の場合、直接に出荷残のフィールドを増減する方法も考えられるのですが、競合する確率が上がることなどがあるので、増と減をそれぞれ別々のフィールドにしておきました。一方、今回の場合はバッチ処理で求めているので、残数はバッチ処理内で簡単に求められます。結果、残数が必要なので、それをフィールドとして置いておき、むしろ受注数や出荷数は不要になります。ですが、説明上ややこしくなるので、受注数と出荷数のフィールドは置いておきました。変に細かく考えているとも言えるかもしれませんが、残数の出所の違いでこうした変化が発生しうるということでもあります。
この方法は、期の概念の導入と、バッチ処理などのロジックの発生をどう評価するかです。ロジックは発生しますが、銀行口座方式のように、単一のフィールドを複数のユーザで更新するような仕組みよりも、バラバラにレコードを作っておいて必要な時に集計する方が、システムの動作上は安定することが期待できます。どちらが良いのかという問題は、実際の要求に照らし合わせないと結論は出ませんが、少なくとも、いろいろな実現方法があることは考慮すべきでしょう。
ということで、一旦、あるロボットおもちゃメーカーを題材にしたシリーズはここまでとします。しばらくは、データベースを理解するのに必要な概念を深掘りしていこうと思います。更新頻度は落ちるかな〜