STEP 2:エンティティとリレーションシップ

🎯 STEP 2: エンティティとリレーションシップ

データベース設計の基本!「モノ」と「関係」を理解しよう

📋 このステップで学ぶこと

  • エンティティ(実体)とは何か、どう見つけるか
  • 属性(カラム)の種類と特定方法
  • リレーションシップ(関係)の3つの種類
  • カーディナリティ(多重度)の考え方
  • 実際のシステムでエンティティを抽出する練習

前提知識: STEP 1修了

🎯 1. エンティティ(実体)とは?

エンティティの定義

エンティティ(Entity)とは、システムで管理したい「モノ」や「概念」のことです。データベースでは、エンティティがテーブルになります。

📝 一番シンプルな考え方:エンティティ=「名詞」

エンティティを見つけるとき、「名詞」に注目するとわかりやすいです。

例えば、図書館のシステムを考えてみましょう。

  • → これはエンティティ(管理したいモノ)
  • 会員 → これもエンティティ(管理したい人)
  • 貸出 → これもエンティティ(管理したい出来事)

このように、「システムで管理したい対象」を見つけることが、エンティティ抽出の第一歩です。

エンティティと認められる4つの条件

すべての名詞がエンティティになるわけではありません。以下の条件を満たす必要があります。

🎯 エンティティの4つの条件
条件 説明
① 複数存在する 1つだけでなく、複数の実例がある 本は何冊もある ✅
会社名は1つだけ ❌
② 一意に識別できる それぞれを区別できる方法がある 本にはISBN、会員にはID
③ 属性を持つ そのモノについての詳しい情報がある 本なら「タイトル」「著者」「出版日」
④ 業務上重要 システムで管理する必要がある 顧客は重要 ✅
天気予報は関係ない ❌

エンティティを見つける4つの質問

実際のシステムから、どうやってエンティティを見つければいいのでしょうか?以下の4つの質問を自分に問いかけてみましょう。

🔍 エンティティを見つける4つの質問

質問1: 「何を管理したいか?」

システムで記録・追跡したい対象は何ですか?
例:ECサイトなら「顧客」「商品」「注文」など

質問2: 「その情報は複数存在するか?」

1つだけではなく、複数のインスタンスがありますか?
「商品」は何個もある → ✅ エンティティ
「会社名」は1つだけ → ❌ エンティティではない(設定値として扱う)

質問3: 「それぞれを区別できるか?」

各インスタンスをユニークに識別できますか?
各商品にID、各顧客にIDで区別できる → ✅ エンティティ

質問4: 「詳しい情報を持っているか?」

そのモノについて、記録したい属性がありますか?
商品なら「名前」「価格」「在庫数」など → ✅ エンティティ

具体例:ブログシステムのエンティティ抽出

実際の要件からエンティティを抽出する例を見てみましょう。

【要件】

ブログシステムを作りたい。ユーザーが記事を投稿でき、他のユーザーがコメントできる。記事はカテゴリに分類される。

【エンティティの抽出プロセス】 要件を読んで、名詞を拾い出す: 「ユーザー」「記事」「コメント」「カテゴリ」 それぞれを4つの条件でチェック: 1. ユーザー(User) ✅ 複数のユーザーがいる ✅ ユーザーIDで識別可能 ✅ 名前やメールなどの属性を持つ ✅ 業務上、必ず管理が必要 → エンティティとして採用! 2. 記事(Post) ✅ 複数の記事がある ✅ 記事IDで識別可能 ✅ タイトルや本文などの属性を持つ ✅ ブログの核となる情報 → エンティティとして採用! 3. カテゴリ(Category) ✅ 複数のカテゴリがある(技術、日記、趣味など) ✅ カテゴリIDで識別可能 ✅ カテゴリ名などの属性を持つ ✅ 記事の分類に必要 → エンティティとして採用! 4. コメント(Comment) ✅ 複数のコメントがある ✅ コメントIDで識別可能 ✅ コメント本文、投稿日時などの属性を持つ ✅ ブログの重要な機能 → エンティティとして採用!
💡 エンティティ抽出のコツ

