5

スタッカーの挨拶、

私は、ユーザーが調査を作成して一般に公開できるようにするアプリケーションに最適なデータベーススキーマを考え出そうとしています。名、姓など、ほとんどの調査(すべてではない)に含まれる「標準」の人口統計フィールドがたくさんあります。もちろん、ユーザーは無制限の数の「カスタム」質問を作成できます。

私が最初に考えたのは次のようなものです。

Survey
  ID
  SurveyName

SurveyQuestions
  SurveyID
  Question

Responses
  SurveyID
  SubmitTime

ResponseAnswers
  SurveyID
  Question
  Answer

しかし、それは私がデータを照会したいときはいつもひどいことになるでしょう。そして、それは危険なほど内部プラットフォーム効果に近いようです

改善点は、応答テーブルに事前に考えられる限り多くのフィールドを含めることです。

Responses
  SurveyID
  SubmitTime
  FirstName
  LastName
  Birthdate
  [...]

そうすれば、少なくともこれらの一般的な列からのデータのクエリは簡単です。たとえば、誕生日を出した調査に回答したすべての人の平均年齢をクエリできます。

しかし、これはコードを少し複雑にするようです。ここで、調査でどの質問が行われるかを確認するには、有効になっている一般的な回答フィールド(Surveyのビットフィールドを使用)とSurveyQuestionsテーブルの内容を確認する必要があります。また、Responsesテーブルの「一般的な」質問と重複する「カスタム」質問を誰かが作成しようとした場合など、特殊なケースについて心配する必要があります。

これは私ができる最善のことですか?私は何かが足りないのですか?

4

4 に答える 4

5

2 つのスキーマのうち、最初のスキーマの方が適しています。この時点では、パフォーマンスの問題について心配する必要はありません。優れた、柔軟で拡張可能な設計を作成することに注意してください。データをキャッシュしてクエリを高速化するために後で実行できるあらゆる種類のトリックがあります。実現さえしないパフォーマンスの問題を解決するために、柔軟性の低いデータベース スキーマを使用することは、悪い決定です。

さらに、多くの (おそらくほとんどの) 調査結果は定期的に少数の人々 (イベント主催者、管理者など) によってのみ表示されるため、すべての結果についてデータベースに常にクエリを実行する必要はありません。たとえそうであったとしても、パフォーマンスは問題ありません。とにかく、何らかの形で結果をページ付けするでしょう。

最初のスキーマはより柔軟です。デフォルトでは、名前や住所などの質問を含めることができますが、匿名のアンケートの場合、それらを作成することはできません. 調査の作成者が、500 の質問のうち 3 つの質問に対する全員の回答のみを表示したい場合、それは非常に単純な SQL クエリです。カスケード削除を設定して、調査が削除されたときに回答と質問を自動的に削除することができます。このスキーマを使用すると、統計の生成もはるかに簡単になります。

これは、提供されたスキーマのわずかに変更されたバージョンです。どのデータ型がどこに行くのかを理解できると思います:-)

    調査
      調査 ID (インデックス)
      題名

    質問
      question_id (インデックス、自動インクリメント)
      survey_id (surveys->survey_id へのリンク)
      質問

    反応
      response_id (インデックス、自動インクリメント)
      survey_id (surveys->survey_id へのリンク)
      submit_time

    答え
      answer_id (インデックス、自動インクリメント)
      question_id (questions-question_id へのリンク)
      答え
于 2009-01-09T20:23:39.103 に答える
1

常にデータベース スキーマに対して正規化されたアプローチを採用し、後でパフォーマンス上の理由からソリューションを作成する必要があるかどうかを判断することをお勧めします。時期尚早の最適化は危険です。データベースの正規化解除が早すぎると、悲惨な結果になる可能性があります。

元のスキーマをそのまま使用し、後で必要に応じて、正規化されたスキーマの非正規化バージョンであるレポート テーブルを作成することをお勧めします。

于 2009-01-09T19:59:08.467 に答える
1

単純化に役立つかもしれないし、そうでないかもしれない変更の 1 つは、ResponseAnswers を SurveyID にリンクしないことです。代わりに、応答ごとおよび質問ごとに ID を作成し、ResponseAnswers テーブルに ResponseID、QuestionID、Answer フィールドを含めます。これには、各ユニットに一意の識別子を保持する必要がありますが、物事をもう少し正規化するのに役立ちます. 回答の回答は、回答している特定の質問と関連付けられている回答情報だけに回答していた調査に関連付ける必要はありません。

于 2009-01-09T20:08:56.717 に答える
0

私は前職で顧客調査システムを作成し、あなたが持っているものと非常によく似たスキーマを思いつきました. アンケートを(紙で)送信し、回答を集計するために使用されました。

いくつかの小さな違い:

  • 調査は匿名ではありませんでした。これは、印刷されたフォームで非常に明確にされました。また、例の人口統計データが事前にわかっていたことも意味します。

  • 調査に添付された質問のプールがあったため、1 つの質問を複数の調査で使用し、それが表示された調査とは別に分析することができました。

  • さまざまなタイプの質問を処理することは興味深いものでした。1 ~ 3 の尺度 (例: 悪い/同じ/良い)、1 ~ 5 の尺度 (非常に悪い、悪い、OK、良い、非常に良い)、はい/いいえ、およびコメントがありました。 .

    コメントを処理するための特別なコードがありましたが、他の質問タイプは、質問タイプのテーブルと各タイプの有効な回答の別のテーブルを持つことにより、一般的に処理されました。

クエリを簡単にするために、調査 ID と質問 ID に基づいて応答を返す関数を作成できます。

于 2009-01-09T20:11:16.103 に答える