数据库设计之问卷模块的设计2

数据库设计之问卷模块的设计1

2016/07/13更新

整个实习已经告一段落了,其实整个问卷模块的数据库设计,在6月初基本上已经最终敲定并实现出来了。

本次的总结分为两个部分。

一、对之前提出的几个遗留问题,解决了的做一个说明

二、最终总结一下,问卷模块的核心:问卷、试题、选项几个实体之间的关系如何表示,如实记录之中的心路历程,以及遇到过的一些坑。

一。之前遗留问题

1.结果试题标签

这个结果标签其实不是难点,到时候只需要记录获得的结果标签的id即可。

一次问卷的评价当然可以获得,若干个结果标签。同一个结果标签也可以被不同问卷所持有。

所以问卷:结果标签是n:n关系。

①可以使用关联表实现

②可以在评价结果记录中使用一个字符串来记录所有得到的结果标签id

这个标签模块,后来准备做成一个通用模块。

比较复杂的逻辑是如何根据用户的答案以及评价规则得到结果标签的id。

不过这不是本帖的内容。

2.试题序号

这个很多都可以由前端实现了。

但是当时我还是进行了实现的。

如果两个实体的关系是1:n,实现采用的是持有id实现,可以直接把序号维护在n的字段之中

比如,选项在试题中的序号(最终采用的是选项持有试题id)

如果两个实体的关系是n:n,实现采用的是关联表,那么序号应该放在关联表中

比如,试题在问卷中的序号

如果只是自身的序号,就直接放在自身字段之中

比如,问卷的序号、问卷类型的序号

①增

新增一个记录,序号赋值为,查询已有记录,然后count出来。

②删

删除一个记录,查询到序号大于被删除的记录的所有记录,对其序号字段进行批量减一操作。

③删除多个

在删除类型时,由于删除类型需要将其子类型一起逻辑删除,这个时候不确定会对哪些字段删除,不知道删除多少个。

采用的办法是,查询所有剩余的字段,按序号升序排序,然后统一遍历重新设定其序号。

3.填空题

未解决

4.父子试题、选项与隐藏试题

未实现

5.类型的删改策略

①删除采用逻辑删除

对字段N_IS_DELETE进行赋值。

删除后,新增加类型看不见已经删除了的。问卷选择类型也看不见已经删除了的。

但是已经选择了的,不会受到删除的影响。

特别注意,层级结构的话,删除需要对其子类别一同删除。

②编辑

内容当然可以编辑,但是层级结构不允许编辑

二。问卷模块的设计

最重要的就是三个实体:问卷(paper)、试题(question)、选项(option)

1.设计一

paper和question是关联表

option最开始的想法是,同一个题目,在不同的paper中,可以有不同的选项,并且拥有不同的分值。

当时采用的就是option持有paperId和questionId

优点:

①不同的试卷,对同一个题目的选项的修改是互不影响的

②同一个题目可以拥有不同的选项,提供了更大的灵活性

缺点:

如果有paper1和paper2都有试题6,这个时候paper3同时从paper1中导入了试题x,记为ques1,也从paper2中导入了试题6,记为ques2。

①选项窜了

对于paper3,ques1和ques2是不同的两道题。

然而,由于选项的设计,持有paperId和持有questionId,这个时候ques1的选项和ques2的选项共用了。

修改ques1的选项会完全反映到ques2上面。

这种情况虽然很难出现,但是由于我们就是希望提供统一题干,不同选项的灵活性,这个bug是实实在在存在的。

②导入试题不方便

这个时候导入试题,你会发现你只能导入题干,导入过来的试题,如果不指定试卷的话,导入过来的试题是没有选项的。

综合①、②我们只能修改设计。

2.设计二

如图所示

paper与question关闭不变

option牺牲一部分的灵活性与question绑定。

也就是说,除了分数以外,不同的试卷导入同一个试题,其题干以及所有选项内容是一样的。

这样试题和选项就是1:n关系,采用选项持有试题id即可。

由于还是需要维护不同试卷的同一试题同一选项的不同分值,

而试卷有多个选项,选项也可以对应不同的问卷,所以是n:n关系,所以这个时候问卷、选项也需要一张关联表。

该关联表字段有paperId、optionId、score

优点:

①选项与试题绑定以后,避免了一些麻烦,比如之前提到的串扰问题。

②导入试题的时候可以不用管问卷了,因为选项内容只与试题相关。

缺点:

①选项与试题绑定之后,也带来了新的缺点。不同的问卷导入同一道试题,会相互影响。

而这个影响本身也有好有坏。

如果希望对所有的问卷一起修改,当然很方便。

如果不希望别人的修改影响到自己,则无能为力。

②显示选项的分数有很大的麻烦。

A。通过问卷id,查询所有的试题id。通过某个试题id,查询所有的选项id,显示选项的内容。

B。通过问卷id,选项id在关联表中,查询选项的分数。

C。如果对于某个选项就需要查询一次数据库,代价太大。

如果查询问卷所有选项的分数,将分数与对应的想象匹配起来,异常地复杂。

解决办法:

针对②,解决办法是,修改问卷-选项关联表

将里面的字段改为paperId,questionId,optionName,score

这样将分数按选项的名称(A,B,C,D)单独显示在旁边,避免了配对的问题。

因为以选项名称来存储,所以无法区分不同试题的选项,所以又加入了questionId字段

针对①,开始我们想到了,先进行判断(通过在关联表中查询count某个试题,看是否等于1)。

如果某个试题没有被其他问卷导入,当然可以直接修改。

如果被多个问卷导入,那么将决定权给用户,在每次进行修改的时候告知用户这样修改可能会影响到其他试卷。

3.设计三

其实在设计二中,针对①的办法还存在着难以忍受的问题。

如果一个用户新建了一个题目,但是它还没有创建选项。

这个时候他有事儿走了,但是别的用户导入了该题目。

后来该用户回来开始创建选项,这个时候,它每创建一个选项,就会被问及这个修改会影响到别人,是否修改。

这个体验是不可忍受的。

在这种设计之下,试题和选项是绑定了的,

那么对于试题的修改就会有一下4种情况:

①对于试题内容的修改,比如修改题干。

②增加选项

③修改选项内容

④删去选项

而在这种不同问卷共享导入题目的设计有一个一直没有解决的矛盾:

对于一个人修改,所有人跟着变的共用

与自己所引用的东西,不希望别人修改影响到自己的不共用

共用与不共用的矛盾

最终我采用的折衷解决办法如下:

题目加入一个创建人字段

题目增加一个权限字段:①不可导入(这种权限的题目根本不会出现在导入列表中)②可导入,只能自己修改③可导入,任何人可以修改

权限编辑是单独的。只有当前操作人=题目创建人,可以进行权限编辑

普通编辑:

(1)若试题权限为不可导入,直接修改

(2)若试题权限为可导入,只能自己修改

①操作人=题目创建人,直接修改

②操作人!=题目创建人,弹出提示不能修改

(3)若试题权限为可导入,任何人可以修改,直接修改

导入分为两种:

(1)关联导入

导入直接将当前问卷与某个题目关联。复制问卷-试题-选项关联表记录即可。

关联导入的创建人不变。权限也不变。

(2)独立导入

复制一个问题,将其单独保存,再和当前试卷关联,再复制问卷-试题-选项关联表。

问题创建人修改为导入的操作人,权限默认修改为不可导入。

独立导入功能的加入,使得别人设置为可导入,只能创建人自己修改权限的试题在不具备编辑权限,自己又想编辑的时候,可以导入过来,进行编辑。

权限编辑功能,使得可以随时将不可导入的试题分享出来给别人。

在权限控制下,所有能够的修改都可以直接修改,修改引起的其他试卷修改,由用户自己负责。

时间: 2024-08-25 02:38:07

数据库设计之问卷模块的设计2的相关文章

[译文]Domain Driven Design Reference(三)—— 模型驱动设计的构建模块

本书是Eric Evans对他自己写的<领域驱动设计-软件核心复杂性应对之道>的一本字典式的参考书,可用于快速查找<领域驱动设计>中的诸多概念及其简明解释. 其它本系列其它文章地址: [译文]Domain Driven Design Reference(一)—— 前言 [译文]Domain Driven Design Reference(二)—— 让模型起作用 [译文]Domain Driven Design Reference(三)—— 模型驱动设计的构建模块 Ⅱ.模型驱动设计的

跟我一起学extjs5(37--单个模块的设计[5取得模块列表数据])