「このシステムで何を管理・記録したいのか?」を常に考えましょう。
名詞を見つけたら、4つの条件を当てはめてチェックすれば、エンティティかどうか判断できます。

📝 2. 属性(カラム)の特定方法

属性とは

属性(Attribute)とは、エンティティが持つ情報のことです。データベースでは、これがカラム(列)になります。

📝 身近な例で理解する

「名刺」を思い浮かべてください。名刺には以下の情報が書かれていますよね。

  • 会社名
  • 部署
  • 役職
  • 名前
  • 電話番号
  • メールアドレス

この「名刺に書かれている情報」が、データベースでいう属性です。「ユーザー」というエンティティなら、そのユーザーについてどんな情報を記録したいかを考えます。

属性の3つの種類

属性には、役割によって3つの種類があります。

🎯 属性の3分類

1. キー属性(識別子)

  • そのエンティティを一意に識別するための属性
  • 例:ユーザーID、商品ID、注文番号
  • これが主キー(Primary Key)になる
  • 必ず重複しない値を持つ

2. 記述属性

  • エンティティの特徴や状態を表す属性
  • 例:商品名、価格、在庫数、説明文、登録日
  • そのエンティティ固有の情報

3. 外部キー属性

  • 他のエンティティとの関係を表す属性
  • 例:注文テーブルの「顧客ID」(顧客テーブルを参照)
  • 別のテーブルの主キーを参照する

属性を見つけるチェックリスト

属性を漏れなく見つけるには、以下の観点でチェックすると効果的です。

💡 属性抽出の5W1Hチェックリスト
観点 質問 属性の例
Who/What 「誰が/何が」を表す属性は? 名前、タイトル、商品名
When 「いつ」を表す属性は? 登録日、更新日、注文日時
Where 「どこで」を表す属性は? 住所、場所、URL
How much 「いくら/いくつ」を表す属性は? 価格、数量、在庫数
状態 「どんな状態」を表す属性は? ステータス、有効/無効フラグ

具体例:商品エンティティの属性設計

ECサイトの「商品」エンティティを例に、属性を洗い出してみましょう。

商品(Product)エンティティの属性 【キー属性】 – product_id(商品ID) → 主キー、各商品を一意に識別するための番号 【記述属性】 – product_name(商品名) → 「何が」 – price(価格) → 「いくら」 – stock_quantity(在庫数) → 「いくつ」 – description(説明文) → 「どんな」 – image_url(画像URL) → 商品の見た目 – created_at(登録日) → 「いつ」登録されたか – updated_at(更新日) → 「いつ」更新されたか – is_active(販売中フラグ) → 「どんな状態」 【外部キー属性】 – category_id(カテゴリID) → カテゴリテーブルへの参照(どのカテゴリに属するか)

属性にしてはいけないもの

以下のようなものは、属性として定義すると問題が起きます。

⚠️ 属性にしてはいけない3つのパターン

❌ パターン1:計算可能な値

「合計金額」は「単価×数量」で計算できるので、属性にしない方がいい。

  • 理由:単価か数量が変わったとき、合計も更新しないと矛盾する
  • 解決:必要なときにSQLで計算する

❌ パターン2:複数の値を1つのカラムに入れる

「タグ」を「タグ1, タグ2, タグ3」のように1つの列に入れない。

  • 理由:検索が困難になる(第1正規形違反)
  • 解決:タグ用の別テーブルを作る

❌ パターン3:他のテーブルの情報を重複して持つ

「顧客名」を注文テーブルに持つと、顧客テーブルと重複する。

  • 理由:顧客名が変わったとき、両方更新が必要
  • 解決:顧客IDだけを持ち、必要なときにJOINで取得

🔗 3. リレーションシップ(関係)の種類

リレーションシップとは

リレーションシップ(Relationship)とは、エンティティ同士のつながりのことです。

📝 動詞で考える

リレーションシップは、エンティティ間を結ぶ「動詞」だと考えるとわかりやすいです。

  • 「会員」は「本」を借りる
  • 「顧客」は「商品」を注文する
  • 「社員」は「部署」に所属する

