考试数据库设计

Alw*_*uff 4 database-design sql-server

我正在为考试设计数据库,但我被卡住了。我不知道怎么做。

以下是相关信息:

  • 学生回答 10 个问题。
  • 每个问题有 3 个选项(答案),学生选择一个。
  • 只有一个答案是正确的,其他两个是错误的。
  • 学生只能参加一次此考试。他们不能再试一次。
  • 不会有其他考试,只有这一项。

我需要数据库设计方面的帮助。

到目前为止我自己尝试过的:

表学生

ID bigint (primary key, identity)
Name nvarchar(MAX)
Run Code Online (Sandbox Code Playgroud)

表格问题

ID bigint (primary key, identity)
TextOfTheQuestion nvarchar(MAX)
Run Code Online (Sandbox Code Playgroud)

表格答案

ID bigint (primary key, identity)
TextOfTheAnswer nvarchar(MAX)
QuestionID bigint (foreign key to Questions.ID)
isCorrectAnswer bit
Run Code Online (Sandbox Code Playgroud)

表学生选择

StudentID bigint (primary key, foreign key to Students.ID)
AnswerID bigint (primary key, foreign key to Answers.ID)
Run Code Online (Sandbox Code Playgroud)

这是我个人为学习目的而设计的。我正在尝试自己学习实体框架 + C#。

pap*_*zzo 6

轻松使用 bigint 和 nvarchar(MAX)

Table Student:

ID int (primary key, identity)
Name nvarchar(800)

Table Question:

ID smallint (primary key, identity)
TextOfTheQuestion nvarchar(800)
CorrectAns tinyint FK (to AnswerNum.Num)  
tested and can make a composite FK to Answer  QuestionID, AnsNum   
I was not sure could do this but it would mean you have to create the question  
Then populate Answer  
Then come back and edit question for CorrectAns so may not be the way you want to go

Table Answer:

QuestionID smalling PK FK (to Question.ID) 
AnswerNum tinyint   PK FK (to AnswerNum.Num)
TextOfTheAnswer nvarchar(800)


Table StudentChoice:

StudentID int       (primary key, foreign key to Student.ID)
QuestionID smallint (primary key)
AnswerNum tinyint 
(QuestionID, AnswerNum) REFERENCES Answer (QuestionID, AnswerNum)

Table AnswerNum:

Num tinyint PK 
-- just values 1, 2, 3
-- this way you can change number of questions in the future 
Run Code Online (Sandbox Code Playgroud)

这就是你的评分方式
当主查询出来时,它是一个好的数据库设计的标志

  select Student.Name, count(*) as score 
  from student
  left join StudentChoice
         on Student.ID = StudentChoice.StudentID 
  left join Question
         on Question.QuestionID = StudentChoice.QuestionID 
        and Question.CorrectAns = StudentChoice.AnswerNum   
            -- CorrectAns in Question makes this a whole lot easier  
  group by Student.Name 
Run Code Online (Sandbox Code Playgroud)


Vér*_*ace 5

我认为你已经把它钉在了你的初始模式上。

但是,由于我们正在处理 MCQ 场景,因此您不需要“答案”表 - 答案可以包含在问题中(以及两个不正确的答案 - 见下文)。这将大大简化问题。我建议的另一个较小的更改是PRIMARY KEY在 Question 表中添加一个 Question_ID 字段。

我在下面准备了一个架构 - 恐怕是 MySQL,我不经常使用 Microsoft SQL Server 并且手头没有实例。“翻译”应该不会太难。

一些评论。

我建议您不要只使用“ID”作为每个表中的字段名称,而是建议您使用“Table_Name_ID”——它使您的 SQL 更清晰,还有助于调试——如果您收到一条消息,说“... ID 错误” on insert...” - 您不知道消息所指的是哪个表的 ID,而如果您明确命名它们,错误消息就会变得有意义。

CREATE TABLE Student (Student_ID int, Name VARCHAR(25));
CREATE TABLE Question (Question_ID int, Name VARCHAR(25), Question_Text 
                       VARCHAR(64000), Answer1 VARCHAR(4096), 
                       Answer2 VARCHAR(4096), Answer3 VARCHAR(4096),
                       Correct_Answer TINYINT);
CREATE TABLE Student_Response (Student_ID int, Question_ID int,
                               Student_Answer TINYINT);
Run Code Online (Sandbox Code Playgroud)

如果您制定的问题被标记为“A”、“B”或“C”,则需要将 TINYINT 修改为 CHAR(1)。

您会注意到,我为我的FOREIGN KEYs &c使用了相对较长且(希望)易于理解的名称。有两个原因:

  • 程序员不必通过挖掘文档来找出实体是什么——它是不言自明的,

  • 对调试绝对必要- 这是绝大多数应用程序花费大部分时间的地方。收到“...约束 SYS00003433 已被违反...”的消息并不是很有帮助。Oracle 非常适合为未命名的约束提供自己的“特殊”系统生成名称。

您还会注意到我使用了单数的表名。我建议你也这样做——这样你就不必考虑“嗯……是学生还是学生?” 无论哪种方式,选择一个标准并坚持下去。

如果您在 Google 上搜索“数据库设计最佳实践”,您将获得任意数量的站点 - 花时间和精力阅读其中的一些,看看共识是什么 - 如果很多人认为这是一个好主意,那可能是!

ALTER TABLE Student_Response 
  ADD CONSTRAINT fk_sr_student FOREIGN KEY (Student_ID) 
    REFERENCES Student (Student_ID);
ALTER TABLE Student_Response 
  ADD CONSTRAINT fk_sr_question FOREIGN KEY (Question_ID) 
    REFERENCES Question (Question_ID);
Run Code Online (Sandbox Code Playgroud)

这种独特的约束是为了消除对同一问题有两个答案的可能性。

ALTER TABLE Student_Response 
  ADD CONSTRAINT uq_sr_student_question 
    UNIQUE (Student_ID, Question_ID);
Run Code Online (Sandbox Code Playgroud)

即使您明确排除了它,添加考试(相同考试,不同时间)表或可能的“尝试”表也应该相对容易,然后为不同的考试提供考试表 - 即数据库101,数据库201。

也许您应该考虑与尝试相关的日期甚至日期时间字段 - 在上午和下午参加相同的考试?

在一天结束时,人们可以设计直到奶牛回家。避免强迫性的设计障碍——我的意思是(提前)选择一个你对系统功能感到满意的点,然后停在那里。我知道陷入不断添加“点点滴滴”而没有完成实际工作的陷阱是多么容易。