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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

解決済

4回答

567閲覧

商品検索システムのデータベース構造

move

総合スコア16

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

1クリップ

投稿2018/10/28 05:56

なにかしらの商品を検索するようなシステムを作る場合、皆様は検索パラメータのデータベース構造はどのようにされてますか?またどのように検索してますか?

例えば
DBに商品を登録し、以下のパラメータの”任意の組み合わせ”で絞り込み検索し、ページングで表示する場合を想定した時

・形状(shape)・・・一つの商品に複数の形状を設定できる
・色(color)・・・一つの商品に複数の色を設定できる
・用途(use)・・・一つの商品に複数の用途を設定できる
・キーワード(keyword)

例えば以下のようなURLで検索条件を渡し
www.sample.com/catalog?page=2&shape[]=circle&color[]=red&color[]=white&use[]=use_a&keyword=キーワード1

Laravel5.5で実装し、LengthAwarePaginatorでページングを実現予定。
LengthAwarePaginatorの引数は、ヒットした商品総数・ページ番号・1ページあたりの表示数・該当ページの商品配列の4つが必要
1ページあたりの表示数は説明簡略の為15で固定とする。
該当ページの商品配列は商品クラスを定義しておき、商品クラスのオブジェクト配列を予定

その時のDBの構造で効率的な方法を悩んでいます。

・案1
DB
■商品TABLE
ID, 商品名
ITEM001, 商品1
ITEM002, 商品2

■形状TABLE
商品ID, 形状
ITEM001, circle
ITEM002, triangle

■色TABLE
商品ID, 色
ITEM001, red
ITEM001, white
ITEM002, black

■用途TABLE
商品ID, 用途
ITEM001, use_a
ITEM001, use_b
ITEM002, use_c

■キーワード(TAG)TABLE
商品ID, タグ
ITEM001, キーワード1
ITEM001, キーワード2
ITEM002, キーワード3

1.URLのGETパラメータからshape,color,use,keywordの値を取得して、
順番に該当する商品IDの配列をそれぞれ取得。

2.array_intersectで共通する商品IDの配列($item_idsとする)を作る

3.2で取得した商品ID配列のcount($item_ids)が総数

4.array_chunk($item_ids, 15)で該当ページの商品配列を取得し、その配列をもとに各商品のオブジェクトは最低限の15個作成

で実現はできるが、テーブル構造はわかりやすいが、商品検索の処理が鈍臭い気がする、もっとスマートな方法は無いものか?

・案2
■商品TABLE
ID, 商品名
ITEM001, 商品1
ITEM002, 商品2

■属性TABLE
商品ID, タイプ, 値
ITEM001, 形状, circle
ITEM001, 色, red
ITEM001, 色, white
ITEM001, 用途, use_a
ITEM001, 用途, use_b
ITEM001, キーワード, キーワード1
ITEM001, キーワード, キーワード2
ITEM002, 形状, 商品2
ITEM002, 色, black
ITEM002, 用途, use_c
ITEM002, キーワード, キーワード3

のように検索条件を一つのテーブルにまとめて少し簡略化して

1.URLのGETパラメータからshape,color,use,keywordの値を取得して、
属性DBから一回で商品ID配列($item_ids)を取ってくる

2.array_chunk($item_ids, 15)で該当ページの商品配列を取得、その配列をもとに各商品のオブジェクトは最低限の15個作成

案1よりは検索の処理はスマートになるけどまだあまりスマートな感じがしない。

皆様このような用途の場合どのようなデータベース設計にされてますでしょうか?

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

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

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

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

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

guest

回答4

0

どういった商品により、異なってくるんじゃないですか?

投稿2018/10/28 07:01

akirafudo6

総合スコア341

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

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

akirafudo6

2018/10/29 02:25

