Mysql 在数据库列中存储结构化数据?
我和一位同事一直在争论,在数据库列中存储结构化数据(如XML或JSON)而不是创建子表是否是一个好主意。例如,假设我们需要存储有关问题的信息。这两类问题是多项选择题和评分题(例如,评分范围为1-10)。我通常会创建如下结构:Mysql 在数据库列中存储结构化数据?,mysql,database,database-design,Mysql,Database,Database Design,我和一位同事一直在争论,在数据库列中存储结构化数据(如XML或JSON)而不是创建子表是否是一个好主意。例如,假设我们需要存储有关问题的信息。这两类问题是多项选择题和评分题(例如,评分范围为1-10)。我通常会创建如下结构: Table | Columns ------------------------------------------------------ Question | ID, Title, QuestionT
Table | Columns
------------------------------------------------------
Question | ID, Title, QuestionTypeId
Question_MultipleChoice | QuestionId, Choice
Question_Rating | QuestionId, Min, Max
QuestionTypes | ID, TypeName
我的同事认为最好将信息存储在一个带有子信息列的问题表中。例如:
Question
----------------
ID
Title
SubInfo <-- JSON
问题
----------------
身份证件
标题
SubInfo就我个人而言,调查是一种情况,我认为不规范任何内容并按原样存储JSON是更好的选择
如果没有它,你最终会遇到各种各样的奇怪的用例,你最终会想要管理这些用例。除了整理各种各样的选择题之外,你还需要管理其中的“其他”答案,条件问题,条件问题组,列表等等。更重要的是,调查和其他形式的数据一样,随时都会发生变化,一旦发生变化,事情就会从糟糕变为糟糕
JSON的优点是,由于调查在概念上彼此独立,因此您几乎不需要一个到另一个的引用完整性,因此您最好将整个问题和选项树存储为一个JSON blob,并担心在应用程序中格式化它
对于每个提交的答案都是一样的:取原始blob,将相关答案标记为选中,依此类推,并按原样存储生成的JSON,而不是将对原始问题的引用与回答的内容一起存储。这将允许您随时跟踪用户实际回答的内容,而不是当前版本的调查所说的内容,并且无论调查与最初回答的内容有多大差异,您都可以这样做
如果以后需要挖掘答案,请注意Postgres允许在整个字段上使用GIST索引对JSON进行索引,在表达式上使用BTREE索引。JSON,XML本质上是数据类型
因此,如果您选择的数据库支持该数据类型,并且具有合适的匹配运算符集,那么一切都很好
如果您计划将XML或JSON粘贴到数据库中并将其声明为字符串,则绝对不建议这样做。字符串是一个字符串,它既不是JSON也不是XML
例如,JSON数据类型的相等运算符知道(或应该知道)
{“firstName”:“John”,“lastName”:“Smith”}={“lastName”:“Smith”,“firstName”:“John”}
是真的
字符串的相等运算符为此返回false,以此类推
如果DB不能判断两件事是否相等,那么不要对它期望太高。我们正在考虑为类似的问题同时做这两件事。您可以在“问题”表中存储一个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');
如果问题和答案不经常更改,那么在insert和updates上更新这两个表就可以了
不过,我不认为我会将最低/最高评级放在单独的表格中。只是为了添加一些汽油。。。嵌套表呢?我认为,真正的答案是,如果子表中的数据需要在数据库中进行汇总或查询,或者需求的增长/变化是可能的,那么单独的表/列更有意义。但是,如果您确信短期/长期内不会发生任何变化,并且不会对结构化数据执行任何分析,那么将它们结合起来以提高性能是有意义的。如果您要进行第三种标准形式的数据库设计,结构化数据是一个非常有趣的问题!这是MySQL的,所以我继续添加了这个标签。好消息!在你的同事提出的模式下,搜索多个答案可能会很棘手。这完全取决于我想说的上下文和用例。我问题的最后一行是否涉及到这一点?或者你说的是不同的东西?是的。如果您需要基于子信息中的数据进行查询,这将是一个坏主意。但是,如果不需要它,并且您认为从长远来看没有必要更改它,那么它是一个合理的结构,这可能会导致需要查询。(但这只是从根本上解决问题……如果需要查询数据,这是个坏主意。