この「借りる」「注文する」「所属する」といった関係が、リレーションシップです。

リレーションシップの3つのタイプ

リレーションシップには、大きく分けて3つのタイプがあります。

1️⃣ 1対1(One-to-One)

1つのAは、1つのBにだけ対応する関係です。比較的珍しいパターンです。

例1:ユーザーとプロフィール詳細

  • 1人のユーザーは、1つのプロフィール詳細を持つ
  • 1つのプロフィール詳細は、1人のユーザーに属する

例2:国と首都

  • 1つの国は、1つの首都を持つ
  • 1つの首都は、1つの国に属する
【1対1の例:ユーザーとプロフィール詳細】 users(ユーザー) user_profiles(プロフィール詳細) —————— ————————– user_id(主キー) profile_id(主キー) username user_id(外部キー)→ usersを参照 email bio(自己紹介) avatar_url(アバター画像) なぜ分ける? → プロフィール詳細はオプションで、全員が持つわけではない → プロフィール詳細は滅多に使わないので、分けた方が効率的
2️⃣ 1対多(One-to-Many)

1つのAは、複数のBに対応する関係です。最も一般的なパターンです。

例1:顧客と注文

  • 1人の顧客は、複数の注文を行える
  • 1つの注文は、1人の顧客に属する

他の1対多の例:

  • 記事とコメント:1つの記事に、複数のコメント
  • 部署と社員:1つの部署に、複数の社員
  • カテゴリと商品:1つのカテゴリに、複数の商品
  • 著者と本:1人の著者が、複数の本を執筆
【1対多の例:顧客と注文】 customers(顧客) orders(注文) —————— ————————– customer_id(主キー) order_id(主キー) customer_name customer_id(外部キー)→ customersを参照 email order_date total_amount 「1」側のテーブルの主キーを、「多」側のテーブルが外部キーとして持つ
3️⃣ 多対多(Many-to-Many)

複数のAは、複数のBに対応する関係です。直接はテーブルで表現できません。

例1:学生と授業

  • 1人の学生は、複数の授業を履修する
  • 1つの授業は、複数の学生が履修する

他の多対多の例:

  • 商品とタグ:1つの商品に複数のタグ、1つのタグは複数の商品に
  • 医者と患者:1人の医者が複数の患者を診る、1人の患者が複数の医者に診てもらう
  • 俳優と映画:1人の俳優が複数の映画に出演、1つの映画に複数の俳優
【多対多の例:学生と授業】 students(学生) courses(授業) —————— ————————– student_id(主キー) course_id(主キー) student_name course_name この2つだけでは、誰がどの授業を履修しているかわからない! ↓ 中間テーブルを作って解決 enrollments(履修)← 中間テーブル —————— enrollment_id(主キー) student_id(外部キー)→ studentsを参照 course_id(外部キー)→ coursesを参照 enrolled_at(履修日)
💡 多対多の重要ポイント:中間テーブルで解決する

多対多の関係は、直接データベースで表現できません。必ず中間テーブルを作って、「1対多」と「多対1」の2つの関係に分解します。

中間テーブル(履修)が、学生と授業を結びつける役割を果たします。さらに、中間テーブルには「いつ履修したか」「成績は何点か」など、関係についての追加情報も持たせられます。

【多対多の分解イメージ】 学生 ←→ 授業(多対多:直接は無理) ↓ 分解 ↓ 学生 → 履修 ← 授業 学生 -(1対多)- 履修:1人の学生は複数の履修レコードを持つ 授業 -(1対多)- 履修:1つの授業は複数の履修レコードを持つ

📊 4. カーディナリティ(多重度)の基礎

カーディナリティとは

カーディナリティ(Cardinality)とは、リレーションシップの「数の関係」をより詳しく表したものです。

📝 なぜカーディナリティが必要?

「1対多」の関係でも、もっと詳しく考えると:

  • 最小値:最低何個必要か?(0個でもいい? 必ず1個以上?)
  • 最大値:最大何個まで持てるか?(1個だけ? 複数? 無制限?)

