既存プロダクトのDB設計を安全に見直す進め方
「このカラム、結局何のために使ってるんでしたっけ」——既存プロダクトのコードを見せてもらうと、こう聞き返す場面がよくあります。リリース当初はシンプルだったテーブルに、機能追加のたびにカラムが継ぎ足され、気づけば1つのカラムが複数の意味を兼用していたり、本来は別テーブルに分けるべきデータが同居していたりする。担当した開発者もすでにおらず、「なぜこうなっているか」が誰にも分からない状態です。
これは怠慢の結果というより、動くものを止めずに機能を足し続けた自然な帰結です。問題は、この状態を放置すると機能追加のたびに「このカラムを増やしたら整合性が壊れないか」を毎回不安に思いながらリリースすることになる点にあります。この記事では、既存のDB設計をいきなり作り直さずに、段階的かつ安全に立て直す進め方を整理します。
破綻の兆候をまず見極める
「うちのDBは大丈夫か」を判断する前に、よくある兆候を確認します。
- 1テーブルに数十カラム:
usersテーブルに請求情報・通知設定・権限フラグ・分析用の集計値まで全部乗っている。本来別ドメインのデータが1テーブルに詰め込まれている状態 - 同じカラムが意味を使い分けている:
statusカラムが機能追加のたびに値の意味を増やし、コード中にif status == 3 && type == "old"のような分岐が散在する - JSON/JSONBへの逃げすぎ: 構造化して正規のカラムにすべきデータまで
metadataのようなJSONBカラムに詰め込み、検索・集計のたびにアプリ側で無理な処理をしている - 正規化と非正規化が場当たり的に混在: あるテーブルは律儀に正規化されているのに、隣のテーブルは検索を楽にするためだけに冗長に複製されていて、更新時にどちらが正か分からない
- 外部キー制約がない、または一部だけある: 「アプリ側で担保しているはず」の整合性が、実際には壊れたレコードとして残っている
これらは単独では致命傷になりませんが、複数重なると「機能追加のたびに謎のバグが出る」「新しいメンバーがオンボーディングできない」状態に進みます。心当たりが3つ以上あれば、着手のタイミングです。判断に迷う場合は既存プロダクト改善の最初の確認観点も参考にしてください。
いきなり作り直さない理由
「もう限界だから全部作り直そう」という判断は、多くの場合リスクを増やします。理由は次の3つです。
- 仕様の暗黙知が失われる: 歪んだテーブル設計の裏には、過去の障害対応や例外対応の跡が残っていることが多く、作り直すとその知見ごと失われる
- 停止できない: 稼働中のプロダクトは、移行期間中もデータを受け続ける。一括で切り替える「ビッグバンリリース」は、失敗したときの影響範囲が大きすぎる
- 検証コストが跳ね上がる: 全テーブルを作り直すと、既存の全機能を回帰テストし直す必要があり、期間もコストも見積もりづらくなる
作り直すべきかどうかの判断軸は改修とリプレイスの見極め方で詳しく扱っていますが、DB設計に限って言えば「部分的にテーブルを切り出す・分割する」段階的なアプローチで解決できるケースが大半です。
段階的に直す進め方
1. 新旧のテーブル構造を並存させる
まず新しいテーブル構造を追加し、既存のテーブルは残したまま並行稼働させます。いきなり古いテーブルを消さないのがポイントです。
2. 二重書き込み期間を設ける
アプリケーションから書き込む際、旧テーブルと新テーブルの両方に書き込む期間を設けます。読み取りはまだ旧テーブルから行い、新テーブル側は「正しくデータが溜まっているか」を検証する期間として使います。
- 書き込み処理はトランザクションで一貫性を保つ
- 新テーブルへの書き込み失敗が旧テーブルへの書き込みを巻き込んで失敗させないよう、エラーハンドリングを分離する
- 一定期間、バッチ処理で新旧テーブルのデータ突合(整合性チェック)を回す
3. 読み取りを新テーブルに切り替える
突合で問題がないことを確認できたら、読み取り経路を新テーブルに切り替えます。ここも一気に全機能を切り替えるのではなく、影響の小さい機能から順に切り替え、問題があればすぐ旧経路に戻せる状態を保ちます。
4. 旧テーブル・旧カラムを削除する
新経路で一定期間(目安は本番トラフィックの1〜2サイクル分)安定稼働したことを確認してから、旧テーブルやカラムを削除します。ここで焦って早期に消すと、切り戻しの選択肢を失います。
リスクの高いDB変更を安全に進める工夫
- マイグレーションはロックを意識する: 大きなテーブルへの
NOT NULL制約追加やカラム型変更は、テーブル全体をロックし本番トラフィックを止めることがある。PostgreSQLではNOT VALID制約やCONCURRENTLY付きインデックス作成など、ロックを避ける手法を優先する - 本番相当のデータ量でリハーサルする: 開発環境の小さいデータでは一瞬で終わるマイグレーションが、本番の数百万行では数十分かかることがある。事前に本番相当のデータ量でリハーサルし、所要時間を実測する
- ロールバック手順を先に書く: マイグレーションを書く前に「戻すマイグレーション」も一緒に書く。順方向しか用意しないと、本番で異常が出たときに戻す手段がない
- 段階を小さく刻む: 「カラム追加」「二重書き込み開始」「読み取り切り替え」「旧カラム削除」を1つのデプロイにまとめない。1段階ずつ分けて、各段階で異常がないか確認してから次に進む
外注する場合に確認すべきこと
DB設計の見直しを外部チームに依頼する際は、次の点を発注前に確認しておくと安心です。
- 段階的な移行計画を出せるか: 「作り直します」だけの提案ではなく、上記のような無停止での移行手順を具体的に説明できるか
- 既存データの意味を先に調査するか: いきなり設計から入るのではなく、既存カラムの実際の値やコードでの参照箇所を洗い出す工程があるか
- ロールバック手順とリハーサル計画があるか: 本番相当データでのリハーサルや、切り戻し手順が計画に含まれているか
- 業務影響への理解があるか: 「DBをきれいにすること」自体が目的化していないか。ビジネス上どの機能が止められないかを踏まえた優先順位付けがされているか
技術的な正しさだけでなく、こうした進め方の丁寧さが、既存プロダクトの改善案件では品質を大きく左右します。私たちが対応する技術スタックの詳細はデータベース関連の技術ページに、進め方全体はモダナイゼーション支援サービスにまとめています。
まとめ
- DB設計の歪みは「1テーブルに数十カラム」「同カラムの意味の使い分け」「JSONへの逃げすぎ」など具体的な兆候で見極められる
- いきなり作り直さず、新旧テーブルの並存・二重書き込み・段階的な読み取り切り替えで無停止のまま立て直す
- リスクの高いマイグレーションはロック回避・本番相当データでのリハーサル・ロールバック手順の準備で安全に進める
継ぎ足しで歪んだDB構造に不安を感じている、あるいは機能追加のたびにヒヤヒヤしているという方は、まず現状の診断から始めることをおすすめします。torcheeesでは既存プロダクト改善の診断と、継続的な改善支援を提供しています。まずはお問い合わせフォームから現状を聞かせてください。