请教一个数据库设计的问题

SilverNet 2010-01-11 03:10:41
现在我要改变的系统的数据库是一个答题教学系统,现在遇到了一个数据库设计方面的问题。
系统中的答题为选择题,以往的数据库设计如下:

IF OBJECT_ID('Question') IS NOT NULL DROP TABLE Question
CREATE TABLE SUBJECT(
SubjectID INT PRIMARY KEY IDENTITY,
SubjectName VARCHAR(1000), --题目内容
AnswerA VARCHAR(1000), --答案A
AnswerB VARCHAR(1000), --答案B
AnswerC VARCHAR(1000), --答案C
AnswerD VARCHAR(1000), --答案D
RightAnswer CHAR(4) --可以为A,也可以为ABCD等……即满足单选和多选
)


这样设计就将将一道题目存在一行数据中,程序调用起来很方面,很容易就能对题目数据进行操作。

现在因为以上设计有2个缺陷不足:
1.虽然系统中暂时一道题目最多只能设置4个答案,但是用户有时候只填写2个或3个答案,这样其他答案就是空白,这样导致数据库字段没有充分的利用。
2.考虑到系统中如果用户以后需要一道题目填入更多的答案就会造成现有的设计无法支持(暂时不存在这个问题)。

现在我想使用如下的设计方式:

//题目表
IF OBJECT_ID('Question') IS NOT NULL DROP TABLE Question
CREATE TABLE Questions(
queID INT PRIMARY KEY IDENTITY,
queContent VARCHAR(1000) --题目内容
)
GO
//答案表
IF OBJECT_ID('ANSWERS') IS NOT NULL DROP TABLE ANSWERS
CREATE TABLE ANSWERS
(
ansID INT PRIMARY KEY IDENTITY,
ansContent VARCHAR(1000), --答案内容
isRight BIT --是否正确
)
GO
//题目答案关联表
IF OBJECT_ID('QA') IS NOT NULL DROP TABLE QA
CREATE TABLE QA(ID INT PRIMARY KEY IDENTITY,queID INT,ansID INT)
GO


这样就没有以上的缺陷了,一个题目可以根据关联它的答案来算出这道题有多少选择答案,以及对的答案。
但是这样一来程序这边做起来就麻烦多了,需要调用3个表才能返回一道题的数据。并且插入一道题都要先写题目名到题库,然后写该题的答案到答案表,然后再写关系到题目答案的关联表,对程序方面的效率和数据库的效率不知道有没有影响。

请问下各位高手我需不需要把我以前的数据结构改成现在的。或者各位高手有更好的方法。
...全文
98 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
SilverNet 2010-10-16
  • 打赏
  • 举报
回复
往往设计的越灵活功能就不能太健全。设计的过于灵活功能上就不能太贴合业务。结贴
--小F-- 2010-01-11
  • 打赏
  • 举报
回复
如果是多对多查询的话 最好是拆分成几张表 可以一一对应
SilverNet 2010-01-11
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 dawugui 的回复:]
引用 4 楼 silvernet 的回复:
引用 3 楼 dawugui 的回复:
SQL code我认为你应该这么设计:--科目表SubjectID
SubjectName--标准答案表SubjectID , itemid , Answer , score1, score2 , type--itemid 为题号11        A401--1表示单选,--2表示多选12        A,B422--A,B表示两个答案,0,2,4表示存在三种可能的分值。--一般来说,多选题全?-


呵呵,可能大哥你理解错了,我现在的意思是一道题的题目和答案内容是存在一张表中还是分开三个表存储的问题。现在你说的方法是记录题目记录学生成绩的方法。

和3楼差不多一个意思.这样?

--标准答案表
SubjectID , itemid , px , Answer , score  --itemid 为题号,px 为答案的内容序号
1          1        1  , 内容1    4     
1          1        2  , 内容2    5   
1          1        3  , 内容3    6     
1          1        4  , 内容4    7   
1          2        1  , 内容1    6
1          2        2  , 内容2    8
...

   



[/Quote]

呵呵,其实我刚才也意识到,如果答案对于题目是多对一关系的话,应该就不需要设计中间表了。
结合你的代码,改进到以下设计

--题目表
IF OBJECT_ID('Question') IS NOT NULL DROP TABLE Question
CREATE TABLE Questions(
queID INT PRIMARY KEY IDENTITY,
queContent VARCHAR(1000) --题目内容
)
GO
--答案表
IF OBJECT_ID('ANSWERS') IS NOT NULL DROP TABLE ANSWERS
CREATE TABLE ANSWERS
(
ansID INT PRIMARY KEY IDENTITY,
ansContent VARCHAR(1000), --答案内容
isRight BIT --是否正确
subID INT --所属题目
)