この「最小値」と「最大値」を表すのがカーディナリティです。これによって、データの制約をより正確に定義できます。

カーディナリティの表記方法

🎯 カーディナリティの書き方
表記:(最小値, 最大値) よく使うパターン: (0, 1) = 0個または1個(オプショナル、最大1つ) → 「なくてもいいし、あっても1つだけ」 (1, 1) = 必ず1個(必須、1つだけ) → 「必ず1つ必要」 (0, *) = 0個以上(オプショナル、複数可) → 「なくてもいいし、複数あってもいい」 (1, *) = 1個以上(必須、複数可) → 「最低1つは必要、複数あってもいい」 * = 無制限(many)という意味

具体例で理解する

例1:顧客と注文

顧客 → 注文の関係を考える

  • 1人の顧客は、注文を0回以上行える
  • 新規登録したばかりの顧客は、まだ注文していない(0回)
  • リピーターは何度も注文する(複数回)

→ カーディナリティ:(0, *)

注文 → 顧客の関係を考える

  • 1つの注文は、必ず1人の顧客に属する
  • 注文者がいない注文はありえない
  • 1つの注文が複数の顧客に属することもない

→ カーディナリティ:(1, 1)

例2:記事とカテゴリ

カテゴリ → 記事の関係を考える

  • 1つのカテゴリには、0個以上の記事がある
  • 新設カテゴリは、まだ記事がない(0個)
  • 人気カテゴリには多くの記事がある(複数)

→ カーディナリティ:(0, *)

記事 → カテゴリの関係を考える

  • 1つの記事は、必ず1つのカテゴリに属する
  • カテゴリなしの記事は許可しない(ビジネスルール)

→ カーディナリティ:(1, 1)

例3:ユーザーとプロフィール画像

ユーザー → プロフィール画像の関係を考える

  • 1人のユーザーは、プロフィール画像を0個または1個持つ
  • 設定していない人もいる(0個)
  • 設定しても1枚だけ(1個)

→ カーディナリティ:(0, 1)

プロフィール画像 → ユーザーの関係を考える

  • 1つのプロフィール画像は、必ず1人のユーザーに属する

→ カーディナリティ:(1, 1)

カーディナリティを決めるポイント

💡 カーディナリティ決定の3ステップ

ステップ1:最小値を考える

「必須か、オプショナルか?」を考える

  • 注文には必ず顧客が必要 → 最小値は 1
  • 顧客は注文がなくてもOK → 最小値は 0

ステップ2:最大値を考える

「1つだけか、複数可能か?」を考える

  • 1つの注文は1人の顧客だけ → 最大値は 1
  • 1人の顧客は何度も注文可能 → 最大値は *(無制限)

ステップ3:ビジネスルールを確認

業務上の制約を確認する

  • 「会員登録必須」なら注文→顧客は (1, 1)
  • 「ゲスト購入OK」なら注文→顧客は (0, 1)

🎯 5. 実践:エンティティ抽出演習

実際のシステム要件から、エンティティとリレーションシップを抽出する練習をしましょう。

演習1:図書館管理システム

【要件】
  • 会員が本を借りられる図書館システム
  • 本には、タイトル、著者、ISBN、出版年などの情報がある
  • 会員は名前、メールアドレス、会員番号を持つ
  • 貸出履歴を記録する(誰が、いつ、何を借りたか)
  • 本は1人の会員に貸し出される(同時に複数人には貸せない)
  • 会員は複数の本を借りられる(同時に最大5冊まで)
【解答例】

ステップ1:エンティティの抽出

要件から名詞を拾い出し、4つの条件でチェックする

1. 会員(Member) – member_id(主キー) – member_name – email – member_number(会員番号) – registered_at(登録日) 2. 本(Book) – book_id(主キー) – title – author – isbn – published_year 3. 貸出(Loan)← 「貸出履歴を記録する」から抽出 – loan_id(主キー) – member_id(外部キー) – book_id(外部キー) – loan_date(貸出日) – return_date(返却予定日) – returned_at(実際の返却日、NULLなら未返却)

