正規化だけが正解ではない


はじめに

こんにちは、毎川です!

業務でデータ設計について考える中で、このデータ構造で本当に良いのかと迷うことがあります。
その際に判断材料の一つになるのがデータベースの正規化です。

座学では正規化することが正解だと勝手に理解していましたが、
実務でシフト周りのデータを扱う中で、それだけでは決まらない事に気がつきました。

本記事で皆さんにも共有したいと思います!


目次

  • 類似データでも設計が違う!
  • 2つのデータ構造比較
  • 正規化の視点から見ると…
  • ただし正規化すれば正しいとは限らない
  • おわりに
  • 参考文献


類似データでも設計が違う!

業務でシフト管理に関するデータを扱う中で、同じように曜日ごとの勤務時間を管理しているにもかかわらず、
データの持ち方が異なることに気づきました。

一方は1つのレコードに全曜日の情報を持ち、もう一方は曜日ごとにレコードを分ける方法です。


2つのデータ構造比較

A. 1つのレコードに全曜日の情報を持つ

idmontuewed…sun
1夕方休夕方…休

月〜日のカラムに、あらかじめ決まった勤務区分を入れる方法です。1週間分を1レコードで読み書きできます。

B. 曜日ごとにレコードを分ける

idshift_idweekdaystart_timeend_time
11mon17:0022:00
21wed17:0022:00

曜日ごとに開始・終了時間を持てます。1週間分を取得するときは複数レコードを扱います。


正規化の視点から見ると…

Aは、曜日ごとに同じ種類のカラムが並ぶ「繰り返しグループ」で、第一正規形に反する形です。
この形だと次のような困りごとが出ます。

  • 開始・終了時間を持たせたくなった場合、14カラムを追加するマイグレーションと、
    関連するコードの修正が必要になる
  • 「水曜日に勤務する人」のように曜日単位で検索・集計する場合、曜日ごとにカラムを指定する必要がある

Bは項目が増えても行が増えるだけで、曜日単位の検索・集計もしやすい構造です。


ただし正規化すれば正しいとは限らない

Aにも利点があります。例えば次のような利用シーンを考えてみてください。
あらかじめ用意された勤務パターンから選ぶ運用で、1週間分をまとめて取得・更新する場面がほとんど。
この場合1レコードで完結するAのほうが実装も画面もシンプルです。

構造を決める際は、正規化に加えて次の点を考える必要があります。

  • どの単位でデータを取得・更新するか
  • どんな検索や集計を行うか
  • 今後、管理する項目が増える可能性があるか
  • 実装・保守がしやすいか

これらは設計図を眺めるだけでは分からないため、ユーザーへのヒアリングが欠かせません。


おわりに

データ設計を再び行う機会があれば、今回の学びを活かしたいと思います。
正規化は、変更に強い設計かを考えるための優れた判断軸ですが、
答えを決めるのはあくまで利用目的だと学びました。


参考文献


現在デザイン・システム室では、新しいメンバーを募集しています。
少しでも興味を持たれた方は、ぜひご応募ください。
皆様からのご応募、心よりお待ちしております。