• ベストアンサー

最適なDB Table作成

現在以下のシステムを作成しているのですが、データベース設計に悩んでいます。 システムはユーザーが自由に作成&カスタマイズできるアンケートです。 例えばデフォルトはアンケート項目が 名前 数字 年齢 数字 興味のある物 チェックボックス とします。 でユーザーはこのアンケート項目を自由にカスタマイズできます。 デフォルト時のDBでは userform ユーザーID | 変更日 | 項目 | 項目名 | 条件 | 掲載日 userid | 200812 | name/age/interestings/ | 名前/年齢/興味のある物 | num/num/cb/ | allrequired | 200901 と成っています。  ここでユーザーが名前と年齢の間にフリガナを追加した際、DBでは変更日と項目、項目名、条件が書き換えられます。 アンケートを表示すると、PHPで動作するスクリプトがユーザーのレコードを読み込み、各項目をHTMLに変換、表示します。 そしてデータを収集する方ですが、DB構成は以下になります。 ユーザID | データ入力日(int) | 結果(text) | IPアドレス データが入力されると datadb userid | 20081209 | 佐藤/25/computer | 123.123.123 となり、データ集計プログラムをブラウザで表示すると、SELECT * FROM datadb WHERE userid = "userID" と SELECT * FROM userform WHERE userid = "userID"を発行し、PHPでデータをソートし表示します。 しかし以上の構成だと、途中でアンケートの項目を追加&削除したり変更することはできず、使い勝手が悪くなります。 仮にuserformのカラムをユーザーアンケート項目の追加、削除のたびにAlterで追加、削除てしまう方法も頭に浮かびましたが、そうすると別のユーザーにもその追加したカラムを適用してしまうためNGです。 どのようにすればユーザーアビリティも保て、中規模なシステム利用でも耐えることが出来るできるDBを作成できるのでしょうか? よろしくお願いいたします。

  • MySQL
  • 回答数4
  • ありがとう数0

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

  • ベストアンサー
  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.3

 わたしなら、次のような構成を考えるでしょうか・・・  ・ユーザーテーブル   userid int username char2 以下略  ・アンケート質問票   userid int qno int qcont char2 qstatus bool (必須か否か)  ・アンケート結果表   userid int ansuserid int (回答者の個別id・単なる通し番号でokか?) qno int   ans char2  と3つにわけます。  アンケート結果表のansuseridは、回答者ごとに通し番号を打っておけばokかと。  ユーザー表の主キーは、useridで、アンケート質問票の主キーは、(userid,qno) 、アンケート結果表の主キーは、(userid, ansuserid,qno)となります。アンケート質問票の外部キーとして、ユーザー表.useridを、アンケート結果表の外部キーとして、(アンケート質問票.userid, アンケート質問票.qno)を指定することになると思います。  あるユーザーのアンケートを表示するには、  select a.userid, b.qno, b.qcont, b.qstatus from ユーザー票 a, アンケート質問票 b where a.userid=b.userid, a.userid=パラメータ  となりますし、アンケートの結果を表示するには、  select a.userid, b.qno, c.ansuserid, c.ans from ユーザー表 a, アンケート質問票 b, アンケート結果表 c  where a.userid=b.userid and b.userid=c.userid and b.qno=c.qno and a.userid=パラメータ  order by a.userid, b.qno  くらいとなるでしょうか。  ユーザーの属性とアンケートの属性、それに結果表の属性をすべて分離し、アンケートの質問は各設問に対して一つのレコードを割り当てているのがポイントです。  利点は、どんな時点であれ、設問数・内容を各ユーザーが自由に加除できるところでしょうか。(ただし、すでに回答が入っている設問を操作(削除・更新)すれば設問と回答が整合しなくなりますから、そのときには古い回答は削除する処理が別途必要でしょう。でも設問の追加はこのような考慮は不要です。qnoを新たに発行すればすみますから。)  用途には合いますでしょうか?

その他の回答 (3)

  • kuroizell
  • ベストアンサー率55% (95/170)
回答No.4