ステップ2:リレーションシップの特定

会員 -(1対多)- 貸出 – 1人の会員は、複数の貸出レコードを持てる – 1つの貸出は、必ず1人の会員に属する – カーディナリティ:会員(0, *) ← 貸出(1, 1) 本 -(1対多)- 貸出 – 1冊の本は、複数の貸出レコードを持てる(過去の履歴含む) – 1つの貸出は、必ず1冊の本に対応する – カーディナリティ:本(0, *) ← 貸出(1, 1)

演習2:レストラン予約システム

【要件】
  • 顧客がレストランの席を予約できるシステム
  • レストランは複数のテーブル(席)を持つ
  • 各テーブルには席番号と収容人数がある
  • 予約時には、顧客名、電話番号、人数、日時を記録
  • 1つの予約は1つのテーブルに対して行われる
  • 1つのテーブルは、異なる日時であれば複数予約可能
【解答例】

エンティティと属性

1. 顧客(Customer) – customer_id(主キー) – customer_name – phone_number – email 2. テーブル(RestaurantTable) – table_id(主キー) – table_number(席番号:A1, B2など) – capacity(収容人数) 3. 予約(Reservation) – reservation_id(主キー) – customer_id(外部キー) – table_id(外部キー) – reservation_date(予約日) – reservation_time(予約時間) – party_size(予約人数) – status(ステータス:確定、キャンセルなど) – created_at(予約作成日時)

リレーションシップ

顧客 -(1対多)- 予約 – 1人の顧客は、複数の予約を持てる – カーディナリティ:顧客(0, *) ← 予約(1, 1) テーブル -(1対多)- 予約 – 1つのテーブルは、複数の予約を持てる(異なる日時) – カーディナリティ:テーブル(0, *) ← 予約(1, 1)

📝 STEP 2 のまとめ

✅ このステップで学んだこと
  • エンティティは、システムで管理したい「モノ」や「概念」(テーブルになる)
  • エンティティを見つけるには、要件から名詞を抽出し、4つの条件でチェック
  • 属性は、エンティティが持つ情報(カラムになる)
  • 属性には、キー属性、記述属性、外部キー属性の3種類がある
  • リレーションシップには、1対1、1対多、多対多の3つのタイプがある
  • 多対多の関係は、中間テーブルで解決する
  • カーディナリティで、関係の詳細な数を表現する(最小値、最大値)
💡 次のステップへ

エンティティとリレーションシップの理解は、データベース設計の土台です。

エンティティ抽出のコツは、「管理したい名詞」を見つけること。
リレーションシップは、「動詞」や「前置詞」で考えるとわかりやすいです。

次のSTEP 3では、これらをER図で視覚的に表現する方法を学びます!

📝 練習問題(10問)

問題 1 基礎

エンティティとは何か、自分の言葉で説明してください。

【解答例】

エンティティとは、システムで管理したい「モノ」や「概念」のことで、データベースではテーブルとして表現されます。

例えば、ECサイトなら「顧客」「商品」「注文」などがエンティティです。これらは複数存在し、IDで識別でき、それぞれが属性(名前、価格など)を持ちます。

問題 2 基礎

以下のうち、エンティティとして適切なものを選んでください。

A. 会社名(1つしかない)
B. 社員(複数いる)
C. 本日の日付(1つしかない)
D. 部署(複数ある)

【解答】

B. 社員D. 部署

理由:
エンティティは複数のインスタンスが存在する必要があります。
・「会社名」は1つだけなので、エンティティではなく設定値として扱う
・「本日の日付」も1つだけなので、エンティティではない
・「社員」は複数いる → ✅ エンティティ
・「部署」も複数ある → ✅ エンティティ

問題 3 基礎

リレーションシップの3つのタイプを挙げてください。

【解答】
  1. 1対1(One-to-One):1つのAは1つのBにだけ対応
  2. 1対多(One-to-Many):1つのAは複数のBに対応
  3. 多対多(Many-to-Many):複数のAは複数のBに対応
問題 4 応用

