無趣味の戯言

⏱️

変更履歴って意外と難しいかもしれない

こんにちは。だいちゃんです。

ひょんなことから社内で利用するシステムを開発することになり、始めてDjangoを使っているのですが、そもそもデータベース使う系の「The・Webシステム」を開発したことがないので、テーブル設計に特に苦戦しています。(裏を返すと、Djangoは分かりやすくてすんなり使い始められた)

kintoneのサポートしていた経験も活きて、なんとなくこんな感じがよさそうってのは分かるんだけど、リレーショナルデータベースのお作法を分かっていないので遠回りしている気もする。

特に、変更履歴に悩んでるので、結果は見えてないけど自分の勉強のために調べたものをメモしておきます。

最初に考えた案

前提として、変更であってもレコードは「追加」していく。

そして is_active (Boolean) カラムを持たせて、デフォルトは True にしておきつつ、変更があった際に変更前のレコードを is_active=False にする運用。

そうすれば、現在の値だけを表示したいときは is_active=True でフィルターすればいける。

問題点は、1. データ更新時に必ず継承元のレコードを is_active=False に更新しなきゃいけない点と、2. パッと見で変更なのか、追加なのかがわからない点。3. 変更箇所がわからないのも問題。

改善案

更新時に注意すべき点が多い=正規の方法以外で更新されると整合性が取れなくなる問題を解決するか、取得時の負荷を上げる=取得時に全データを調べて現在有効なレコードを探し出すか、のトレードオフになるかな、というのが現状の自分なりの答え。

となると、作ってるシステムの特性からして、閲覧のほうが回数多いし、Djangoの機能を使ってそのテーブルだけは管理画面を閲覧専用にしちゃえば、正規のフローを逸脱する更新方法をほぼ塞げると思ったので、現状案をそのまま採用。

正規の更新フローとしては、更新用APIを用意してるんだけど、さらに「変更種別」カラムを追加して、API側で以下の機能を実装することで対処しようかなと画策中。

  • 「変更元のレコードID」と「変更後の入力情報」を受け取る
  • 「変更元のレコードID」が空の場合:「変更種別」カラムに「新規」を入力してレコード追加。
  • 「変更元のレコードID」が1以上の場合:「変更種別」カラムに「新規」を入力してレコード追加。「変更元のレコード」の is_active=False を行う

相変わらず変更箇所まではわからないけど、一旦はそのまま行こうかな、と思ってます。というのも、変更箇所まで調べ上げるとAPI側の実装が複雑になるので、カラム追加時のコーディング難易度が高くなるため。まだ仕様が固まりきってないので、カラムの増減には柔軟に対応したく、いまは細部まで作り込まなくていいかなーという判断です。


素人なりの考えなので、考えが甘いかもですので、ご指摘もお待ちしてます。。。


参考記事

Buy Me A Coffee