在数据库列中存储结构化数据?

时间:2013-11-15 16:28:20

标签: mysql database database-design

我一直在与同事讨论将结构化数据(例如XML或JSON)存储在数据库列中而不是创建子表是否是个好主意。例如,假设我们需要存储有关问题的信息。这两类问题是多项选择和评级(例如1-10的比率)。我通常会创建类似下面的结构:

Table                   |   Columns
------------------------------------------------------
Question                | ID, Title, QuestionTypeId
Question_MultipleChoice | QuestionId, Choice
Question_Rating         | QuestionId, Min, Max
QuestionTypes           | ID, TypeName

我的同事认为最好将信息存储在单个Question表中,并带有subinfo列。例如:

Question
----------------
ID
Title
SubInfo  <-- JSON

因为它可以通过避免JOINS使查询更简单,也可能更快。是否有理由避免使用这种类型的数据库结构?看起来如果您需要根据SubInfo列中的数据进行查询,这将是一个坏主意,但如果不需要,这是一个合理的数据库结构吗?

3 个答案:

答案 0 :(得分:2)

就个人而言,调查是一种情况,我认为没有规范化并且存储JSON几乎,因为是更好的选择。

如果没有它,你将最终得到各种奇怪的用例 - 你最终想要在这些用例中管理。除了整理各种选择问题外,您还需要管理其中的“其他”答案,条件问题,条件问题组,列表不断。此外,调查 - 就像其他形式的数据一样 - 可能会发生变化,而且当它们发生变化时,事情会从笨拙变为核心。

JSON的优点在于,由于调查在概念上彼此独立,因此您几乎不需要从一个到另一个的参照完整性,因此您可以将整个问题和选项树存储为一个JSON blob,并担心在您的应用程序中格式化它。

对于每个提交的答案,同样如此:获取原始blob,将相关答案标记为已选中,依此类推,并将生成的JSON 存储为,而不是存储引用原始问题以及所回答的问题。这样您就可以轻松跟踪用户实际回答的内容,而不是当前版本的调查所说的内容,并且无论调查自最初应答以来有多大分歧,都可以做到。< / p>

如果您需要稍后挖掘答案,请注意Postgres允许在整个字段上使用GIST索引索引JSON,并在表达式上使用BTREE索引。

答案 1 :(得分:1)

JSON,XML本质上是数据类型

因此,如果您选择的数据库支持该数据类型且具有适当的匹配运算符集,那么一切都很好。

如果您打算在数据库中粘贴XML或JSON并将其声明为字符串,那么绝对不推荐。 String是一个字符串,它不是JSON也不是XML。

例如,JSON数据类型的相等运算符知道(或应该知道) {"firstName": "John", "lastName": "Smith"} = {"lastName": "Smith", "firstName": "John"} true

字符串的等于运算符返回 false - 依此类推。

如果不能判断两件事情是否相同,那么不要期望从数据库中获得太多。

答案 2 :(得分:0)

我们正考虑为同样的问题做两件事。您可以在问题&#39;中存储blob。表格,以便您在尝试检索包含所有答案的问题时不会遇到n + 1问题,同时也会保留“问题”答案。表,所以你可以编写如下的查询:

SELECT q.*
FROM Questions q
WHERE EXISTS (
           SELECT a.question_id 
           FROM Answers a 
           WHERE 
              a.question_id = q.id AND 
              a.Choice = 'SomeAnswer');

如果问题和答案不经常更改,那么更新插入和更新的表格都可以正常工作。

我不认为我会将最低/最高等级放在单独的表格中。