どういった場面とかの情報がないので、解が導き出せれない。 何か、本とかみて質問されているのか、学校から出された宿題なのか、あるいはとある業務をこなしていて迷っているのか、それはどうゆう場面たとえば、倉庫の管理なのか、店舗のような在庫管理なのか、あるいは生産製造業をいとなんでその受発注を管理したいのか?、とある商品って、食べ物?金属系?或いは、木工製品?機械の部品管理?、形状って何種類ぐらいあるのとか?またitemの相対関係(商品に対して、色、形状、用途、キーワードについての関係) 色についても、例として3種類啓示されてますが実際何種類あるのか(16種類、256?、それともフルカラー?)。扱う商品もどれぐらいの数を扱うのか?ひょっとしたら、XML(これもdbの一種)で管理したほうがいいかもしれないし、質問の内容だけでこれだけ疑問に思ってしまします。
guest

0

(マスタ系)
■色マスタTABLE
色cd 色名 色表示名
01  赤  アカ
02  青  アオ

■形状マスタTABLE
形状cd 形状名 形状表示名
01  circle マル
02  triangle  サンカク

■用途マスタTABLE
用途cd 用途名 用途内容
01  社用 カイシャヨウ
02  個人 コジニョウ

以上がコードのマスタ。
一つ一つが似た構造なら汎用コードマスタみたいなのを等を作ってもいい。

(商品マスタ)
案1:

■商品マスタTABLE
商品ID, 商品名, 色cd,  形状cd,      用途cd ,  キーワード(スペースで区切る)
ITEM001, 商品1, 01;02,  circle,      01;02,   まるいしょうひん かわいい商品
ITEM002, 商品2, 01,    circle;triangle, 02,    傘  かさ カサ

色コード「01;02」のように情報を;区切りで入れてしまう手が1案。
嫌いな人は嫌いだし、マスタ管理画面等があるならやめたほうがいいかもしれません
sqlではinで聞けるのでそっちは楽です。

案2:
商品マスタTABLE
商品ID, 商品名,キーワード,色cd1,色cd2,色cd3,色cd4,色cd5,形状cd1,形状cd2,形状cd3,形状cd4,....

一つの商品に対して設定できる色数の上限が決まっているなら
こういった横に広い商品情報テーブルを持つプロジェクトもありました。

美しいかというと悩ましい所ですが。

投稿2018/10/29 05:53

ms5025

総合スコア292

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

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

ms5025

2018/10/29 05:59

ちなみにセレクトするときは shape,color,use,keyword を商品マスタからwhere句で引いてくる感じです。 案1なら全部 in句で聞けばいいと思います。 カンマ区切りで文字列として保存し、読み出すときにパースして扱うのを 嫌う人は嫌います。 マスタ管理画面などがある場合は ;区切りで入れたデータの抜き差しが美しくないと感じる人もいます。 毎回どうしようかなと思うポイントでもあります。
kgm

2018/10/29 06:32

案1も案2も属性が増えた場合、商品マスタのカラムを増やすことになりますね。 やっちゃいけない典型ですよ。 システム設計は、好き嫌いという個人の感情は関係ありません。 効率的かどうか、整合性が取れるかどうかで判断すべきです。 新人さんや業界外の人にはなかなか理解されないんですけどね。
ms5025

2018/10/30 00:17

そうですか、考えがいたらず申し訳なかったです。 回答は無視してください。 運用段階に入ると一つのテーブルでさっと全体を把握できると割と楽だったりするので 案件の大きさによってはこういう形をとるプロジェクトも多かったです (あくまで私が渡り歩いてきた会社では。私がというよりそういう形をとってるところに配属されることが多かった) 設計段階で商品に必要な属性は決めて進む事が多いのと(増える可能性がない) もしこうだったら、もしこうだったらで分散させて結果わかりにくくなる事も多かった事から 案件の大きさと仕様変更の有無の可能性でこうなることもあったのかもしれません。 いずれにせよあまりよくない回答だったようで、削除依頼を出しておきました。 >システム設計は、好き嫌いという個人の感情は関係ありません 私の周りでは割といつも「どうしましょうかね」と数人で意見が割れる事もあります。 一般的にはこうだけど、今回はこれでいきましょう。とか。 教科書どおりにいかないことも多いですね。全員が全員同じレベルってわけでもないのが原因かもしれませんが。
kgm

