【データモデリング】論理テーブル設計のチュートリアル

データモデリングにおいて、エンティティ抽出とER図の作成が完了したら、次のステップとして論理テーブル設計を行います。本記事では、ECサイトを題材にして論理テーブル設計の手順を詳しく解説します。
1. シナリオの確認
ECサイトにおける主要な機能を整理します。
- 商品一覧の表示
- カートへの追加・削除
- 注文処理
- 決済処理
この機能をもとに、エンティティ抽出とER図を作成しました。これを基に論理テーブル設計を進めます。
2. 論理テーブル設計の手順
2.1 テーブル定義(エンティティ → テーブル化)
エンティティをそのままテーブルとして定義し、データの構造を明確にします。多対多の関係がある場合は、中間テーブルを作成します。
2.2 主キー・外部キー・制約の設定
- 主キー(Primary Key, PK)
- サロゲートキー(自動採番IDなど)またはナチュラルキー(業務上意味を持つID)を選択
- 外部キー(Foreign Key, FK)
- リレーションの参照整合性を担保
- 制約(Constraints)
UNIQUE,CHECK,NOT NULLなどの制約を適用
2.3 正規化の徹底と非正規化判断
- 基本は 第3正規形(3NF)を適用
- 性能要件 に応じて部分的に非正規化
- 正規化のステップ
- 第1正規形(1NF): 繰り返し要素を排除し、各列に単一値のみを格納
- 第2正規形(2NF): 1NFを満たし、部分関数従属を排除(主キーに完全依存する)
- 第3正規形(3NF): 2NFを満たし、推移的関数従属を排除(主キー以外の列が他の非キー属性に依存しない)
2.4 論理レベルでのデータ型選定
- 製品依存を避け、抽象的なデータ型を選択
VARCHAR,INTEGER,DATE,DECIMALなど
3. 論理テーブル定義の例
3.1 User(ユーザー)
| カラム名 | データ型 | 制約 | 説明 |
|---|---|---|---|
| user_id | INTEGER | PK, 自動採番 | ユーザーの一意識別子 |
| username | VARCHAR(255) | NOT NULL | ユーザー名 |
| VARCHAR(255) | UNIQUE, NOT NULL | メールアドレス(ナチュラルキー) | |
| password | VARCHAR(255) | NOT NULL | パスワード |
3.2 Product(商品)
| カラム名 | データ型 | 制約 | 説明 |
|---|---|---|---|
| product_id | INTEGER | PK, 自動採番 | 商品の一意識別子 |
| product_code | VARCHAR(100) | UNIQUE, NOT NULL | 商品コード(ナチュラルキー) |
| name | VARCHAR(255) | NOT NULL | 商品名 |
| price | DECIMAL(10,2) | NOT NULL | 価格 |
| stock | INTEGER | NOT NULL | 在庫数 |
3.3 Cart(カート)
| カラム名 | データ型 | 制約 | 説明 |
|---|---|---|---|
| cart_id | INTEGER | PK, 自動採番 | カートの一意識別子 |
| user_id | INTEGER | FK (User) | カート所有者 |
| created_at | DATE | NOT NULL | カート作成日時 |
3.4 CartItem(カート内商品)
| カラム名 | データ型 | 制約 | 説明 |
|---|---|---|---|
| cart_id | INTEGER | PK, FK (Cart) | カートの識別子 |
| product_id | INTEGER | PK, FK (Product) | カート内の商品 |
| quantity | INTEGER | NOT NULL | 商品の個数 |
3.5 Order(注文)
| カラム名 | データ型 | 制約 | 説明 |
|---|---|---|---|
| order_id | INTEGER | PK, 自動採番 | 注文の一意識別子 |
| user_id | INTEGER | FK (User) | 注文したユーザー |
| total_price | DECIMAL(10,2) | NOT NULL | 合計金額 |
| status | VARCHAR(50) | NOT NULL | 注文ステータス(例: 確定, 発送済み) |
| order_date | DATE | NOT NULL | 注文日時 |
3.6 OrderItem(注文内商品)
| カラム名 | データ型 | 制約 | 説明 |
|---|---|---|---|
| order_id | INTEGER | PK, FK (Order) | 注文の識別子 |
| product_id | INTEGER | PK, FK (Product) | 注文内の商品 |
| quantity | INTEGER | NOT NULL | 商品の個数 |
3.7 Payment(決済)
| カラム名 | データ型 | 制約 | 説明 |
|---|---|---|---|
| payment_id | INTEGER | PK, 自動採番 | 決済の一意識別子 |
| order_id | INTEGER | FK (Order) | 関連する注文 |
| method | VARCHAR(50) | NOT NULL | 決済方法(クレジットカード, 銀行振込など) |
| status | VARCHAR(50) | NOT NULL | 決済ステータス(成功, 失敗など) |
| payment_date | DATE | NOT NULL | 決済日時 |
3. 論理テーブル設計後のER図
以下のER図は、論理テーブル設計を反映したものです。
erDiagram User { INTEGER user_id VARCHAR username VARCHAR email VARCHAR password } Product { INTEGER product_id VARCHAR product_code VARCHAR name DECIMAL price INTEGER stock } Cart { INTEGER cart_id INTEGER user_id DATE created_at } CartItem { INTEGER cart_id INTEGER product_id INTEGER quantity } Order { INTEGER order_id INTEGER user_id DECIMAL total_price VARCHAR status DATE order_date } OrderItem { INTEGER order_id INTEGER product_id INTEGER quantity } Payment { INTEGER payment_id INTEGER order_id VARCHAR method VARCHAR status DATE payment_date } User ||--o{ Cart : owns User ||--o{ Order : places Cart ||--o{ CartItem : contains CartItem ||--|| Product : includes Order ||--o{ OrderItem : contains OrderItem ||--|| Product : includes Order ||--o{ Payment : processes
4. まとめ
本記事では、ECサイトを題材に論理テーブル設計の手順を解説しました。
- エンティティをテーブル化し、リレーションを定義
- 主キー・外部キー・制約を適切に設定
- 第3正規形を基本にしつつ、性能要件に応じて非正規化を検討
- 正規化の基本概念(1NF, 2NF, 3NF)を説明
- 抽象的なデータ型を選定し、製品依存を避ける
- ER図で論理テーブルの構造を視覚化
この設計をもとに、次は物理データベース設計を進め、最適なインデックスやパーティショニングの適用を検討していきましょう!
この記事をシェアする
合同会社raisexでは一緒に働く仲間を募集中です。
ご興味のある方は以下の採用情報をご確認ください。