• ベストアンサー

DB設計について

ユーザー情報などで、チェックボックスで複数選択してもらった項目を DBへ登録する場合どのように、テーブルを作るのが良いのでしょうか? 例えば、一つのフィールドに、選択してもらった項目を user_id hoby 1    'サッカー,野球,バスケ' などと入れるのがいいのか、 別の、テーブルを作って、 user_id hoby 1    サッカー 1    野球 1    バスケ この方がよいのか、どちらがよいのでしょうか、よろしくお願いいたします。

  • MySQL
  • 回答数7
  • ありがとう数7

質問者が選んだベストアンサー

  • ベストアンサー
noname#221739
noname#221739
回答No.7

> user_tb > user_id name > 1    AAAA > hoby_tb > user_id hoby > 1    サッカー > 1    野球 > 1    バスケ > ユーザーid1の結合結果 > user_id name hoby[]  hoby[] hoby[] > 1    AAAA サッカー 野球  バスケ まず、hoby_tbの主キーを ・user_id ・seq_no …連番ね に変更する必要がありますね。 その上で。一発で取ってこれるかどうかは、テーブル仕様に拠ります。 仮に hoby_tb.seq_no が最大 5 というようにしているなら、下記のようなSELECT文になるんじゃないかな? SELECT F1.user_id, F1.name , ( SELECT hoby FROM hoby_tb WHERE seq_no = 1 AND user_id = F1.user_id ) AS hoby1 , ( SELECT hoby FROM hoby_tb WHERE seq_no = 2 AND user_id = F1.user_id ) AS hoby2 , ( SELECT hoby FROM hoby_tb WHERE seq_no = 3 AND user_id = F1.user_id ) AS hoby3 , ( SELECT hoby FROM hoby_tb WHERE seq_no = 4 AND user_id = F1.user_id ) AS hoby4 , ( SELECT hoby FROM hoby_tb WHERE seq_no = 5 AND user_id = F1.user_id ) AS hoby5 FROM user_tb F1 ORDER BY F1.user_tb 仮に hoby_tb.seq_no の最大数は不確定だ、というなら、SELECT文の発行を2回に分けたりする必要があるんではないかな?

jyangule_p
質問者

補足

stein_JP様 有難う御座いました。 チェックが多いいとSQL文もかなり長くなりそうですね。

その他の回答 (6)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.6

>hoby[0]['サッカー'],hoby[1]['野球'],hoby[2]['バスケ'] ではなく hoby[$user_id][0]='サッカー'; hoby[$user_id][1]='野球'; hoby[$user_id][2]='バスケ'; ・・・・ とすべきではないでしょうか?

jyangule_p
質問者

補足

yambejp様 有難う御座いました。 配列の書き方が、変でした。

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.5

がるです。 > データを取り出すして、 > hoby[0]['サッカー'],hoby[1]['野球'],hoby[2]['バスケ'] > としたい場合には、どうすればよろしいでしょうか、 二つほど質問なのですが。 順番は厳密に管理されるべきでしょうか? それとも順不同でもOKでしょうか? あと、拝見していると配列のキーに情報が入っているのですが、これはこのように持ちたいものなのでしょうか? # 通例、例えば「hoby[0]='サッカー',hoby[1]='野球',hoby[2]='バスケ'」若しくは「hoby['サッカー'],hoby['野球'],hoby['バスケ']」という風に持つケースが多いと思うので。 順不同であれば単純に SELECT hoby FROM テーブル名 WHERE user_id='1'; で。 もし順番が管理されるべきなのであれば、それようにもう1フィールド突っ込んでおいて(例えばsort_noなど)、 SELECT hoby, sort_no FROM テーブル名 WHERE user_id='1' ORDER BY sort_no; という風になさるとよろしいかと思います。 で、データを並べ替えたら、後はプログラム側で好きな形の配列にいれるとよろしいかと思います。

jyangule_p
質問者

補足

がる様 有難う御座いました。 すいません、言葉が足りませんでした、 配列の順番は、今のところ考慮しておりませんが、 下記のように、user_tbとhobo_tbを結合した時の SQL文が、いま一つ良く分からないもので、 すいませんが、よろしくお願いいたします。 user_tb user_id name 1    AAAA hoby_tb user_id hoby 1    サッカー 1    野球 1    バスケ ユーザーid1の結合結果 user_id name hoby[]  hoby[] hoby[] 1    AAAA サッカー 野球  バスケ

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.4