2018/10/31 02:17

ちょっと言葉がきつかったかもしれませんね。失礼しました。 でも、DB周り(特にテーブル設計)はシステムの根幹に関わることなので本当に大切です。 プロジェクトの成否の50%はDBで決まると言われているくらいです。 もちろんどんなプロジェクトでも、スピード重視であえて正規化しないテーブルはあります。 だからといって最初から不合理なやり方をすべきではないと思います。 基本を押さえておかないと、異常なくらい開発しにくくなったり、何か問題が起こったとき対応しにくくなったり、スケールアップに対応しにくくなったり、他の人に引き継ぎできなくなってしまいます。 ある程度大きさがあるプロジェクトでは、テーブル設計だけは経験豊富で知識がある人がきっちりやらないとダメですね。 話し合いで解決することではない場合も多いです。
ms5025

2018/10/31 02:46

私が質問を読み違えていたのかもしれませんが、 関係テーブルを使う事が冗長な気がするので テーブルの簡略化ができないか?という質問かと思っていました。 通常は関係テーブルで商品IDと属性とを括り付けるのが正しいですが 運用時一目でぱっと見たい(sql叩けばいいことですが) テーブル一つで管理したいから、小さいプロジェクトだから、仕様はもう変わらないから、という要望は、確かに今まで何度かありました。 よってこういう方法もありますよという提案をしたつもりです。 削除依頼は却下されたのですいません。 >テーブル設計だけは経験豊富で知識がある人がきっちりやらないとダメですね。 特にPHPは少人数で若い子が適当に作ったテーブルとかでやる開発現場も多いです。 現場もきっちりしたそれを求めてない所もあったり様々といったところです。
guest

0

スマートと言われているのは、フロント側で配列になっていると扱いやすい事ですね。
DB視点で言うと、配列というのは正規化の観点から扱いづらい事です。

DBは正規化した状態で保持し、取り出すときに配列として扱えれば、問題は解決します。
MySQLではなくPostgresであれば、array_aggなどの集約関数でそのような事ができますので、検討されては如何でしょうか。
また、postgresでユーザー定義型を使用すると、配列に対するようなアクセスをする事ができます。
そもそも、配列でも項目定義ができますし、配列を扱う関数も充実しています。
9.18. 配列関数と演算子

投稿2018/10/29 00:30

編集2018/10/29 05:56
sazi

総合スコア25195

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

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

0

ベストアンサー

2つの問題がごっちゃになってますね。
DBにどういう形でデータを保存するかということとそのデータをどう処理するかは別問題です。
正しくデータを保存できれば(妥当なテーブル設計ができれば)、検索処理も簡単になります。
まずはどういうテーブルを作ればいいか考えるべきでしょう。

多少なりとも心得のある設計者ならこんなテーブルにわけるはずです。

  • 商品テーブル
  • 関係テーブル
  • 形状テーブル
  • 色テーブル
  • 用途テーブル

・・・

関係テーブルで商品がどの属性を持つか規定します。
形状や色などの属性テーブルに商品IDを持たせないようにすれば、属性を増やす場合や属性の名前を変える場合も簡単です。
カラムの型が違う属性も関係テーブルをかませることによって一括で管理できます。
検索処理が簡単になるのは言わずもがな。

もっと詳しく知りたければこんなキーワードでググってみて下さい。

  • 正規化
  • テーブルの独立性
  • SQLアンチパターン

投稿2018/10/28 13:20

kgm

総合スコア275

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

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

move

2018/10/30 11:07

ありがとうございます、回答いただいた中で一番しっくりくると思いましたのでベストアンサーとさせていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問