使用PHP和MySQL开发'测验'Web应用程序的数据库设计

时间:2011-08-18 04:49:13

标签: php mysql database database-design html-form

所以,我正在尝试学习PHP和MySQL(我对两者都有基本的了解;我已经阅读了Head First SQL和Head First PHP& MySQL的前半部分),我认为最好的方法是巩固我的知识是建立一些东西而不是阅读。

考虑到这一点,我想创建一个连接到服务器上的MySQL数据库的基本网页。我将构建一个基本的HTML表单,并允许用户输入基本信息,例如:last_name,first_name,email,birthday,gender。

我的问题我不知道如何设计一个记录基本测验结果的数据库 - 我只想要5个多项选择题。最后,我想显示用户的结果与之前用户的结果。

如果你能帮助我理解如何为一个5个问题的测验设计表格,我会很感激。谢谢!

4 个答案:

答案 0 :(得分:32)

我将从4个简单的表开始:

 * User
   - user_id    auto integer
   - regtime    datetime
   - username   varchar
   - useremail  varchar
   - userpass   varchar
 * Question
   - question_id   auto integer
   - question      varchar
   - is_active     enum(0,1)
 * Question_choices
   - choice_id        auto integer
   - question_id      integer
   - is_right_choice  enum(0,1)
   - choice           varchar
 * User_question_answer
   - user_id      integer
   - question_id  integer
   - choice_id    integer
   - is_right     enum(0,1)
   - answer_time  datetime

我对这个表设计的想法是:

  • table User用于存储注册用户。
  • Question用于存储您的所有问题。它具有is_active,因此您可以选择性地仅显示活动问题(使用WHERE is_active ='1')
  • table question_choices用于存储所有可用选项。它有is_right_choice,它定义了特定问题的正确答案选择。
  • User_question_answer用于存储用户的答案。它具有is_right以便更快地查找,以查看该特定问题和答案选择是否正确(基于先前定义的is_right_choice)。当特定用户回答问题时,它还有answer_time

答案 1 :(得分:8)

我不确定你对编程有多新,但即使你刚刚开始,我建议你使用一个框架。

使用框架将指导您提供项目中所需工具的最佳实践。

我个人使用Symfony进行php项目,我建议你查看their guides and tutorials。 Symfony是一个完善的框架,它基于广泛接受的设计。

但是,为了更直接地回答您的问题,我会为您的申请建议类似的内容:

 - user
  - id (PK)
  - last_name
  - first_name
  - email
  - gender


 - quiz
  - id (PK)
  - title


 - quiz_question
  - id (PK)
  - quiz_id (FK)
  - text

 - quiz_question_option
  - id (PK)
  - quiz_question_id (FK)
  - text
  - is_correct

 - quiz_user_answer
   - id (PK)
   - quiz_question_id (FK)
   - quiz_question_option_id  // this is the answer.

以上将允许您定义多个问题,每个问题都有多个问题并创建答案集(用户对测验的答案集)并记录每个答案。

希望有所帮助:)

答案 2 :(得分:5)

这也是我8年前在PHP / MySQL中做的第一个项目。

您的第一个解决方案是将数据库编码为与您的表单完全匹配。所以,你想记录用户和测验提交,所以它看起来像这样:

CREATE TABLE users (
  username VARCHAR(16) PRIMARY KEY, 
  password VARCHAR(8), 
  email VARCHAR(255), 
  birthday DATE, 
  gender ENUM('M', 'F')
);

CREATE TABLE quiz_answers (
  username VARCHAR(16) REFERENCES users,
  question1 VARCHAR(10),
  question2 INT,
  question3 ENUM('YES', 'NO', 'MAYBE'),
  question4 BOOLEAN,
  question5 VARCHAR(25),
  submitted_at DATETIME,
  PRIMARY KEY (username, submitted_at)
);

所以这只是记录最低限度:用户和测验提交。我已经给出了你需要特定于实际测验的答案的类型。我还做了一个响应用户及其提交时刻的响应;你更有可能使用代理键(AUTO_INCREMENT),但我喜欢尽可能地抵制代理人。

马上就有1NF违规:questionN。如果你做得对,你可以根据它们的含义来命名这些列,而不仅仅是它们是哪个问题。但规范化这实际上是迈向可扩展形式的下一步,但追踪历史。

接下来你要注意的是,真正的测验是一系列问题,每个问题都有一系列可能的答案。然后,表单提交确实将特定测验表单上的一组选定答案与他们的问题相关联,由特定的测验用户。这听起来像一个四方关系:用户,测验,问题,答案。如果你不介意在不同的问题上重复问题,你可以删除其中一个,但为了完整起见,让我们走这条路。将以上quiz_answers替换为:

CREATE TABLE questions (
  id INTEGER AUTO_INCREMENT PRIMARY KEY,
  question TEXT
);

CREATE TABLE answers (
  id INTEGER AUTO_INCREMENT PRIMARY KEY,
  question_id INTEGER REFERENCES questions,
  answer VARCHAR(255)
);

CREATE TABLE quizzes (
  name VARCHAR(255) PRIMARY KEY,
);

我们实际上没有测验的任何特殊元数据,所以它现在只是一个名字。

所以现在你需要从问题到答案,从测验到问题的一对多关系。

CREATE TABLE question_answers (
  question_id INTEGER REFERENCES questions,
  answer_id INTEGER REFERENCES answers,
  idx INTEGER,
  PRIMARY KEY (question_id, answer_id)
);

CREATE TABLE quiz_questions (
  quiz_name VARCHAR(255) REFERENCES quizzes,
  question_id INTEGER REFERENCES questions,
  idx INTEGER,
  PRIMARY KEY (quiz_name, question_id)
);

如上所述,棘手的部分是用户和表单提交之间的高阶关系,以及从表单问题到用户答案的​​链接。我决定把它分成两个表来避免重复。

CREATE TABLE quiz_submissions (
  id INTEGER AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(16) REFERENCES users,
  quiz_name VARCHAR(255) REFERENCES quizzes,
  submitted_at DATETIME
);

CREATE TABLE submission_answer (
  submission_id INTEGER REFERENCES quiz_submissions,
  question_id INTEGER REFERENCES questions,
  answer_id INTEGER REFERENCES answers,
  PRIMARY KEY (submission_id, question_id)
);

此时这很正常。你可以看到,查询也会有点困难。要获得测验的所有问题,您必须从测验加入问题。你可以从那里加入答案,做一个大的查询,以获得构建表格所需的所有数据(以及必须做更多的后处理),或者你可以再次针对每个问题点击数据库并做减少后期处理。我可以争论任何一种方式。要获得所有特定用户的答案,您将不得不从带有测验ID的user_submissions和request_answer表中的用户名中选择问题和用户选择的答案。所以查询会很快变得有趣。如果你有加入,你就会失去对加入的恐惧。

我希望这不会让你离开关系数据库太多;通过这样做,你实际上是在关系模型中做一个关系模型,尽管是一种限制形式。

我意识到使用很多自然键,就像我上面所做的那样,这些日子有点不正统。但是,我建议您尝试一下,至少在您开始使用时,因为如果它们不是1-10范围内的所有整数,它将更容易看到连接如何工作。

答案 3 :(得分:1)

好吧,现在我处于开发阶段,仍然遇到一些问题(即在服务器和客户端之间同步循环状态),但它可能会对你有所帮助 enter image description here

P.S。:不要将密码存储在数据库中,如上图所示 - 存储密码哈希值