PHP+MySQLで複数ページにまたがるWebアンケートの作成を考えています。

書籍とサイトを参考にして「フォーム入力→DBへ登録→header:locationでリダイレクト」という流れは作成できたのですが、各ページの回答に同じIDがつきません(当たり前ですが)。IDはAuto Incrementに設定しています。そのため、以下の疑問についてお分かりの方、ご教示ください。
質問の仕方、情報提供など不適切な点があればご指摘頂ければ幸いです。

1.どのようなフローが適切でしょうか?
すべての回答をセッションで管理して、最後の確認時にDBに登録すれば同じIDがつくのでしょうか。
それとも、一意の何かをセッションで保有して、都度登録するものでしょうか。

2.DBを利用したこうしたサイト作成に際しての一般的な注意点・守るべき事項があればお教えください。
参考サイト等でも結構です(あまり網羅的なものは厳しいです・・・)。

よろしくお願いします。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2012/02/26 19:00:54
  • 終了:2012/02/27 22:59:29

ベストアンサー

id:windofjuly No.1

うぃんど回答回数2625ベストアンサー獲得回数11492012/02/26 19:21:46

ポイント120pt

フローは、すでに挙げておられるように、おおよそ下記のどちらかですね

(a)データは全てセッションで管理して、
  最終項目の入力が終わった時点で、テーブルに一括登録
  構造が簡単なのが最大の利点

(b)セッションでは投稿者IDみたいなものだけを管理して、
  その都度、一時登録用のテーブルに保管しておいて、
  最後に本登録用のテーブルに書き込む
  瞬間的な通信エラーなどが起こっても再開を可能にすることが出来るなど、
  利用者側からみても処理の中断/再開なども実現できて利便性は増しますが、
  構造は複雑になります

どちらを選択すべきかですが、
項目が非常に多く、途中トラブルで一からやりなおしは避けたいとか、
ミッションクリティカルなものとかでなければ、おおよそ(a)で問題ないはずですよ

特に注意すべき点としては、
途中で止まってしまった場合に備えてログ出力するようにしておくとか、
バックアップはどのような時点で行うようにすべきかくらいですね
もっと上のレベルになると、サーバーの冗長化(常に予備を動かす)とかになっちゃいます・・・

id:qcmqem

ありがとうございます。
今回作成するものはやり直しがクリティカルな問題にはならないと考えていますので、提案頂いた(a)の方の、セッション変数として値を保持して最後に書き込むフローにしようかと思います。
ログ出力とバックアップは、できる範囲でやろうと思います。

冗長化が必要なほどのレベルのものではないと思います・・・

2012/02/27 22:20:00

その他の回答(1件)

id:windofjuly No.1

うぃんど回答回数2625ベストアンサー獲得回数11492012/02/26 19:21:46ここでベストアンサー

ポイント120pt

フローは、すでに挙げておられるように、おおよそ下記のどちらかですね

(a)データは全てセッションで管理して、
  最終項目の入力が終わった時点で、テーブルに一括登録
  構造が簡単なのが最大の利点

(b)セッションでは投稿者IDみたいなものだけを管理して、
  その都度、一時登録用のテーブルに保管しておいて、
  最後に本登録用のテーブルに書き込む
  瞬間的な通信エラーなどが起こっても再開を可能にすることが出来るなど、
  利用者側からみても処理の中断/再開なども実現できて利便性は増しますが、
  構造は複雑になります

どちらを選択すべきかですが、
項目が非常に多く、途中トラブルで一からやりなおしは避けたいとか、
ミッションクリティカルなものとかでなければ、おおよそ(a)で問題ないはずですよ

特に注意すべき点としては、
途中で止まってしまった場合に備えてログ出力するようにしておくとか、
バックアップはどのような時点で行うようにすべきかくらいですね
もっと上のレベルになると、サーバーの冗長化(常に予備を動かす)とかになっちゃいます・・・

id:qcmqem

ありがとうございます。
今回作成するものはやり直しがクリティカルな問題にはならないと考えていますので、提案頂いた(a)の方の、セッション変数として値を保持して最後に書き込むフローにしようかと思います。
ログ出力とバックアップは、できる範囲でやろうと思います。

冗長化が必要なほどのレベルのものではないと思います・・・

2012/02/27 22:20:00
id:oil999 No.2

oil999回答回数1728ベストアンサー獲得回数3202012/02/26 23:42:06

ポイント80pt

1.どのようなフローが適切でしょうか?

2通りの考え方があります。

  1. すべての回答をセッション変数に持たせる
  2. すべての回答をサーバ側の一時ファイル(または作業用テーブル)に持たせ、セッションIDで紐づける

1.はコーディングは楽ですが、通信量が増えますし、SSL通信でないと回答内容が盗み見られるという恐れがあります。
2.はコーディングは複雑ですが、通信量は少なく、回答内容が盗み見られる可能性も低くなります。

