🐡

【DB設計】ECサイトのER図作成

2023/07/11に公開
5

ECサイトをチームで開発するにあたり、ER図を作成していきます。
みんなそれぞれ考えて作ってきて持ち寄ったのですが、意見が分かれる点も何点かありました。
なんでそうしたのか、というのを間違っていてもいいので考えることが大切だと思います。

ER図は答えになってしまうので載せないのですが、自身の学びや考え方の備忘録を残します。

ER図

要件定義からER図を作成します。
draw.ioというサイトを使用しました。

各テーブルの役割

各テーブルについてポイントを説明します。

管理者

管理者のデータを格納するテーブル。

会員

ECサイトに登録する顧客の情報を格納。会員情報(氏名、住所、連絡先など)を管理する。
「会員ステータス」[1]のカラムを持つことで、退会状況がわかるようにする。退会時にデータを削除しないのは、退会者の注文履歴等を見れるようにしておくため。

配達先

顧客注文時の配送先情報を格納。注文時に指定された配送先の情報(郵便番号、住所、宛名など)を管理する。

商品

ECサイトで販売する個々の商品データを格納。商品の情報(商品名、説明、価格など)を持つことで、顧客に表示・購入される商品データを管理する。
「販売ステータス」カラムを持つことで、販売中/販売停止中の商品を管理できるようにする。

ジャンル

商品を分類するためのジャンルを表すテーブル。商品を特定のジャンルに分類し、顧客にとってのナビゲーションや、検索手段として使えるようにする。

カート

会員が選択した商品を一時的に保存するためのテーブル。

カート機能には以下の情報が必要:

  1. 会員id(誰が)
    カートに商品を入れた会員を分かるようにするため。

  2. 商品id(何の商品を)
    どの商品がカートに入ったかを分かるようにするため。

  3. 個数(いくつカートに入れたのか)
    会員はカートに同じ商品を複数個入れることができるため、個数カラムをもつことで、会員がカートに入れた商品の数量をわかるようにする。

個数カラムの必要性

個数カラムがなくても実装できるが、データの無駄が多くなる。
以下は具体例。

  • カートテーブル(個数カラムなし):
会員_id 商品_id
1 101
1 101
1 102
2 101
3 103
3 103
3 103

上記の例では、商品101が会員1のカートに2個入っているために、2つの同じ行が存在する。このように個数情報は行数で表現されるため、重複した情報は、データベース内で無駄が多くなる。

  • カートテーブル(個数カラムあり):
会員_id 商品_id 個数
1 101 2
1 102 1
2 101 1
3 103 3

個数カラムを持つことで、カート内の各商品の個数を直接参照することができる。無駄が減り、特定の商品の個数を把握するために行数を数える必要がなくなる。

注文

顧客が商品を注文する際の注文情報を表すテーブル。
注文の情報を管理し、顧客の注文履歴を追跡できるようにする。
「注文ステータス」を持つことで、[入金待ち・入金確認・製作中・発送準備中・発送済み]の状態を管理。

注文詳細

注文ごとの商品の詳細情報を表すテーブル。
各注文に対して、注文された商品の情報(個数、製作ステータスなど)を管理。

注文テーブルと注文詳細テーブルを分ける理由
  1. データの無駄が多くなる。
  2. 注文情報の更新や修正が必要な場合に処理が大変。
    以下は具体例。
  • 注文テーブル(注文詳細テーブルなし):
注文id 会員id 配達先 支払方法 商品id 数量 価格 送料 請求金額 製作ステータス 注文ステータス
1 123 456 クレジットカード 100(商品A) 1 800 800 3000 製作中 入金待ち
1 123 456 クレジットカード 200(商品B) 2 800 800 3000 製作中 入金待ち
1 123 456 クレジットカード 300(商品C) 3 600 800 3000 製作中 入金待ち

この例は、会員ID 123 の顧客の1回の注文。商品A、商品B、商品C の3つの商品を注文している。
このように、注文テーブルと注文詳細テーブルを1つにする場合、同じ注文に関連する商品の詳細情報(会員id、配達先、支払方法、送料、請求金額など)が繰り返される。そのためデータの無駄が生まれる。

  • 注文テーブルと注文詳細テーブルを分けた場合:

注文テーブル:

注文id 会員id 配達先 支払方法 送料 請求金額 注文ステータス
1 123 456 クレジットカード 800 3000 入金待ち

注文詳細テーブル:

注文詳細id 注文id 商品id 数量 価格 製作ステータス
1 1 100 1 800 製作中
2 1 200 2 800 製作中
3 1 300 3 600 製作中

