質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

Q&A

解決済

4回答

1150閲覧

DB設計 1注文に動的に設定できるオプションが有る場合の注文管理について

p19ljk

総合スコア146

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

0グッド

1クリップ

投稿2022/06/07 04:05

編集2022/06/07 04:13

前提

ある商品の注文管理システムのDB設計を考えています。
注文をする際に管理者が事前に登録をしておいたオプション事項を注文者が設定できる場合の注文管理の方法が分からないので質問させていただきました。

お弁当を例に簡易的に、

  1. 商品は商品Aひとつのみ
  2. 注文の際に「サイズ」(大,中,小), 「箸」(あり,なし)が選択できる
  3. これらオプションの種類は管理者が別の管理画面にて追加、削除ができる。
    (ex. 後から「袋」(あり,なし)が追加できる)

これらを実現するためにまず下記のようにテーブル設計。
■ 商品テーブル

id名前
1商品A

■ オプションテーブル

id商品id名前
11サイズ
21

■ オプション明細テーブル

idオプションid名前
11
21
31
42あり
52なし

そして、とある利用者が一度に注文を
・商品A / サイズ大 / 箸あり => 3個
・商品A / サイズ中 / 箸あり => 2個
・商品A / サイズ中 / 箸なし => 2個
とできるとします。

検討したこと

良い設計が思いつかず、一つ思いついたのは下記です。
■ 注文

idユーザid日付個数
11202206077

■注文明細

id注文idオプション個数
111,43
212,42
312,52

(「オプション」へ設定されたオプション明細のidを列挙)
1カラムに複数値入れるのはアンチパターンと言われているので、最悪これなのかなと思いつつ他に良い方法が思いつきません。
オプションが固定であればカラムをオプションごとに作ればよいのですが。。。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/06/07 04:18

オプションにもid持たせて、注文idと商品idとオプションidでユニークになるようにしたら良いのでは?
p19ljk

2022/06/07 04:24

>オプションにもid持たせて、 とはどういうことでしょうか? 「注文明細」のオプションのことですかね?
guest

回答4

0

現状を素直に正規化するなら、
注文明細テーブルを二つに分ける形でしょうね
(注文テーブルの「個数」も無い方がいいとは思います)

注文明細

id注文id個数
113
212
312

注文明細-オプション明細

id注文明細idオプション明細id
111
214
322
424
532
635

ただ、

1カラムに複数値入れるのはアンチパターンと言われているので、

については、RDBMSの機能と使い方次第でどっちが適しているかが変わってくるので、
実際の条件に近づけて、クエリを作って比較してみるのが良いのかなと思います。

投稿2022/06/07 05:55

tanat

総合スコア18713

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

p19ljk

2022/06/07 06:03

回答ありがとうございます。 なるほど! 正規化するならそうなるのですねー 全否定されるアンチパターンではないようなので、正規化する場合と比較して実装してみます。
guest

0

ベストアンサー

どの程度正規化を緩めるかという話になりますが、

これらオプションの種類は管理者が別の管理画面にて追加、削除ができる。

という事ですから、マスタは正規化した状態が良いかと思います。

悩ましいのはトランザクションテーブルですね。
配列に関する関数[array_agg()unnest()等) が充実しているpostgresであれば、設計のように配列でも良いかと思います。(正規化して別テーブルにする場合はキーによるリソースの問題や性能面も考えなければなりませんので。)
尚、正規化した状態の設計でも、array_agg()を使用すれば配列に畳むことも出来ますので、画面側で制御する事も可能かと。

投稿2022/06/07 04:26

編集2022/06/07 04:26
sazi

総合スコア25173

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

p19ljk

2022/06/07 04:40

回答ありがとうございます。 この場合って正規化は可能なのでしょうか? 「サイズ」と「箸」が固定であればそれぞれの組み合わせテーブルが用意できますが、動的にオプション数が増える、変更できるとなると対応させるにはこの方法では無理かと思いますし。。。
sazi

2022/06/07 07:10 編集

オプションなどで使われるものとして、配列型の他にjson型などもあります。 これらは可変な項目数を一つのカラムに畳むことが出来ます。 正規化の有無によってあまりにも件数に差異が出るような場合、大量に処理するようなケースでは性能に影響しますので、正規化を緩めた方が良いと個人的には思います。
guest

0

オプションテーブルに選択肢もenumなどで設定してやっても良いかもしれません

投稿2022/06/07 05:17

yambejp

総合スコア114779

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

注文テーブルに商品idを持たせていないことが気になりますね。

商品idを注文テーブルに持たせたならば、
注文詳細テーブルでは
注文id、商品id、(商品id由来の)オプションid
でユニークになるようにして、
オプションに対する名前?値?を持てばよろし。

投稿2022/06/07 04:25

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

p19ljk

2022/06/07 04:34

回答ありがとうございます。 > 注文id、商品id、(商品id由来の)オプションid > でユニークになるようにして、 これがちょっと理解できていないのですが、オプションは各オプションの組み合わせがあるのでユニークキー群に含めるのが難しい気がするのですが、全組み合わせのテーブルを作るということですかね?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問