95307


Webアプリケーションで機能追加に伴い、RDB（拘りはないですが一旦MySQL）の既存のテーブルに新しい情報を持たせたいとします。  
その時に、既存のテーブルにカラムを追加するか、それとも既存のテーブルと1対1の関係でテーブルを追加するかの判断基準を知りたいです。

例えば、ブログアプリでブログ記事に対応するpostsテーブルがあり、予約投稿ができる機能を追加するとします。  
この時、以下の選択肢があり、それぞれメリット・デメリットがあると思います。

  1. postsテーブルに予約投稿日時のscheduled_atカラムを追加する
  2. postsテーブルと1対1の関係のpost_schedulesテーブルを作成する 
    * post_schedulesテーブルはpost_id, scheduled_atカラムを持つ

思いついたものでは、以下の2点です。

  * カラム追加はテーブルのロックが伴うため、既にpostsテーブルに大量のレコードがあってロックが長時間になる場合はユーザ影響を考慮すべき。
  * scheduled_atは値がない（予約投稿をしない場合）ことがあるため、NULLになりうるカラム追加ではなくテーブル作成の方が良い 
    * NULL許容のカラムは作らない方がいい、という前提です（一般的な考えだと思っています）。

他に判断基準となる考え方はあるでしょうか？ご教示いただけますと幸いです。


CC BY-SA 4.0
2023-06-17T05:12:47.783
95273
2023-06-20T06:38:38.427
2023-06-17T06:36:16.203
3060
41605
question
mysql database データベース設計
RDBにおけるカラム追加と1対1でテーブル作成する判断基準について


すでにシステムが稼働している前提なので、実装上の都合で考えているようですが、本来の考え方としては  
予約投稿は投稿の一形態と考えるか、普通の投稿とは別物として考えるか  
じゃないでしょうか


CC BY-SA 4.0
2023-06-18T17:34:57.410
95286
2023-06-18T17:34:57.410
9811
95273
answer


ご質問の観点の通りの判断基準で、おおむね間違っていないと思います。

個人的な感覚では、稼働中のシステムを停止することなく作業するならば、従属テーブル作成一択です。  
もしもカラム追加作業が原因で本番環境のSQLがエラーになったり、ユーザの更新処理とカラム追加処理がぶつかってデッドロックで永遠に帰らぬSQLになったり、本番環境に限ってインデックスがうまく評価されずに既存のSQLが非常に遅くなったりするリスクを考えると、よほどテストやロールバックを含めた作業手順がしっかりしていない限り怖くてできません。  
(当然の感覚でブルーグリーンデプロイメントができる環境の方は「何言ってんの？」となるのでしょうけれど…)

上記のリスクのほかに付け加えるならば、下記の観点もあるでしょう。

  * レコードが 1..n に設計変更される可能性が低くないならば別テーブルが良い  
予約投稿が論理削除されて履歴を持つケースは少ないかもしれませんが、テーブルカラム追加した場合には拡張が面倒です。

  * 高速な検索が必要なカラムならば別テーブルにすべき  
アプリケーションサーバの投稿判定で1分ごとに予約投稿日時をチェックするならば、予約投稿日時カラムはNULLを含まずインデックスを効かせるべきです。  
そして投稿判定時に過去データは不要なので、定期バッチ処理で過去データを退避したくなるかもしれません。メインテーブル一つではこれらの対応ができません。

  * どう考えても従属しないカラムならばテーブルカラム追加が必要  
例えば`氏名`カラムがあって`氏名カナ`カラムがない時や、`社員番号`カラムを主キーにしていたけれど破綻して`ID`カラムを主キーとして作らなければいけない時はテーブルカラムを追加すべきです。


CC BY-SA 4.0
2023-06-20T06:38:38.427
95307
2023-06-20T06:38:38.427
9820
95273
answer