がると申します。 基本的には後者がよろしかろうかと。検索その他を考えて、前者のメリットはないに等しいので。 ただ、レコード数制限などの観点から後者がチョイスできない場合に前者のような持ち方をしないわけではないです…が、レコード数が溢れたらもうちょっと抜本的に色々対策を練りますねぇ(苦笑 といった思考過程から、私は後者に一票を投じます。

jyangule_p
質問者

補足

がる様 有難う御座いました。 やはり、後者のようですが、 後者の場合気になったのが、SQL文の組み立てですが、 データを取り出すして、 hoby[0]['サッカー'],hoby[1]['野球'],hoby[2]['バスケ'] としたい場合には、どうすればよろしいでしょうか、 よろしくお願いいたします。

  • nikuq
  • ベストアンサー率22% (8/36)
回答No.3

それぞれ一長一短がありますが、私は前者の方法で使っています。 前者の長所は、レコード数が少ない事と、修正がラクチンな事です。 ユーザがのちのちに変更しても、同じレコード内にあるデータを書き換えるだけですからね。 短所は、Indexが効かない事ですね。fulltextでも日本語はダメなので。 それと、サッカーが例えばテニスに変更した場合には修正がめっちゃくちゃ面倒な事になりますね。 後者の一長一短は前者のまるっきり反対になると思います。 後者の長所は、Indexが使える事です。ユーザID等のユニークなIDを英数字で紐付けすれば Indexが使えます。 短所は、レコード数がむちゃくちゃ増える事ですね。 1ユーザが3項目選択するとそのまま3レコード増える事になります。 そのぶん、直接DBを管理する時に非常に乱雑になると思います。 ユーザが修正かけてもいちいち全レコードからユーザIDで抽出し、1レコードずつ修正しなくては いけません。 そのかわり、前者の例のように、まとめて変更する時は楽です。 という事から、ユーザ情報のDBだとすると、将来、どれくらい ユーザが増えるかによって、決めた方がいいと思います。 ちなみに、前者の場合で、例えばサッカー好きの人だけ検索するには、 jyangule_pさんの例題だと検索できないので、区切記号を『/』にしています。 実際にDBに書き込む内容は、 1 | '/サッカー/野球/バスケ/' となります。 こうすると、後でサッカー好きの人だけ集めたければSQL文で where column_name like '%/サッカー/%' という具合に検索かけられます。

jyangule_p
質問者

お礼

nikuq様 有難う御座いました。 前者でも可能との事ですが、 データの修正が、面倒のようですね。

  • fxdwg99
  • ベストアンサー率45% (43/94)
回答No.2

DBを設計する際には、データを取り出してどう使いたいかを 考えるべきです。従って、その二つのどちらが良いかは、 どう使いたいか次第と言えます。 が、自分が設計するなら後者ですね。前者の方法では柔軟性が 全くないに等しいですから、SQL文であれこれしたくても できませんし。

jyangule_p
質問者

お礼

fxdwg99様 有難う御座いました。 >データを取り出してどう使いたいかを 考えるべきです。 確かにこれが重要ですね、まだ漠然としている状態ですが。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

リレーショナルデータベースには「正規化」という 考え方があります。 検索性、保守性を考えれば後者になるとおもいます。 実際に運用するはもうちょい工夫が必要になるかと おもいますが。

jyangule_p
質問者

お礼

yambejp様 有難う御座いました。 自分も正規化を考えると、後者かなと思っておりましたが。。。

関連するQ&A

  • DBの設計について

    MySQLの設計について質問があります。 まずDBの設計ですが以下のような場合どのようにすればよいのでしょうか? 1. 商品情報が数十万件あり、商品DBを作ってその中に全商品を登録するテーブルを作る 2. 各会員が上記の中から自分が扱いたい商品を登録するテーブルが必要 このとき、2.のテーブルは、  A. 1.のDBの中に作る  B. 各会員のDBを作ってその中に扱いたい商品のテーブルを作る  C. 会員DBを作って会員ごとのテーブルを作る のどれが正しいのでしょうか?各会員が扱う商品数も数万~数十万件になります。 どうぞよろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • DB設計についてアドバイスお願いします。

    作成するアプリケーションは簡単なスケジュール管理のできるWEBアプリケーションです。 以下、作成予定のテーブルです。 <tbl_date> id VARCHAR(50) ・・・PRIMARYKEY / not null / AUTO INCREMENT date VARCHAR(8) ・・・not null <tbl_schedule> id VARCHAR(50) ・・・PRIMARYKEY 、not null 、AUTO INCREMENT morning VARCHAR(50) afternoon VARCHAR(50) evening VARCHAR(50) 以下、ページ詳細です。ユーザー側と管理側に分けています。 <ユーザー側> 1ページ目 ⇒はじめのページで日付を選択する。プルダウンメニューで日付を選択してsubmitボタンを押すと選択された日付がDBに登録され、次の画面に遷移する。 2ページ目 ⇒登録されているスケジュールをDBから呼び出して表示する。 <管理側> 1ページ目 ⇒はじめのページで日付を選択する ※ユーザー側とは別のページ 2ページ目 ⇒スケジュールの編集画面。テキストフォームと登録されているスケジュールをDBから呼び出して表示する。 DB設計は初挑戦なので見当違いなところ多くあると思います... ご指摘、アドバイス等いただけたらと思います。よろしくお願いいたします。

  • Accessで1つのフィールドに複数の選択肢を設ける

    Accessで、1つのフィールドで複数選択可能な選択肢を設ける方法はあるのでしょうか? たとえば、スタッフのシフトを表す「何時から何時」という項目を複数作りたいのです。 自分の想定しているものでは、チェックボックスで複数選択できるようにしたいと思っています。 テーブルでできなくても最終的にフォームで登録時に実現できればいいと思っています。 アドバイスをよろしくお願い申し上げます。

  • DB設計に要する見積もりについて

    新規のシステムで、全体の見積もりを行う中で、DBだけに注目して容量の算出、テーブル作成、正規化等プログラミングする前にいろいろやる事があると思いますが、その部分だけの作成にはどのような情報があれば、工数を算出できるのでしょうか? 勿論、テーブルの数や名前、その中の項目数や項目名、収まるデータ量なんか はDB作成以前の設計段階での工数見積もりに入ってくると思うので、ここでは DB見積もりから除外して考えております。 宜しくお願い致します。

  • 人気記事(ランキング)表示に関するDB設計や方法

    DBのテーブル設計と実装について教えて頂けると嬉しいです。 登録制サイトで、記事を投稿して閲覧者がお気に入りに登録できるような仕組みを作っています。 トップページ等で「人気の記事」を表示する際、お気に入り登録数が多いものを表示させたいと思っています。 このような場合、どのようなテーブル設計や方法を取るのが良いのでしょうか? 3つ方法を思いつきますが、どれも一長一短なのかなという気がしています。 (テーブル設計の例)  「posts」テーブル  : post_id, user_id, text  「favorites」テーブル: favorites_id, user_id, post_id  「users」テーブル  : user_id, user_name (方法1)お気に入り登録数をテーブルに持たない(都度カウント処理する) トップページ表示の都度、「favorites」各記事のお気に入り登録数をカウントして(post_id で group byしてcountする)、登録の多い記事を表示させます。シンプルな方法ですが、レコード数が多い場合の負荷を心配しています。 (方法2)お気に入り登録数をテーブルに持つ お気に入り登録数を「posts」テーブル内に保持させます。  「posts」テーブル  : post_id, user_id, text, favorite_count 閲覧者がお気に入り登録した場合は「favorites」テーブルへの追加を行うと供に「posts」テーブルの「favorite_count」を更新します。トップページ表示の際は「posts」テーブルの「favorites_count」を見に行って多いものを表示させるだけなので負荷の心配は減ります。しかし、冗長な?データをテーブルに持つのは何か嫌な気がしますし、またプログラム実装が少し困難になります。 (方法3)人気の記事テーブルを別に持つ バッチ処理を1日1回等走らせ、登録数の多い記事をサーチして「人気の記事」テーブルに格納します。トップページでは、この「人気の記事」テーブルを見に行って表示させるだけになりますので負荷が減ります。しかし、リアルタイムな情報を表示できないのが残念です。 環境は、MySQL5.1、PHP5.2.17 となります。 アドバイス等頂けましたら嬉しいです。

  • WEBシステムのDB設計について

    趣味でWEBによるグループウェアを作ろうと思ってます。 DB設計について質問です。 プロの方が作るシステムでは 通常、ユーザーを識別する主キーは「ログインID」でしょうか? 「ログインID」は認証用のみ使用して、識別キーは別に作ったほうが良いのでしょうか? ※ログインIDは1度設定したら変更不可にしようと思ってます。 プロの方が作るWEBシステムの、認証・ユーザーマスター部分の DB設計の定石などありましたら教えてください。 2パターン考えました。 <パターン1> ■認証テーブル 1.ログインID(主キー)※認証のみ使用 2.ログインパスワード 3.ユーザーID(外部キー)※ユーザー情報、その他の識別主キー システム自動で設定 ■ユーザーマスター 1.ユーザーID(主キー) 2.名前 3.メールアドレス 4.グループID 5.その他情報    : 6.更新日時 7.更新者 ■グループマスター 1.グループID(主キー) 2.グループ名 3.ユーザーID(外部キー)    : <パターン2> ■認証テーブルなし ■ユーザーマスター 1.ログインID(主キー)※ユーザー識別キー 2.ログインパスワード 3.名前 4.メールアドレス    : 7.更新者 ■グループマスター 1.グループID(主キー) 2.グループ名 3.ログインID(外部キー)    : ご指導いただけたら嬉しいです。

  • DB設計方法

    MS-SQLServer7.0を使用してASPと連動したHPを製作しております。 1つの製品情報に複数の製品カテゴリ(1~5個まで)と 1つのスペックを登録し、このデータベースから製品カテゴリの前方一致検索を可能にする場合、製品カテゴリは別テーブルにあると仮定して列名を次のうちどちらにしたほうが良いか教えてください。 =====例1===== 製品ID|カテゴリID|スペック| =====例2===== 製品ID|カテゴリID-1|カテゴリID-2|カテゴリID-3|カテゴリID-4|カテゴリID-5|スペック|

  • チェックボックスで渡ってきたデータを一つのフィールド(や変数)で処理したい

    特にPHPに限った質問というわけではないのですが、複数のチェックボックスからのデータをmySQLにためて、ユーザーが検索できるプログラムを作っています。 チェックボックスの数があまり多くないので、項目ごとにフィールドを追加してやってもいいのですが、あまりスマートではないし、後で項目の追加があった場合に対応できないので、一つのフィールドにすべてのチェックボックスのデータを納めたいと思っています。 一般的にこのような場合、どのように処理するのでしょうか? 方法を考えたのですが、チェックボックスのvalueに value=1 value=2 value=4 value=8・・・として、チェックがある項目は全部足して2進数に変換してDBに登録し、(例えば、value=1とValue=8にチェックがあったら9となり、2進数では1001でonが判別できます)ユーザーが検索するときには同じく検索条件を2進数に変換して論理積で1以上のものを抜き出せば自分の想像通りの動きはしそうです。 ただ、DBから抜き出すときにいちいち論理積でパターンマッチしたものを抜き出す必要があるので、あまり高速ではない(?)&SQL文一発で書けないのでちょっと処理が面倒かなと思っています。 ちょっと説明がうまくできなくてわかりづらいとは思いますが、何かいい方法はないでしょうか?

    • ベストアンサー
    • PHP
  • 項目があったりなかったりするテーブル設計について。

    伊藤と申します。 postgreSQL7.2.2を使用して、Webアプリケーションを制作しています。 テーブル設計で迷っているところがあります。 HTMLのフォームのデータを取り込み、データベースに格納する、 と言う事をしたいのですが、クライアントが自由に フォームの内容を変えることができるようになっています。 そこで、変わったパターンが出てきてテーブル設計に困っています。 Radioボタンが3つあるとします。 1番目と2番目がチェックされるときは問題ないのですが、 3番目をチェックしたときにはさらに、 テキストボックスに入力を求められる事があるのです。  下記のような場合が問題になります。 ==================================== Q2 あなたのすきな食べ物は? ○りんご ○みかん ○その他 ↓下のボックスに入力してください  ______________ |______________| ==================================== 以下が現状です。 ■環境 OS:Turbolinux 7 Server DBサーバ:postgreSQL ■テーブル ・質問テーブル ・質問選択肢テーブル ・回答テーブル ■キー 質問テーブルの主キー(質問ID)に対して、 質問選択肢テーブルにある外部キーがリレーションします。 質問選択肢テーブルにはシーケンスもあり(選択肢No)、 質問IDと選択肢Noで主キーとしています。 ■問題 ・例外的な選択肢追加を(ある選択肢に対して並行に)  可能にするには質問選択肢テーブルをどう設計すればいいのか。 ・回答テーブルに通常なら選択された値をレコードに  格納するだけだが、  ひとつ項目が増える事もイレギュラー的に発生するので、  回答テーブルどう設計するか。 以上2点です。 長くなって申し訳ありません。 ご教授よろしくお願い申し上げます。

  • データベースの設計について教えてください。

    データベースの設計について教えてください。 基本的な質問ですみません。宜しくお願いいたします。 単純なテーブルで表現しますが、 パターンA、Bのどちらのテーブルで設計するのが良いのでしょうか。 DBはmysqlで5000万件のデータで検索のみのデータベースです。 【前提】 ユーザは複数のメールアドレスを持ちます。 画面から、このユーザのもつメールアドレスを表示させる仕様だとします。 【userマスタ】 (PK)ユーザID   ユーザ名   会社名 <パターンA> 【mailテーブル】 (PK)ユーザID (PK)ユーザメールアドレス   モバイル用アドレス <パターンB>  【mailテーブル】 (PK)ユーザメールアドレス   モバイル用アドレス   ユーザID ←インデックスをはります。

    • ベストアンサー
    • MySQL