2つに分けると、注文テーブルには注文全体に関する情報が1つ記録される。注文詳細テーブルには個々の商品に関連する詳細情報が格納される。
これにより、注文詳細テーブルでは商品ごとに数量、価格、製作ステータスが管理できる。つまり、注文テーブルと注文詳細テーブルを分けることで、商品の個別な管理が可能になる。例えば、商品の製作ステータスの更新や数量の変更は、注文詳細テーブルの該当するレコードのみを操作すればよい。

参照

以下参考にさせてもらった記事です。
ありがとうございました♪
https://zenn.dev/goldsaya/articles/272826e55c9809

以下の本もわかりやすかったです。
https://www.amazon.co.jp/スッキリわかるSQL入門-第3版-ドリル256問付き-スッキリわかる入門シリーズ-中山/dp/4295013390
チーム開発が始まりました!3~4人編成のチームがあり、俺のチームは3人でした☆
チームビルディングは楽しかったしめちゃめちゃ素敵な方々だった!チーム開発に向け、皆同じ想いを持っていたのが印象的だったし嬉しかったです。チーム開発が終わっても仲良くできたら嬉しいな
良いものができそうだなっと思ったのでとても楽しみ!

脚注
  1. 追記:カラム名に入る値が分かりやすいカラム名がよいとのこと。「退会フラグ」や「退会ステータス」等 ↩︎

Discussion

Matsukura YukiMatsukura Yuki

ECサイトや在庫管理などの発生する業務システムを何度か作った事があるのでその視点で軽くレビューしてみます。

要求定義しだいで色々な設計の作り込みが考えられるので、浅く広く見た上での論点を軽く書いておきます。

  • 商品で在庫管理はしない感じでしょうか?
  • 商品テーブルのレコードのライフサイクルが気になりました。注文から商品の情報を外部キーで持っているとと、商品が物理削除されたら参照できなくなってしまったり、商品の名称が変更されたら注文時の内容と変わってしまいます。
    • 配送先に関しても同じ。
  • ユーザ登録しないとカートに入れられないようですが、ユーザ視点で見ると不便かもしれません。

といったかんじで、ECサイトの設計はかなり面倒なのと、要件定義によって設計が変わるので要件定義などがないとレビューしづらいです。

がんもがんも

経験からのレビューとても嬉しいです!
ご指摘の通り要件定義を出していないのでわかりづらいですね💦そのうえでも、知識を共有していただき本当にありがとうございます。

以下に論点へのコメントいたします。

  • 商品で在庫管理はしない感じでしょうか?
  • ユーザ登録しないとカートに入れられないようですが、ユーザ視点で見ると不便かもしれません。

→要件によるものでした💦受注生産だったので在庫管理は設けません。閲覧はログインなしでできるようにしますが、カート機能はログインなしでは使えないようにします。

  • 商品テーブルのレコードのライフサイクルが気になりました。注文から商品の情報を外部キーで持っているとと、商品が物理削除されたら参照できなくなってしまったり、商品の名称が変更されたら注文時の内容と変わってしまいます。配送先に関しても同じ。

→そこに関してのフォローは考えていなく、ご指摘の通りだと思い、とても勉強になりました。データベースに削除制約を設定すればと思ったのですが、名前変更には対応できませんね💦
リレーションさせない場合、商品テーブルに「商品コード」みたいなカラムを追加して管理するのでしょうか?ご教授いただければ幸いです。よろしくお願いいたしますm(__)m

Matsukura YukiMatsukura Yuki

リレーションさせない場合、商品テーブルに「商品コード」みたいなカラムを追加して管理するのでしょうか?

注文テーブルの子供の要素として、商品テーブルとほぼ同じ属性のテーブルを作っておいて、商品テーブルの内容をコピーしておいておくといったアプローチがあります。

がんもがんも

注文テーブルの子供の要素として、商品テーブルとほぼ同じ属性のテーブルを作っておいて、商品テーブルの内容をコピーしておいておくといったアプローチがあります。

なるほど!!それで、注文時に商品情報が変更されても影響されずに管理できるようになるんですね。履歴も管理できますしとても参考になるアプローチです。
参考になるご意見本当にありがとうございました。

Matsukura YukiMatsukura Yuki

もう1歩話を進めると、
商品テーブルのコピーを保持すると似たようなレコードが大量に生成されてしまう問題があります。
この部分を正規化するためには、商品テーブルの情報をバージョニングして1回更新するごとに1 revision進めて行って、注文した際にはそのrevisionを保管するというアプローチもあります。

このアプローチでは、逆に商品マスタ側もレコードがどんどん増えてしまうデメリットもあるので、商品の更新頻度と注文の頻度、実装の時間を計算した上で最適なアプローチを選択するのが良いです。