我正在研究一个相当简单的调查系统。数据库模式将变得简单:Survey
表,与Question
表的一对多关系,与Answer
呈一对多关系表和PossibleAnswers
表。
最近,客户意识到她希望能够只向那些对某个先前问题给出一个特定答案的人展示某些问题(例如你买香烟吗?后面会跟着什么是你最喜欢的卷烟品牌?,没有必要向非吸烟者提出第二个问题。)
现在我开始想知道在我的数据库架构方面实现这个条件问题的最佳方法是什么?如果question A
有两个可能的答案:A和B,question B
只应向用户显示,如果答案是A
?
编辑:我正在寻找的是一种在数据库中存储有关需求的信息的方法。数据的处理可能在应用程序端完成,因为我的SQL技能很糟糕;)
答案 0 :(得分:125)
调查数据库设计
最后更新: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的东西而无需多个链接。
答案 1 :(得分:13)
你也可以考虑复杂的规则,并在你的Questions表中有一个基于字符串的条件字段,接受/解析其中任何一个:
其中A(x)= y表示“问题x的答案是y”,C(x)表示问题x的条件(默认为真)......
问题有一个订单字段,你会逐个浏览它们,跳过条件错误的问题。
这应该允许调查您想要的任何复杂性,您的GUI可以在“简单模式”中自动创建这些,并允许和“高级模式”,用户可以直接输入方程式。
答案 2 :(得分:9)
一种方法是使用字段添加表'问题要求':
在您提交某个问题之前,请先检查此表格。 使用单独的表格,可以轻松添加所需答案(为“有时”答案添加另一行等...)
答案 3 :(得分:5)
就个人而言,在这种情况下,我会使用您描述的结构并将数据库用作哑存储机制。我很喜欢将这些复杂和依赖的约束放入应用程序层。
我认为强制执行这些约束而不为每个带有外键的问题构建新表的唯一方法是使用T-SQL内容或其他供应商特定机制来构建数据库触发器来强制执行这些约束。
在应用程序级别,你有更多的可能性,并且更容易移植,所以我更喜欢这个选项。
我希望这有助于您为自己的应用找到策略。