DB設計の重要性。後から失敗したと思わないために。

目次アイコン目次
  • 🚀 コードの保守性には気を遣うけど、DB設計は?
  • ⚠️ コードは変えられるが、DBは変えにくい
  • 📈 スケールしやすい構造を最初から考える
  • 🎯 正規化:「無駄を省くこと」
  • 🔍 本当に必要な要件かを考える
  • 🌟 まとめ

🚀 コードの保守性には気を遣うけど、DB設計は?

開発をしていると、「コードの保守性」というキーワードをよく聞きます。

リファクタリングの重要性、可読性の向上、設計パターンの適用など、コード品質に関しては多くの開発者が意識を向けています。

DB設計はどうでしょうか?

今回は、なぜDB設計が重要なのか、そして実際にどう取り組めばよいのかを整理してみました。

⚠️ コードは変えられるが、DBは変えにくい

🔄 コードはリファクタリングできる

# ❌ 修正前:読みにくいコード
def calc(a, b, c)
  if a > 0
    return a * b + c
  else
    return 0
  end
end

# ✅ 修正後:読みやすいコード
def calculate_total_price(quantity, unit_price, tax)
  return 0 if quantity <= 0

  quantity * unit_price + tax
end

コードの場合、このようにリファクタリングという形で後から改善できます。変数名を変更したり、関数を分割したり、設計パターンを適用したりと、運用中でも比較的安全に修正が可能です。

🗄️ DBは運用開始後の変更が困難

一方で、DB設計は運用が始まってから変更するのは結構難しいんです。

-- ❌ 後から気づいた問題のあるテーブル設計
CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(255),
  email VARCHAR(255),
  address TEXT  -- 住所を1つのフィールドに格納
);

-- ✅ 理想的だった設計
CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(255),
  email VARCHAR(255)
);

CREATE TABLE addresses (
  id INT PRIMARY KEY,
  user_id INT,
  prefecture VARCHAR(50),
  city VARCHAR(100),
  street VARCHAR(255),
  postal_code VARCHAR(10),
  FOREIGN KEY (user_id) REFERENCES users(id)
);

上記の例で、運用開始後に住所の検索機能が必要になった場合、都道府県別の集計が必要になった場合など、既存のデータがある状態でのテーブル構造変更は:

  • データ移行が必要
  • ダウンタイムが発生する可能性
  • アプリケーションコードの大幅な修正が必要
  • バックアップとロールバック計画が必須

📈 スケールしやすい構造を最初から考える

💡 要件からテーブル・カラム設計を考える

DB設計では、しっかりと要件から何をテーブルとして、何をカラムとして持つのかを考える必要があります。

-- 🤔 これで本当に十分?
CREATE TABLE products (
  id INT PRIMARY KEY,
  name VARCHAR(255),
  price DECIMAL(10,2),
  category VARCHAR(100)
);

-- 🎯 将来を見据えた設計
CREATE TABLE categories (
  id INT PRIMARY KEY,
  name VARCHAR(100),
  parent_id INT,
  FOREIGN KEY (parent_id) REFERENCES categories(id)
);

CREATE TABLE products (
  id INT PRIMARY KEY,
  name VARCHAR(255),
  description TEXT,
  category_id INT,
  created_at TIMESTAMP,
  updated_at TIMESTAMP,
  FOREIGN KEY (category_id) REFERENCES categories(id)
);

CREATE TABLE product_prices (
  id INT PRIMARY KEY,
  product_id INT,
  price DECIMAL(10,2),
  effective_from DATE,
  effective_to DATE,
  FOREIGN KEY (product_id) REFERENCES products(id)
);

この設計により:
- カテゴリの階層構造に対応
- 価格履歴の管理が可能
- 将来的な拡張に対応しやすい

🎯 正規化:「無駄を省くこと」

正規化は難しくない

よく言われるのは正規化ですが、一言でいえば「無駄を省くこと」です。何も難しいことではなく、無駄や重複、論理破綻が起きないように設計していけばよいのです。

-- ❌ 非正規化:データの重複と不整合のリスク
CREATE TABLE orders (
  id INT PRIMARY KEY,
  customer_name VARCHAR(255),
  customer_email VARCHAR(255),
  customer_address TEXT,
  product_name VARCHAR(255),
  product_price DECIMAL(10,2),
  quantity INT
);

-- ✅ 正規化:データの重複を排除
CREATE TABLE customers (
  id INT PRIMARY KEY,
  name VARCHAR(255),
  email VARCHAR(255),
  address TEXT
);

CREATE TABLE products (
  id INT PRIMARY KEY,
  name VARCHAR(255),
  price DECIMAL(10,2)
);

CREATE TABLE orders (
  id INT PRIMARY KEY,
  customer_id INT,
  order_date DATE,
  FOREIGN KEY (customer_id) REFERENCES customers(id)
);

CREATE TABLE order_items (
  id INT PRIMARY KEY,
  order_id INT,
  product_id INT,
  quantity INT,
  FOREIGN KEY (order_id) REFERENCES orders(id),
  FOREIGN KEY (product_id) REFERENCES products(id)
);

正規化のメリット

  • データの不整合を防ぐ
  • ストレージの効率化
  • 更新処理の単純化
  • データの整合性担保

🔍 本当に必要な要件かを考える

無駄を作らないために

無駄を作らないためにも、本当に必要な要件なのかをしっかり考えることが大切です。

-- ❌ 「念のため」で追加したフィールド
CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(255),
  email VARCHAR(255),
  phone VARCHAR(20),
  fax VARCHAR(20),        -- 本当に必要?
  blood_type VARCHAR(5),  -- 本当に必要?
  hobby TEXT,            -- 本当に必要?
  memo TEXT              -- 何のためのメモ?
);

-- ✅ 必要最小限から始める
CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  email VARCHAR(255) NOT NULL UNIQUE,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

🎯 要件整理のポイント

  1. 現在の必須要件を明確にする
  2. 将来の拡張可能性を考慮する
  3. 「念のため」フィールドは避ける
  4. 実際の使用パターンを想定する

🌟 まとめ

DB設計は、一度決めてしまうと後から変更するのが非常に困難です。だからこそ、最初の設計段階でしっかりと検討することが重要。

🎯 DB設計で意識すべきポイント

  • ✅ 要件を深く理解する
  • ✅ 正規化で無駄と重複を排除する
  • ✅ 将来のスケールを考慮する
  • ✅ 本当に必要な機能だけを実装する
  • ✅ データの整合性を保つ仕組みを作る

コードのリファクタリングと同じように、DB設計にも時間と労力を投資することで、長期的に保守しやすく、スケールしやすいシステムを構築できます。

皆さんも、次のプロジェクトではDB設計により多くの時間を割いて、後から「あの時ちゃんと設計しておけばよかった...」と後悔しないような設計を心がけてみてください!

🚀 良いDB設計で、より良いアプリケーション開発を!