LimeSurvey、phpESPなどの既存のOSSアンケートシステムを使うとか。 テーブル構造の参考にもなると思います。

  • hrm_mmm
  • ベストアンサー率63% (292/459)
回答No.2

正規化を行いましょう。 参考 http://www.ddsystems.info/ex/ex_db/400101.html 最低でも、user 情報table と、項目情報table(アンケート項目ごとに1レコード登録) と、userid に対して項目idを登録するためのtable の3つ必要でしょう。 あとは、適宜join すれば、select文で必要なデータの取り出しは可能です。

  • denbee
  • ベストアンサー率28% (192/671)
回答No.1

思い付きですが、ユーザがカスタマイズしたい質問項目は 別テーブル(例えばoptiontable)に生成し、 userformには、このテーブルのID項目(例えばoption_id)を追加し、 そちらで連携を取るようにするのはどうでしょうか? PHPのスクリプトはoption_idを確認し、そちらに項目があれば その項目をHTMLに追加します。これなら、ユーザごとに 個別の質問項目が作れると思いますが。

Intel_404
質問者

補足

ご回答ありがとうございます。 なるほど、別テーブル策ですね。 一応最大項目数は制限するつもりなので、別テーブルに格納するのもいいかもしれません。そうすると以下のテーブルが思いつくのですが、どうでしょう? Koumoku userid | 項目1の名前 | 項目1の形式 | 項目1の条件 | 項目2..... userid | 名前 | Number | required | 出身 | CheckBox | notRequired ... よろしくお願いいたします。

