- ベストアンサー
DB設計について
ユーザー情報などで、チェックボックスで複数選択してもらった項目を DBへ登録する場合どのように、テーブルを作るのが良いのでしょうか? 例えば、一つのフィールドに、選択してもらった項目を user_id hoby 1 'サッカー,野球,バスケ' などと入れるのがいいのか、 別の、テーブルを作って、 user_id hoby 1 サッカー 1 野球 1 バスケ この方がよいのか、どちらがよいのでしょうか、よろしくお願いいたします。
- みんなの回答 (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回に分けたりする必要があるんではないかな?
その他の回答 (6)
- yambejp
- ベストアンサー率51% (3827/7415)
>hoby[0]['サッカー'],hoby[1]['野球'],hoby[2]['バスケ'] ではなく hoby[$user_id][0]='サッカー'; hoby[$user_id][1]='野球'; hoby[$user_id][2]='バスケ'; ・・・・ とすべきではないでしょうか?
補足
yambejp様 有難う御座いました。 配列の書き方が、変でした。
- galluda
- ベストアンサー率35% (440/1242)
がるです。 > データを取り出すして、 > 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; という風になさるとよろしいかと思います。 で、データを並べ替えたら、後はプログラム側で好きな形の配列にいれるとよろしいかと思います。
補足
がる様 有難う御座いました。 すいません、言葉が足りませんでした、 配列の順番は、今のところ考慮しておりませんが、 下記のように、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)
がると申します。 基本的には後者がよろしかろうかと。検索その他を考えて、前者のメリットはないに等しいので。 ただ、レコード数制限などの観点から後者がチョイスできない場合に前者のような持ち方をしないわけではないです…が、レコード数が溢れたらもうちょっと抜本的に色々対策を練りますねぇ(苦笑 といった思考過程から、私は後者に一票を投じます。
補足
がる様 有難う御座いました。 やはり、後者のようですが、 後者の場合気になったのが、SQL文の組み立てですが、 データを取り出すして、 hoby[0]['サッカー'],hoby[1]['野球'],hoby[2]['バスケ'] としたい場合には、どうすればよろしいでしょうか、 よろしくお願いいたします。
- nikuq
- ベストアンサー率22% (8/36)
それぞれ一長一短がありますが、私は前者の方法で使っています。 前者の長所は、レコード数が少ない事と、修正がラクチンな事です。 ユーザがのちのちに変更しても、同じレコード内にあるデータを書き換えるだけですからね。 短所は、Indexが効かない事ですね。fulltextでも日本語はダメなので。 それと、サッカーが例えばテニスに変更した場合には修正がめっちゃくちゃ面倒な事になりますね。 後者の一長一短は前者のまるっきり反対になると思います。 後者の長所は、Indexが使える事です。ユーザID等のユニークなIDを英数字で紐付けすれば Indexが使えます。 短所は、レコード数がむちゃくちゃ増える事ですね。 1ユーザが3項目選択するとそのまま3レコード増える事になります。 そのぶん、直接DBを管理する時に非常に乱雑になると思います。 ユーザが修正かけてもいちいち全レコードからユーザIDで抽出し、1レコードずつ修正しなくては いけません。 そのかわり、前者の例のように、まとめて変更する時は楽です。 という事から、ユーザ情報のDBだとすると、将来、どれくらい ユーザが増えるかによって、決めた方がいいと思います。 ちなみに、前者の場合で、例えばサッカー好きの人だけ検索するには、 jyangule_pさんの例題だと検索できないので、区切記号を『/』にしています。 実際にDBに書き込む内容は、 1 | '/サッカー/野球/バスケ/' となります。 こうすると、後でサッカー好きの人だけ集めたければSQL文で where column_name like '%/サッカー/%' という具合に検索かけられます。
お礼
nikuq様 有難う御座いました。 前者でも可能との事ですが、 データの修正が、面倒のようですね。
- fxdwg99
- ベストアンサー率45% (43/94)
DBを設計する際には、データを取り出してどう使いたいかを 考えるべきです。従って、その二つのどちらが良いかは、 どう使いたいか次第と言えます。 が、自分が設計するなら後者ですね。前者の方法では柔軟性が 全くないに等しいですから、SQL文であれこれしたくても できませんし。
お礼
fxdwg99様 有難う御座いました。 >データを取り出してどう使いたいかを 考えるべきです。 確かにこれが重要ですね、まだ漠然としている状態ですが。
- yambejp
- ベストアンサー率51% (3827/7415)
リレーショナルデータベースには「正規化」という 考え方があります。 検索性、保守性を考えれば後者になるとおもいます。 実際に運用するはもうちょい工夫が必要になるかと おもいますが。
お礼
yambejp様 有難う御座いました。 自分も正規化を考えると、後者かなと思っておりましたが。。。
補足
stein_JP様 有難う御座いました。 チェックが多いいとSQL文もかなり長くなりそうですね。