2.DBを利用したこうしたサイト作成に際しての一般的な注意点・守るべき事項があればお教えください。

  1. DBロックを防ぐ:前述のように、セッション変数または一時ファイルに持たせ、最終的な確定操作でDB登録した方がいいです。
  2. ブラウザの戻るボタンを押したときの対処:一般的には、戻るボタンを押下された場合にはアンケートは最初からやり直しという形にします。
  3. セッション切れ対策:セッション継続時間を決めておき、それを超えたらセッション変数または一時ファイルは破棄するようにします。
  4. インジェクション対策:不正な入力値が送られてきた場合にプログラムの制御を奪われないようにします。
  5. セッション・ハイジャック対策
他2件のコメントを見る
id:windofjuly

コメントしているのは回答No.1と同じくwindofjulyです
アイコン(私のアイコンは?が!に変わっていくアニメGIF)にマウスをしばらく置くと、アカウントが出てきます

実際の対応としては、コメント欄のほうで、くろふね(id:jranar)さんが書いてくださっているので、そちらを参考になさるとよろしいでしょう
私からも回答リクエスト送ってみますが、お忙しかったりして回答できないこともあると思いますので、この質問をキャンセルして別途ポイント送信でお礼を述べるという方法を取っても良いとは思います

2012/02/27 22:28:03
id:qcmqem

はてなの仕様がわからず失礼しました。アイコンで識別できたのですね。
くろふね(id:jranar)さんからも返信頂けたので今回の質問は終了とさせて頂きます。
ありがとうございました。

2012/02/27 22:57:46
  • id:jranar
    仕様がわからないので回答しようがないと思います。

    不明点1:IDとはなんのためのIDなのでしょうか?
    不明点2:どのようなテーブル、カラム、主キーが用意されているのでしょうか?
  • id:qcmqem
    ご指摘ありがとうございます。要領を得ない質問ですみません・・・

    >不明点1:IDとはなんのためのIDなのでしょうか?
    回答者の特定を意図した連番のID(整数)ですが、現状、各テーブルで自動的に増えていっています。主キーにしています。

    >不明点2:どのようなテーブル、カラム、主キーが用意されているのでしょうか?
    アンケート自体が大きく4つの要素があるので4つのテーブルを作成し、各10~20のカラムでテキストや数値を入れる予定です。
    主キーは上記の通り連番のID(整数)としています。
    それぞれのテーブル間で同じ回答者の回答を特定するのが希望です。

    書き忘れていましたが、ひとり1回の回答のみを想定しています。
  • id:jranar
    4つのテーブルすべてにIDがあって、すべてAUTO_INCREMENTなのですか?

    それだと仮に最終ページでまとめて登録したとしても、複数ユーザが同時に登録した場合に各テーブル間でIDが異なってしまう可能性がありますよね。

    そういう場合は

    【事前準備】
    A、B、C、Dというテーブルが4つある場合、最初に登録するテーブルのみAUTO_INCREMENTにする(とりあえず最初に登録するテーブルをAとします)。
    あとデータは最終ページですべて登録する形に変更。


    【最終ページでの登録処理】
    (1)AテーブルにINSERT
    (2)B、C、DテーブルにINSERT。ただしIDはLAST_INSERT_ID()を設定しINSERTする。

    という感じです。(1)~(3)は1回のCONNECT~DISCONNECTで行なってください。


  • id:qcmqem
    ありがとうございます。
    ご指摘の通り、各テーブル間でIDが異なってしまうことが不安でした。
    具体的には複数ユーザが同時に登録した際に、入れ子状態でIDが前後してしまう(可能性がある)、ということでしょうか。
    今まで特にDBへの接続の切断を明示していなかったのですが、「1回のCONNECT~DISCONNECT」というのは
    1.mysql_connectで接続
    2.INSERTで登録
    3.mysql_close(?)で切断
    という流れにすると、排他的な処理になるため、LAST_INSERT_ID()には必ず最初に登録するテーブルと同じIDが入っているので、各テーブルでIDを共通にできる、という理解でよいでしょうか。
    お教え頂ければ幸いです。

    #よろしければ回答として登録頂けますでしょうか(ポイントが付けられないようですので・・・)
  • id:jranar
    > 具体的には複数ユーザが同時に登録した際に、入れ子状態でIDが前後してしまう(可能性> がある)、ということでしょうか。

    試しているわけじゃないですけど、そうなる可能性があると思います。

    > 1.mysql_connectで接続
    > 2.INSERTで登録
    > 3.mysql_close(?)で切断

    そうです。そうすればエラー発生したタイミングですべてロールバックもかけられますのでゴミデータも残りませんし、LAST_INSERT_ID()はcloseするまで最後にAUTO_INCREMENTした値が維持されるとのことです(これも試したわけでなくドキュメントを見て確認した程度です)。


    で、私は特にポイントが欲しいわけでもないですし、検証もしてないので誤っている可能性もあるわけですから上で回答している方にあげてください。
    よろしくおねがいします。
  • id:qcmqem
    非常に具体的に手順を教えて頂いたので大変助かります。
    LAST_INSERT_ID()で希望の動作が実現できそうです。
    ポイントについても寛大な対応を頂き感謝致します。
    ありがとうございました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません