MySQL データは「縦持ち」「横持ち」どっちがいいの?

MySQL データは「縦持ち」「横持ち」どっちがいいの?

MySQL データは「縦持ち」「横持ち」どっちがいいの?

今入っている現場で、私は上流工程から関わって動いています。

そんな中、議論になった事案があったのでメモしておこうと思います。

議題はタイトルの通り【縦持ちVS横持ち】です。

今回の(仮)想定環境

  • データベース:MySQL
  • フレームワーク:Laravel(ログイン機能付き)
  • 1ユーザーに関連する情報として、約200のカラムが存在する
  • 200のカラムを全て使うわけではなく使わない時はNullとして出力すれば良い
  • ただし表示部(Vue.js)でNull判定に基づく表示要素の変更が必要となる(要は無い奴は出さない)

縦持ち論者の主張

私は縦持ち論者なので、主だっては私の主張です。

今回の「1ユーザーに対して約200のカラムがぶら下る構成」&「Nullがある」という状況はレコードの中にNULLが大量発生する可能性があります。これって「正規化」という視点で見た時どうなの?と大いに疑問ですよね。

NULLはできるだけ存在させない。
そして、同じ値は可能な限り登録しない。

そう考えると、1つのテーブルにカラム数200なんてありえない。
新規にカラムを追加したくなった場合、簡単にできないので修正工数増えますよ?

と主張するのですが、横持ち論者は次のように反論します。

横持ち論者の主張

  • 縦持ちにするとレコードの取り出しが大変(だから横持ちがいい)
  • 縦持ちにするといくつものテーブルができる。テーブル数は少ない方がいい(混乱しない)
  • NULLがあっても、NULLを認識して処理すれば良いのであって正規化よりも作業性を重視すべき
  • 縦持ちはレコード取得した後の処理をしないとVue側で使い物にならない。
  • 最整形する縦持ちと、取得したレコードをそのまま使える横持ちでは、横持ちの方が処理時間が短くてすむ。

言いたいことの理解できるところも理解できないところも混在している感じです。

議論の感想と落とし所

縦持ちは速度を言われると痛いのは確かに。
でもさ、要は常用利用とそれ以外を分けてDB設計すれば良いのでは?

ということで、DBの構成を横持ち派にだいぶ妥協して次のようにしました。

  • ログイン関連の情報は独立したテーブルで用意する
  • ユーザーの基本情報(氏名などの必須項目)は横持ちテーブルとしてログインユーザーに紐付けて管理
  • その他の値は縦持ち化。縦持ち用のカラム名テーブルはもちろん用意してカラム名にテキストは利用しない。

こんな感じで4テーブル構成。
果たしてよかったのか悪かったのか。

まとめ

個人的には、DBは縦持ちであるべきだと思っています。
でも、現場をコントロールする企画側にDB設計のできる人が揃っているとは限りません。
そのため、DBの議論がエクセルベースに置き換わってしまう事が多々あります。
ここら辺は上手に立ち回って、喧嘩腰にならずに構成を詰めていきたいものです。

う〜ん、どうすっかなぁ(悩)