我正在研究一个相当简单的调查系统.数据库模式将很简单:一个Survey
表,与Question
表的一对多关系,与Answer
表和表的一对多关系PossibleAnswers
.
最近,顾客意识到她希望能够只向那些对前一个问题给出一个特定答案的人展示某些问题(例如,你是否购买了香烟?接下来是你最喜欢的卷烟品牌?),没有必要问第二个问题向非吸烟者提问).
现在我开始想知道在我的数据库模式方面实现这个条件问题的最佳方法是什么?如果question A
有2个可能的答案:A和B,以及question B
应该只出现一个用户,如果答案是A
?
编辑:我正在寻找的是一种在数据库中存储有关需求的信息的方法.数据的处理可能在应用程序端完成,因为我的SQL技能很糟糕;)
调查数据库设计
最后更新:2015年5月3日
图表和SQL文件现已在https://github.com/durrantm/survey上提供
如果您使用此(顶部)答案或任何元素,请添加有关改进的反馈!
这是一个真正的经典,成千上万.它们似乎总是"相当简单",但要好,它实际上非常复杂.要在Rails中执行此操作,我将使用附图中显示的模型.我确信对某些人来说似乎过于复杂,但是一旦你构建了其中的一些,多年来,你意识到大多数设计决策都是非常经典的模式,最好通过动态灵活的数据结构解决.一开始.
更多细节如下:
关键表的表详细信息
该答案表是至关重要的,因为它抓住了用户的实际响应.您会注意到答案链接到question_options,而不是问题.这是故意的.
input_types是问题的类型.每个问题只能是1种类型,例如所有无线电拨号,所有文本字段等.当有(例如)5个无线电拨号和1个"包含?"复选框时,请使用其他问题.选项或某种组合.将用户视图中的两个问题标记为一个,但内部有两个问题,一个用于无线电拨号,一个用于复选框.在这种情况下,复选框的组为1.
option_groups和option_choices允许您构建"常见"组.例如,在房地产应用中可能会出现"房产多大了?"的问题.可能需要以下范围内的答案:1-5 6-10 10-25 25-100 100+
然后,例如,如果存在关于相邻属性年龄的问题,则调查将要"重复使用"上述范围,以便使用相同的option_group和选项.
units_of_measure就像听起来一样.无论是英寸,杯子,像素,砖块还是其他什么,你都可以在这里定义一次.
仅供参考:虽然本质上是通用的,但是可以在此基础上创建应用程序,并且此模式非常适合Ruby On Rails框架,其中诸如"id"之类的约定用于每个表的主键.此外,关系都是简单的one_to_many,不需要many_to_many或has_many.我可能会添加has_many:throughs和/或:delegates虽然可以很容易地从一个单独的答案中得到类似survey_name的东西而无需多个链接.
您还可以考虑复杂的规则,并在您的Questions表中有一个基于字符串的条件字段,接受/解析以下任何一个:
A(1)= 3
((A(1)= 3)和(A(2)= 4))
A(3)> 2
(A(3)= 1)和(A(17)!= 2)和C(1)
其中A(x)= y表示"问题x的答案是y",C(x)表示问题x的条件(默认为真)...
问题有一个订单字段,你会逐个浏览它们,跳过条件为FALSE的问题.
这应该允许调查您想要的任何复杂性,您的GUI可以在"简单模式"中自动创建这些,并允许和"高级模式",用户可以直接输入方程式.
一种方法是使用字段添加表'问题要求':
question_id(链接到"哪个品牌?"问题)
required_question_id(链接到"你抽烟吗?"的问题)
required_answer_id(链接到"是"答案)
在应用程序中,您在提出某个问题之前检查此表.使用单独的表格,可以轻松添加所需答案(为"有时"答案添加另一行等...)
就个人而言,在这种情况下,我会使用您描述的结构并将数据库用作哑存储机制.我很喜欢将这些复杂和依赖的约束放入应用程序层.
我认为实施这些约束而不为每个带有外键的问题构建新表的唯一方法是使用T-SQL内容或其他供应商特定机制来构建数据库触发器来强制执行这些约束.
在应用程序级别,您有更多的可能性,并且更容易移植,所以我更喜欢这个选项.
我希望这可以帮助您找到适合您应用的策略.