「学生」と「授業」の関係は、どのタイプのリレーションシップですか?また、それをデータベースで表現するにはどうすればよいですか?

【解答】

多対多(Many-to-Many)の関係です。

理由:
・1人の学生は、複数の授業を履修する
・1つの授業は、複数の学生が履修する

データベースでの表現方法:

中間テーブル「enrollments(履修)」を作成 students(学生) – student_id(主キー) – student_name courses(授業) – course_id(主キー) – course_name enrollments(履修)← 中間テーブル – enrollment_id(主キー) – student_id(外部キー → students) – course_id(外部キー → courses) – enrolled_at(履修日)
問題 5 応用

カーディナリティ記法で (0, *) と (1, 1) の違いを説明してください。

【解答】

(0, *):0個以上、無制限
→ 「なくてもいいし、複数あってもいい」(オプショナル、複数可)

(1, 1):必ず1個
→ 「必ず1つだけ必要」(必須、1つのみ)

例:
顧客 → 注文:(0, *) … 顧客は注文がなくてもいいし、複数注文してもいい
注文 → 顧客:(1, 1) … 注文には必ず1人の顧客が必要

問題 6 応用

以下の要件から、エンティティを抽出してください。

【要件】SNSアプリ
・ユーザーが投稿できる
・投稿には「いいね」ができる
・ユーザー同士がフォローできる

【解答例】
1. ユーザー(User) – user_id – username – email – created_at 2. 投稿(Post) – post_id – user_id(外部キー) – content – created_at 3. いいね(Like) – like_id – user_id(外部キー:誰が) – post_id(外部キー:どの投稿に) – created_at 4. フォロー(Follow) – follow_id – follower_id(外部キー → users:フォローする人) – following_id(外部キー → users:フォローされる人) – created_at

ポイント:
・「いいね」と「フォロー」は、一見エンティティに見えないかもしれませんが、「誰が、いつ、何に対して」という情報を持つため、エンティティとして扱います。
・フォローは、ユーザー同士の多対多の関係を表す中間テーブルです。

問題 7 応用

「商品」エンティティに対して、適切な属性を5つ以上挙げてください。

【解答例】
商品(Product)の属性: 1. product_id(商品ID)← 主キー 2. product_name(商品名) 3. price(価格) 4. stock_quantity(在庫数) 5. category_id(カテゴリID)← 外部キー 6. description(説明文) 7. image_url(画像URL) 8. created_at(登録日) 9. updated_at(更新日) 10. is_active(販売中フラグ)

他にも、商品コード、JANコード、メーカー、重量、サイズなど、ビジネス要件に応じて追加できます。

問題 8 発展

以下のリレーションシップのカーディナリティを考えてください。

「社員」と「部署」の関係
・1人の社員は、必ず1つの部署に所属する
・1つの部署には、0人以上の社員がいる(新設部署は社員0人)

【解答】

社員 → 部署:(1, 1)
→ 社員は必ず1つの部署に所属(必須、1つだけ)

部署 → 社員:(0, *)
→ 部署は社員がいなくてもいいし、複数の社員がいてもいい

問題 9 発展

多対多の関係を中間テーブルで解決する理由を説明してください。

【解答】

多対多の関係は、リレーショナルデータベースで直接表現できないためです。

❌ 悪い設計(中間テーブルなし)

students テーブルに course_ids を持たせる? → 1つのカラムに「1,2,3」のように複数の値を入れることになる → 第1正規形違反!検索も困難になる courses テーブルに student_ids を持たせる? → 同じく複数の値を入れることになる → 第1正規形違反!

✅ 良い設計(中間テーブルあり)

enrollments(履修)という中間テーブルを作る – student_id と course_id の組み合わせを1行ずつ記録 – これで正規化のルールを守りつつ、多対多を表現できる さらに、中間テーブルには追加情報も持たせられる – enrolled_at(いつ履修したか) – grade(成績は何点か) – status(履修中、完了、取り消しなど)
問題 10 発展

以下の要件から、エンティティ、属性、リレーションシップを設計してください。

