开发'的数据库设计;测验';使用PHP和MySQL的Web应用程序
因此,我试图学习PHP和MySQL(我对两者都有基本的了解;我已经阅读了Head-first SQL和Head-first PHP&MySQL的前半部分),我认为巩固我的知识的最好方法是构建一些东西,而不是阅读 考虑到这一点,我想创建一个连接到服务器上MySQL数据库的基本网页。我将建立一个基本的HTML表单,允许用户输入基本信息,例如:姓、名、电子邮件、生日、性别 我的问题是我不知道如何设计一个数据库来记录基本测验的结果-我只想要5道选择题。最后,我想显示用户的结果与以前用户的结果开发'的数据库设计;测验';使用PHP和MySQL的Web应用程序,php,mysql,database,database-design,forms,Php,Mysql,Database,Database Design,Forms,因此,我试图学习PHP和MySQL(我对两者都有基本的了解;我已经阅读了Head-first SQL和Head-first PHP&MySQL的前半部分),我认为巩固我的知识的最好方法是构建一些东西,而不是阅读 考虑到这一点,我想创建一个连接到服务器上MySQL数据库的基本网页。我将建立一个基本的HTML表单,允许用户输入基本信息,例如:姓、名、电子邮件、生日、性别 我的问题是我不知道如何设计一个数据库来记录基本测验的结果-我只想要5道选择题。最后,我想显示用户的结果与以前用户的结果 如果您能帮
如果您能帮助我了解如何为5个问题的测验设计表格,我将不胜感激。谢谢 我将从4个简单的表开始: 用户
- user_id auto integer
- regtime datetime
- username varchar
- useremail varchar
- userpass varchar
- question_id auto integer
- question varchar
- is_active enum(0,1)
- choice_id auto integer
- question_id Questions.question_id
- is_right_choice enum(0,1)
- choice varchar
- user_id Users.user_id
- question_id Questions.question_id
- choice_id Question_choices.choice.id
- is_right enum(0,1)
- answer_time datetime
问题
- user_id auto integer
- regtime datetime
- username varchar
- useremail varchar
- userpass varchar
- question_id auto integer
- question varchar
- is_active enum(0,1)
- choice_id auto integer
- question_id Questions.question_id
- is_right_choice enum(0,1)
- choice varchar
- user_id Users.user_id
- question_id Questions.question_id
- choice_id Question_choices.choice.id
- is_right enum(0,1)
- answer_time datetime
问题选择
- user_id auto integer
- regtime datetime
- username varchar
- useremail varchar
- userpass varchar
- question_id auto integer
- question varchar
- is_active enum(0,1)
- choice_id auto integer
- question_id Questions.question_id
- is_right_choice enum(0,1)
- choice varchar
- user_id Users.user_id
- question_id Questions.question_id
- choice_id Question_choices.choice.id
- is_right enum(0,1)
- answer_time datetime
用户\问题\答案
- user_id auto integer
- regtime datetime
- username varchar
- useremail varchar
- userpass varchar
- question_id auto integer
- question varchar
- is_active enum(0,1)
- choice_id auto integer
- question_id Questions.question_id
- is_right_choice enum(0,1)
- choice varchar
- user_id Users.user_id
- question_id Questions.question_id
- choice_id Question_choices.choice.id
- is_right enum(0,1)
- answer_time datetime
我对这张桌子设计的想法是:
- 表
用于存储注册用户用户
- 表
用于存储所有问题。问题
- 它有
,因此您可以有选择地仅显示活动问题(使用处于活动状态
)WHERE is\u active='1'
- 它有
- 表
用于存储所有可用选项。它有question\u choices
,定义了什么选择才是特定问题的正确答案is\u right\u choice
- 表
用于存储用户的答案。User\u question\u answers
- 它有
用于更快的查找,以查看特定的问题和答案选择是否正确(基于先前定义的is_right
)is_right_choice
- 它还有
,只用于记录特定用户何时回答问题answer\u time
- 它有
- 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.
以上内容允许您定义多个测验,每个测验有多个问题,并创建答案集(用户对测验的答案集)并记录每个答案
希望有帮助:)这也是大约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
。如果你做得对,你会根据这些列的意思来命名,而不仅仅是它们是哪个问题。但是规范化这实际上是实现可扩展但跟踪历史的表单的下一步
接下来你会注意到一个测验实际上是一组问题,每个问题都有一组可能的答案。然后,表单提交实际上是将一组选定答案与特定测验用户在特定测验表单上提出的问题相关联。这听起来像是一种四方关系:用户、测验、问题、答案。如果你不介意在不同的测验中重复问题,你可以删掉其中一个,但是为了完整起见,让我们沿着这条路走下去。用以下内容替换上面的quick\u答案
:
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和用户名中选择,然后从提交答案表中选择用户选择的问题和答案。因此,查询将很快变得有趣。你会失去对加入的恐惧,如果你有加入的话
我希望这不会让您对关系数据库有太多的反感;这样做实际上就是在关系模型内部进行关系模型,尽管是一种受限形式
我意识到像我在上面所做的那样使用很多自然键,这几天有点不合常规。但是,我建议您尝试一下,至少在您刚开始的时候,因为这样可以更容易地了解联接是如何工作的,如果它们不是集合中的所有整数