関連するQ&A

  • WEB→DBの作成について

    WEB→DBの作成について 趣味でHPを作成するレベルで以下機能を作成する事になり、調べてみましたが行き詰まりました。 項目が多いのですが「ここは知ってる」という所だけでも構いません。ぜひお助け頂けませんでしょうか。 300人くらいのデータの入ったDBをWEBページから操作するシステムを作成。 操作は、登録と、登録データの呼び出し(条件検索によってデータを抽出できるようにしたい)を行う。1人に対して、名前、生年月日、性別など、20程の項目を設定する。 【ページA】500人の名前、生年月日、性別など5~6項目が一覧で出るページ NO. 名前 生年月日 性別  住所・・・ 1  山田 1980.1.1  女  東京 2 田中 1990.5.5  男 沖縄 3 鈴木 1985.9.9  男  香川 ◎このページに、性別「男」だけのレコードを表示する、等の抽出機能を作成したい。 ◎会員NO.をクリックするとページB 遷移させたい。 ◎抽出結果をExcelでダウンロードしたい。 【ページB】Aから選んだ1名だけの20項目が出るページ。 ここで表示させたデータを操作し、変更した内容をDBに登録するボタンを作成したい。 ◎このページの項目に対し、ログインユーザーによって登録できる項目、できない項目を作成したい。 <疑問点> 1.htmlとxmlどちらがよいのか。htmlとxmlの差異で使えない機能があるのか。 2.データの呼び出し・格納をするので、phpかjavaが必要になるか。どちらがよいのか。php(java)はサーバー側に入れればよいか。 3.OSのユーザーアカウントにより、WEBページへのログイン時に制限を設定することか可能か。(phpでOSのログインユーザー名を取得し、ログインの可・不可を判定する事は可能か?)   4.3の権限を持つユーザーと、同名のOSのユーザーアカウントを本人以外が作り、ログインされる事を防ぐために、ネットワーク上で同名ユーザーアカウントを作成できないように設定したいが可能か。 5.WEBページへのアクセスを制限を設定する場合、サーバー側でどういう設定をすればよいか。ネットワークからのみ許可したい場合、ネットワーク名を設定に使用するのかhostsファイルを使用するのか。WAN設定を使用するのか。 6.1つのサーバーに複数のDBを入れて、そのうちの1つをこのシステム用として使用したい。そのDBはOracleにしたいが可能か。 7.1つのサーバーにOracleが2つ入っても大丈夫か?DBに名前を設定して区分できるか。 8.1つのサーバーに複数のDBを入れ、そのうちの1つからデータをWEBページで呼び出したい。クライアントが使用するWEBページのURLはどうなるか。 URLにはサーバーのip(ドメイン)とhtmlを指定し、サーバー内のhtml(XML)のソースに接続先DB名を指定すれば、複数あるDBから該当DBにのみアクセスできるか。 9.htmlからDBへのデータ格納失敗などのログは、サーバーのログとして残るのか。 10.ページAから1つのレコードを選び、ページB へ遷移したいが、この動作はphp(java)で可能か。可能であれば、プログラミングではどう書くか。 11.ページAでの抽出機能を、複数条件でも可能としたい。 表示項目に該当する検索用テキストボックスを作成し、入力した状態でボタンをクリックすると、該当レコードだけが検索結果として表示されるようにしたい。 [項目]          会員NO.  名前 生年月日 性別  住所 [テキスボックス]           田中       男 この状態で「検索」ボタンをクリックすると300件のレコードから、名前=田中を含む、性別=男の全レコードを表示するようにしたい。 html上でこの動作はphp(java)で可能かどうか。抽出のSQLが走るようにすればよいのか。 12.ページAで、webページで検索した結果を、Excelへダウンロードするためには、どのような設定をしたらよいか。特別に用意するツールはあるか。 Ofiiceが入っていないPCでダウンロードを行なうと、テキストなどで代替できるように設定はできるか。 13.ページBで、ログインユーザーごとに登録できる項目、できない項目を設定し、権限のない項目を変更し保存を行なうと、その時にエラーとなるようにしたい。 保存アクション時に、php(java)のif文で、全項目に対し値の有無チェックを行なう 事を考えたがもっと効率のよい方法はあるか。

  • テーブルのカラム(列)を追加したい

    お世話になります、 DBはOracle8iです。 一度作成して、データが入っているテーブルAの カラム(列)をデータをそのままにして追加できるの でしょうか? 追加前のデータにデフォルト値を与えることはできるのでしょうか? [変更前] 名前 年齢 性別 あ   1  男 い   2  女 う   3  男 ↓カラム追加 [変更後] 名前 年齢 性別 フラグ あ   1  男   0 い   2  女   0 う   3  男   0  以上のような感じにしたいのですが、 Alter table文を使うところまではわかっているのですが。。。 よろしくお願いします。

  • テーブル作成について質問があります。

    今perlでDBにデータを保存し表示する掲示板を作っています。 書き込みされるデータ(名前・タイトル・本文・URL)をまとめて管理したいです。 管理したい理由はそれぞれの書き込みに対してIDみたいなものを自動的に振り分けて、そのIDで書き込み(そのIDの行のデータ全て)を削除出来るようにしたいのです。 ID:1 名前:佐藤 タイトル:始めまして。 本文:よろしくお願いします。 URL:xxxxxxxxxxxx 等の書き込みがあった場合に、削除したいID(この場合は1)を削除の項目に入力して削除出来るようにしたいのです。 ですが、書き込む際に利用者にはIDを書かせません。書き込みされた時に自動的かつ1/2/3/4/…と順番に振り分けたいのですが、これはDBを作る上でどうにか設定できるのでしょうか?

    • ベストアンサー
    • MySQL
  • DBの環境変数について

    OracleのユーザIDやパスワード等がかかれている環境設定専用のファイルを読み込み、 環境変数に読み込んだ内容をセットし、DBからデータを抽出するというサブルーチンを作っています。 ファイルを読み込み、環境変数にセットするところまでは動くのですが、 DBからデータを抽出することができません。 ただし、ファイルを読み込まずじかにサブルーチンの中に書き込んでいると正しく抽出することができます。 原因がまったくわからないので、アドバイスをお願いします。 -----以下環境ファイル読み込みプログラムの一部----- my $env_file= '○/△/■';←環境設定のファイルパス open(KAN, $env_file); while(<KAN>){ ($name, $val) = split(/=/, $_);←環境ファイルを=で分割 chomp($val); $kankyou{$name} = $val; ←取得したものをハッシュに } close(KAN); $ENV{'userid'} = $kankyou{'db_userid'}; $ENV{'passwd'} = $kankyou{'db_passwd'}; $ENV{'dbstring'} = $kankyou{'db_dbstring'}; このあとDBからのデータ抽出処理実行と続く ---------------------------------- ---ここから環境ファイルの内容--- db_userid=AAA db_passwd=BBB db_dbstring=CCC ↑この内容を下記の書き方でサブルーチンの中で直接書くと動く。 $ENV{'userid'} = 'AAA';

    • ベストアンサー
    • Perl
  • Win NTとSolarisのネットワークでユーザーDBを同期させるには?

    Win NTのPDCでユーザーアカウントDBに新規追加やデータの変更や削除を行った際、同じネットワークに接続されているSolarisマシーン上のユーザーDBのほうも同様に追加や削除を行わなくてはなりませんが、NT上で変更したデータをSolarisのDBに同期させるいい方法はありますでしょうか?NW管理者の方で同じようなことをしていらっしゃる方がおりましたら、ご教授ください。これを実現するためにはやはり、プログラムを作成しなくてはならないでしょうか? よろしくお願いいたします。

  • .netでのDB連携

    ASP.netのVB.NETを勉強していて簡単なシステムを作成しています。 簡単な帳票にデータを登録したり編集、削除したりするものです。 DB接続はできたのですが、DBからデータを呼び出す表示、イベントによるDBにデータを登録、そしてDBのデータを編集、削除する方法がみえてきません。 SQLのクエリを使用して行うのでしょうか? SELECT 呼び出す列 FROMテーブル  これだけではよびだせませんでした。 すいませんが、知恵をかしてください。 DB接続を行った後、

  • DBのアクセスサンプルがほしい 

    DBの検索を以下のロジックでレコードを検索したが、新規(登録)、修正(更新)、削除のロジック・サンプルがほしい。 レコード項目は、ユーザーID(キー)、氏名カナ、氏名漢字の3項目のみのDB(アクセス)です。 MDB_Open Dim rsUserMst1 As ADODB.Recordset Dim Userselect As String Userselect = "Select * From UserMst    Where U_Userid = '" & W_UserID & "'" Set rsUserMst1 = New ADODB.Recordset rsUserMst1.Open Userselect, cn, adOpenKeyset W_UserKana = rsUserMst1!U_Userkana W_UserName = rsUserMst1!U_UserName 以上

  • DB初心者です。

    DB初心者です。 現在、システムのDBで「TERADATA」を使用しています。 データ整理という名目で、不要なテーブルやデータを削除したりしたいと思っています。 (システム稼働中で行う作業) 中には数百GB級の不要テーブルもあり、システムが稼働中の中、 気軽にDROPまたはDELETEをしていいものなのか迷っています。 (しかし、この不要テーブルはどこからも参照されません) 別なところでは、 巨大な不要テーブルを削除したら、 統計情報が変わってしまい、ローディングなどが異様に遅くなったとの話も聞いています。 システムとは関係なく、DB内での影響はあるのでしょうか?

  • テーブルのカラムの追加について

    初歩的なことかもしれませんが、下記質問について教えてください。 現在SQL Server2000の環境でDBを使用しております。 現在使用しているDBの既存テーブルに簡単なバッチファイルを使ってカラムを追加後(ALTER TABLE)、その追加したカラムにデフォルト値やそのテーブルにレコードを追加しようとしています(個々までバッチ処理: 今回試したのは、クエリアナライザにて試験的に行っています)。 ただ、カラムの追加までは可能ですが、デフォルト値やレコードの追加を行うと「追加したカラムが無効です」というエラーが表示されます。 恐れいりますが解決策があれば、教えてください。

  • 社内DBとクラウド上のDBを同期するには?

    社内で工程管理システムが動いており、DBはPostgresを使用しています。 このデータをクラウド上にも置き、外注先からも照会、登録ができるようにしたいです。 社内とクラウド上のDBで、うまく同期をとる方法はあるでしょうか? 当然、どちらでも実績の追加だけでなく変更、削除も行います。 差分をテキストに落としてFTPで送る、ソケット通信をする、 DBのポートに穴を開けて1つのDBで運用する・・・等があると思いますが、 安全で現実的な方法があればご教示お願いします。