【要件】オンライン学習プラットフォーム
・講師が講座を作成する
・受講生が講座を受講する
・講座には複数のレッスンがある
・受講生はレッスンを完了したら、完了記録を残す

【解答例】

エンティティと属性:

1. ユーザー(User) – user_id – username – email – role(講師 or 受講生) 2. 講座(Course) – course_id – instructor_id(外部キー → users) – course_name – description – created_at 3. レッスン(Lesson) – lesson_id – course_id(外部キー → courses) – lesson_title – content – order_number(順序) 4. 受講(Enrollment)← 受講生と講座の中間テーブル – enrollment_id – student_id(外部キー → users) – course_id(外部キー → courses) – enrolled_at 5. レッスン完了(LessonCompletion) – completion_id – enrollment_id(外部キー → enrollments) – lesson_id(外部キー → lessons) – completed_at

リレーションシップ:

講師(User) -(1対多)- 講座(Course) – 1人の講師は、複数の講座を作成できる 講座(Course) -(1対多)- レッスン(Lesson) – 1つの講座は、複数のレッスンを持つ 受講生(User) -(多対多)- 講座(Course) – 中間テーブル:Enrollment(受講) 受講(Enrollment) -(1対多)- レッスン完了(LessonCompletion) – 1つの受講は、複数のレッスン完了記録を持つ

❓ よくある質問

Q1: エンティティと属性の違いがわかりません。どう見分ければいいですか?
シンプルな見分け方:

エンティティ:複数のインスタンスがあり、それ自体を管理したい「モノ」
属性:エンティティを説明する情報

例えば「商品」はエンティティ、「商品名」は属性です。「商品名」だけでは意味がありませんが、「商品」というエンティティがあって、その情報として「商品名」があります。

判断基準:「それ自体を検索・管理したいか?」
→「商品を検索したい」「商品一覧を表示したい」→ エンティティ
→「商品名だけを管理する」ことはない → 属性
Q2: 1対1の関係は、1つのテーブルにまとめてはダメですか?
場合によります。1対1の関係でも、以下の理由で分けることがあります:

1. パフォーマンス:よく使う情報と滅多に使わない情報を分ける
 例:ユーザーの基本情報(よく使う)と詳細プロフィール(たまに使う)

2. セキュリティ:機密情報を別テーブルに分離
 例:ユーザー情報と決済情報

3. オプショナル:必須でない情報
 例:すべてのユーザーがプロフィール画像を持つわけではない

これらの理由がなければ、1つのテーブルにまとめても問題ありません。
Q3: カーディナリティは、どこまで厳密に考える必要がありますか?
設計段階では厳密に考えることが重要です。カーディナリティは、以下に影響します:

NULL制約:(1, …) なら NOT NULL、(0, …) なら NULL許可
ビジネスロジック:「必須」か「オプション」かでバリデーションが変わる
データの整合性:制約をDBレベルで保証できる

後から変更すると、既存データの修正が必要になるため、最初にしっかり考えましょう。
Q4: 中間テーブルの名前は、どうつければいいですか?
以下のパターンがあります:

1. 動詞形:関係を表す動詞
 例:enrollments(履修)、follows(フォロー)、purchases(購入)

2. 2つのテーブル名の組み合わせ
 例:student_courses、user_roles、product_tags

3. ビジネス用語
 例:orders(注文)、bookings(予約)

どれでもOKですが、プロジェクト内で統一することが大切です。
Q5: エンティティの抽出に自信がありません。練習方法はありますか?
以下の練習方法がおすすめです:

1. 身近なシステムを分析
 例:Amazon、Twitter、Netflixなどの有名サービスのDB設計を想像してみる

2. 要件書から名詞を抽出
 文章中の名詞をリストアップし、エンティティ候補として検討

3. 実際に手を動かす
 紙やホワイトボードで、エンティティとリレーションシップを書いてみる

4. 他人の設計を見る
 GitHubなどでオープンソースのDB設計を参考にする

経験を積むことで、自然とエンティティが見えてくるようになります!
📝

学習メモ

データベース設計・データモデリング - Step 2

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE