在处理一个将存储一大堆(完全不同的)表单的项目时,我面临一个设计问题,即如何在保持数据库可用性的同时存储值。
简要说明:每个“文档”包含可变数量的问题(尽管每种文档的数量一致)和匹配的答案。
我想到的最有用的方法是下面的,这里我按“类型”对文档进行了分组,它标识出哪些问题属于文档,而文档又有匹配问题的答案。
+---------------+ 1 n +-----------+
| DocumentType |----------| Questions |
+---------------+ Has many +-----------+
|1 1|
|n Is of type n| Belongs to
+---------------+ 1 n +-----------+
| DocumentEntry |----------| Answers |
+---------------+ Has many +-----------+
这里的缺点是,当数据库变得越来越大(很快就会变大)时,获取带有问题a和答案b的文档的查询变得相当复杂,而且可能相当慢。
我想知道我是否偶然发现了存储数据的最佳方法,或者是否有一些我可能错过的完美解决方案。
最佳答案
您遇到了一个常见的问题:试图将静态的(具有预定义结构的数据库)用于动态的(只有一个共同点的一组单独的数据集:它们来自表单)。你想要的是数据库,但是没有数据库就容易多了,不过,既然我假设你真的想用数据库来做这件事,下面是我要做的:
您有一个包含多个document
的questions
(或问卷)。这两个都是通用的,需要自己的表,正如您目前所做的那样。
每个问题都有一个type
定义它是什么类型的问题(多重选择、自由形式、选择一个…),当然这个问题也有options
。所以还有两张桌子。这里的推理是,去掉这些与实际问题的关系允许存在一定程度的抽象,而你的查询可能还是有点简单,尽管可能有问题。
因此,每个文档有1..n个问题,每个问题有1个类型和1..n个选项。略过一点,下面是我对链接表等的看法。
Document
bigint id
DocumentQuestions
bigint document_id
bigint question_id
Question
bigint id
varchar question
QuestionType
bigint question_id
bigint type_id
Type [pre-filled table with id:type pairs, such as 1=freeform, 2=select one etc.]
QuestionOptions
bigint id
bigint question_id
varchar description
varchar value
Answers
bigint id
bigint document_id
[etc. such as user_id]
QuestionAnswers
bigint answer_id
bigint question_id
bigint questionoptions_id
这种设计允许以下几点:
问题本身是可重用的,如果你要做一个通用的“从y个问题库中回答x个随机问题”,那么问题本身就非常方便。
在不破坏现有类型的情况下,可以很容易地添加新的类型。
您总是可以很容易地浏览结构,例如“对于我的这个问题答案,文档的名称是什么?”或者“有多少人对这一问题回答错误?”
因为类型是分开的,所以您可以创建一个(web)ui,它可以很容易地反映数据库中的状态—如果类型发生更改,您甚至不必接触ui代码,这会更好。
由于问题的每个可能选项都是
QuestionOptions
表中自己的行,因此可以非常容易地获得实际值。这方面的一个明显问题是,为了保持完整性,需要在表之间进行非常严格的耦合,并且在开始时要正常运行会很痛苦。另外,由于
value
中的QuestionOptions
是varchar,因此需要能够大量解析内容,甚至可能需要引入另一个字段来提供转换提示。希望这有帮助,即使你根本不同意我的解决方案。