这样就少了一个表,那么操作的话就只要2个表的关联,感觉比以前好些,但是还是需要循环执行SQL语句插入答案.
这样子添加和编辑的时候肯定就要进行2步操作了,
1.把题目加入题库表
(可能这中间还要一步,把刚才插入的那条题目自动生成的唯一标识给取出来,用于以下插入题目对应的答案做关联用)
2.根据加入题库的题目编号,循环加入答案;

还是感觉比较麻烦。
dawugui 2010-01-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 silvernet 的回复:]
引用 3 楼 dawugui 的回复:
SQL code我认为你应该这么设计:--科目表SubjectID
SubjectName--标准答案表SubjectID , itemid , Answer , score1, score2 , type--itemid 为题号11        A401--1表示单选,--2表示多选12        A,B422--A,B表示两个答案,0,2,4表示存在三种可能的分值。--一般来说,多选题全?-


呵呵,可能大哥你理解错了,我现在的意思是一道题的题目和答案内容是存在一张表中还是分开三个表存储的问题。现在你说的方法是记录题目记录学生成绩的方法。
[/Quote]
和3楼差不多一个意思.这样?

--标准答案表
SubjectID , itemid , px , Answer , score --itemid 为题号,px 为答案的内容序号
1 1 1 , 内容1 4
1 1 2 , 内容2 5
1 1 3 , 内容3 6
1 1 4 , 内容4 7
1 2 1 , 内容1 6
1 2 2 , 内容2 8
...




hbqhd 2010-01-11
  • 打赏
  • 举报
回复
如果都是选择题的话,还是沿用老系统的设计比较好。
SilverNet 2010-01-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 dawugui 的回复:]
SQL code我认为你应该这么设计:--科目表SubjectID
SubjectName--标准答案表SubjectID , itemid , Answer , score1, score2 , type--itemid 为题号11 A401--1表示单选,--2表示多选12 A,B422--A,B表示两个答案,0,2,4表示存在三种可能的分值。--一般来说,多选题全?-
[/Quote]

呵呵,可能大哥你理解错了,我现在的意思是一道题的题目和答案内容是存在一张表中还是分开三个表存储的问题。现在你说的方法是记录题目记录学生成绩的方法。
dawugui 2010-01-11
  • 打赏
  • 举报
回复
我认为你应该这么设计:

--科目表
SubjectID
SubjectName

--标准答案表
SubjectID , itemid , Answer , score1, score2 , type --itemid 为题号
1 1 A 4 0 1 --1表示单选,--2表示多选
1 2 A,B 4 2 2 --A,B表示两个答案,0,2,4表示存在三种可能的分值。

--一般来说,多选题全对得全分,少选不错选,得一半的分,错选,不选,得0分。
这样,你可以通过type为1,2来判断是多选还是单选。

--学生作答表。
studentid , SubjectID , itemid , Answer

--统计方法如下:
select m.studentid ,
sum(case when m.Answer = n.Answer then score1
when n.type = 2 and charindex(m.Answer ,n.Answer) > 0 and m.Answer <> n.Answer then score2
else 0 end)
from 学生作答表 m, 标准答案表 n
where m.SubjectID = n.SubjectID and m.itemid = n.itemid
group by m.studentid

--如果需要科目名称,再连接科目表
select m.studentid , p.SubjectName,
sum(case when m.Answer = n.Answer then score1
when n.type = 2 and charindex(m.Answer ,n.Answer) > 0 and m.Answer <> n.Answer then score2
else 0 end)
from 学生作答表 m, 标准答案表 n,科目表 p
where m.SubjectID = n.SubjectID and m.itemid = n.itemid and m.SubjectID = p.SubjectID
group by m.studentid,p.SubjectName
SilverNet 2010-01-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 dawugui 的回复:]
SQL code--科目表SubjectID
SubjectName--标准答案表SubjectID , itemid , Answer , score1, score2 , type11 A401--1表示单选,--2表示多选12 A,B422--A,B表示两个答案,0,2,4表示存在三种可能的分值。--一般来说,多选题全对得全分,少选不错选,得一半的分,错选,不选,?-
[/Quote]

还少一个答案内容表
dawugui 2010-01-11
  • 打赏
  • 举报
回复
--科目表
SubjectID
SubjectName

--标准答案表
SubjectID , itemid , Answer , score1, score2 , type
1 1 A 4 0 1 --1表示单选,--2表示多选
1 2 A,B 4 2 2 --A,B表示两个答案,0,2,4表示存在三种可能的分值。

--一般来说,多选题全对得全分,少选不错选,得一半的分,错选,不选,得0分。
这样,你可以通过type为1,2来判断是多选还是单选。

34,593

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