跟我一起学extjs5(37--单个模块的设计[5取得模块列表数据]) 写了几个月,总算有点盼头了,最终要从后台取得数据了.后台的spring mvc 和 service 仅仅能简单的说说了,里面加了几十个类.有兴趣的下载了源代码自己看.以下画张通用的模块列表取数据的流程,这个流程是适用于全部的模块.我这个后台处理程序也是对全部的模块进行统一处理,包含数据查找,新增,改动,删除都是同样的. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamZvaw==

ATITIT.翻译模块的设计与实现&#160;api&#160;attilax&#160;总结

ATITIT.翻译模块的设计与实现 api attilax 总结 1. 翻译原理1 2. TMX格式是国际通用格式(xml)1 2.1. 方法/步骤2 3. TRADOS2 4. ATITIT.翻译软件的实现思路2 5. 参考3 1. 翻译原理 在日常生活中英汉辞典的作用就是把中文翻译成英文或者是把英文翻译成中文,它的实现原理就是词典库里先把对应的中文和英文存在数据库表里,然后根据你输入的内容来匹配出相应的结果出来. 作者:: 老哇的爪子 Attilax 艾龙,  EMAIL:[email pr

跟我一起学extjs5(11--自定义模块的设计)

跟我一起学extjs5(11--自定义模块的设计) 从这一节开始我们来设计并完成一个自定义模块.我们先来确定一个独立的模块的所能定义的一些模块信息.以下信息只是我自己在开发过程中想到或用到的,希望有新的想法的或者有建议的跟贴回复. 一个独立模块包含以下信息: 1.模块的基本信息 模块ID号:一个数字的ID号,可以根据此ID号的顺序将相同分组的模块放在一块. 模块分组:模块分到哪个组里,比如说业务模块1.业务模块2.系统设置.系统管理等. 模块标识:系统中唯一的模块的标识,一般这个标识等同于数据库

Java SSH框架系列:用户登录模块的设计与实现思路

时间 2014-01-19 16:14:54  CSDN博客原文  http://blog.csdn.net/nupt123456789/article/details/18504615 1.简介 用户登录模块,指的是根据用户输入的用户名和密码,对用户的身份进行验证等.如果用户没有登录,用户就无法访问其他的一些jsp页面,甚至是action都不能访问. 二.简单设计及实现 本程序是基于Java的SSH框架进行的. 1.数据库设计 我们应该设计一个用户表,其Userinfo表,对应的SQL语句为(

IM系统中聊天记录模块的设计与实现

看到很多开发IM系统的朋友都想实现聊天记录存储和查询这一不可或缺的功能,这里我就把自己前段时间为傲瑞通(OrayTalk)开发聊天记录模块的经验分享出来,供需要的朋友参考下. 一.总体设计 1.存储位置 从一开始我们就打算在服务端和客户端本地同时存储聊天记录,而且,在客户端查看聊天记录时,可以选择是从本地加载.还是从服务器加载.这样做的好处有两个: (1)从本地加载聊天记录速度非常快. (2)当更换了登录的机器,在任何地方任何时刻都可以从服务器加载完整的聊天记录,记录永远不会丢失. 2.存储方案

跟我一起学extjs5(36--单个模块的设计[4根据菜单建立相应的模块])

跟我一起学extjs5(36--单个模块的设计[4根据菜单建立相应的模块]) 前几节处理好了后台,现在又要处理前台了.首先是要修改菜单的选择事件,在创建一个module的时候将 moduleName参数传递进去. 修改MainController.js中的函数: // 选择了主菜单上的菜单后执行 onMainMenuClick : function(menuitem) { var maincenter = this.getView().down('maincenter'); maincenter

跟我一起学extjs5(35--单个模块的设计[3根据类的标注自动生成数据])

跟我一起学extjs5(35--单个模块的设计[3根据类的标注自动生成数据]) 然后在hibernate.cfg.xml中加入: <mapping class="com.jfok.server.hibernate.system._ModuleField" /> <mapping class="com.jfok.server.hibernate.system._ModuleGridScheme" /> <mapping class=&qu

跟我一起学extjs5(39--单个模块的设计[7数据的增加修改删除])

跟我一起学extjs5(39--单个模块的设计[7数据的增加修改删除]) 从后台取得数据已经可以了,下面对记录的新增.修改和删除进行前后台的互动改造.首先将新增和修改在行内进行,也就是都是在grid上进行. 在grid上可以编辑行,需要在initComponent中增加一个plugins的修改,将原来cellEditing的删除掉,加入rowEditing: // 可以在grid中进行行编辑的设置 this.rowEditing = new Ext.grid.plugin.RowEditing(