前のページ

RDB

事実の消失

例:EC サイト

  • 商品をカートに入れて発注するとカートテーブルに記録が残る
  • 売上テーブルの売上金額は設定テーブルの消費税率を下に計算する
  • 売上金額は発注した時点の消費税率を用いることとする
  • 2019 年内は消費税率 :0.05
  • 2020 年からは消費税率 0.08

購入処理

2020/01/01 時点

【商品テーブル】

商品 ID商品名価格
1失敗から学ぶ RDB の正しい歩きかた2500
2SQL アンチパターン2000

【設定テーブル】

設定 ID設定名
1消費税率0.08

【カートテーブル】

カート ID売上 ID商品 ID個数購入者
1112neko
2121neko
3213inu

【売上テーブル】

売上 ID売上金額売上日配送状態
173502019-12-31 23:00:00配送済
281002020-01-01 10:00:00発注中

この時売上テーブルを見てみると、売上 ID が 1 の売上金額は 2019 年内の発注により消費税率 0.05 で計算されていて、売上 ID が 2 の売上金額は 2020 年からの税率 0.08 で計算されている

払い戻し処理

ここで、2020/01/02 に売上 ID が 1 のうち、カート ID が 1 の商品が1つ分返品された場合についての払い戻し処理について考えることとする

売上 ID が 1 について注目してテーブルの更新部分を見てみる

【商品テーブル】

商品 ID商品名価格
1失敗から学ぶ RDB の正しい歩きかた2500
2SQL アンチパターン2000

【設定テーブル】

設定 ID設定名
1消費税率0.08

【カートテーブル】

カート ID売上 ID商品 ID個数購入者
1111neko
2121neko

【売上テーブル】

売上 ID売上金額売上日配送状態
148602019-12-31 23:00:00配送済

一見問題なさそうに思えるが、この売上金額 4166 は間違えている

なぜなら、消費税率は発注時点では 0.05 だったにもかかわらず、2020 年になってからの返品処理によって料金を再計算しようとすると 0.08 で計算しているからである

  • 2020 年内での計算
現在の売上テーブルの計算
(2500 + 2000) x 0.08 = 4860

払い戻し金額
7350 - 4860 = 2490
  • 2019 年内用の税率で計算
正しい計算は以下である
(2500 + 2000) x 0.05 = 4725

払い戻し金額
7350 - 4725 = 2625

実際のところ、消費税率 0.05 の時点で商品 ID が 1 の 2500 円の小計は 2625 円なので 2020 年内の計算が間違っていることがわかりますね

問題は何だったのか

消費税率の変更による払い戻し処理と、それ以外の問題点についても指摘する

  • 消費税率の履歴が全くわからない
  • 消費税率の作成日、更新日が分からないことで原因特定が難しい(見かけ上は消費税率は 0.08 で計算も間違っていないように思えるため)
  • 売上テーブルの配送状態は 発注中→キャンセル→再発注→配送済み のようになっていることが想定されるが、テーブル上では履歴が失われてしまう
  • カートテーブルの購入者が直書きされていて、もし名前を変更した場合にカート上の名称が誰なのかわかりにくくなる

どうすれば良かったのか

  • 設定テーブルに失効日を追加する
  • 売上テーブルに消費税率を追加する
  • 売上テーブルに配送状態が変わるごとにカラムを追加して、最新のものを有効であるとする

ただしデメリットも存在する

  • 履歴保存のためにカラム追加や行を追加する仕様にするとテーブルサイズが増えてしまう
  • テーブルサイズが肥大化した時に検索速度が劣化する(単純な主キーによる検索でなくなるため)

参考

失敗から学ぶ RDB の正しい歩き方

Licensed under CC BY-NC-SA 4.0
このページでは、Google Analyticsを利用しています。