我正在实现以下模型,用于在表中存储与用户相关的数据--我有两列-uid
(主键)和一列meta
以JSON格式存储有关用户的其他数据。
uid | meta
--------------------------------------------------
1 | {name:['foo'],
| emailid:['foo@bar.com','bar@foo.com']}
--------------------------------------------------
2 | {name:['sann'],
| emailid:['sann@bar.com','sann@foo.com']}
--------------------------------------------------
这是不是一种更好的方法(从性能和设计角度),而不是每个属性一列模型,在该模型中,表将有许多列,如uid
、name
、emailid
。
我喜欢的第一个模型是,你可以添加尽可能多的字段没有限制。
还有,我在想,现在我已经实现了第一个模型。我如何对它执行一个查询,比如,我想要获取所有具有“foo”名称的用户?
问题-使用-JSON或每字段列在数据库中存储用户相关数据(记住字段的数量不是固定的)哪种方法更好?另外,如果实现了第一个模型,那么如何进行上述数据库查询呢?我是否应该同时使用这两种模型,将查询可能搜索的所有数据存储在单独的行中,而将其他数据存储在JSON中(是不同的行)?
由于不会有太多的列需要我执行搜索,这两个模型都使用是明智的吗?对于我需要搜索的数据,使用JSON搜索其他数据(在同一个MySQL数据库中)?
只是把它扔在那里,但WordPress有一个这种东西的结构(至少WordPress是我第一个观察到它的地方,它可能起源于其他地方)。
它允许无限键,搜索速度比使用JSON blob快,但不如一些NoSQL解决方案快。
uid | meta_key | meta_val
----------------------------------
1 name Frank
1 age 12
2 name Jeremiah
3 fav_food pizza
.................
编辑
用于存储历史记录/多个密钥
uid | meta_id | meta_key | meta_val
----------------------------------------------------
1 1 name Frank
1 2 name John
1 3 age 12
2 4 name Jeremiah
3 5 fav_food pizza
.................
并通过以下内容进行查询:
select meta_val from `table` where meta_key = 'name' and uid = 1 order by meta_id desc
就像大多数事情一样“这取决于”。将数据存储在列或JSON中本身并不是对或错/好或坏。这取决于你以后需要用它做什么。您预测的访问此数据的方式是什么?是否需要交叉引用其他数据?
其他人已经很好地回答了技术上的权衡是什么。
没有多少人讨论过你的应用程序和特性会随着时间的推移而演变,以及这个数据存储决策如何影响你的团队。
因为使用JSON的一个诱惑力是避免迁移模式,所以如果团队没有纪律,就很容易将另一个键/值对添加到JSON字段中。没有人会为它迁移,也没有人记得它是为了什么。上面没有验证。
我的团队在postgres中使用JSON,同时使用传统列,一开始它是自切片面包以来最好的东西。JSON很有吸引力,功能也很强大,直到有一天我们意识到灵活性是有代价的,它突然变成了一个真正的痛点。有时候,这一点会很快地变得难以改变,因为我们已经在这个设计决策的基础上构建了很多其他东西。
超时、添加新特性、将数据放在JSON中导致了比我们坚持使用传统列可能增加的查询更复杂的查询。然后,我们开始将某些键值放回列中,这样我们就可以在值之间进行连接和比较。坏主意。现在我们有了复制。一个新的开发人员来了,会感到困惑吗?哪一个是我应该保存的值?JSON还是列?
JSON字段成了这个和那个小片段的垃圾抽屉。没有数据库级别的数据验证,文档之间没有一致性或完整性。这就把所有的责任都推到了应用程序中,而不是从传统的列中进行严格的类型和约束检查。
回顾一下,JSON允许我们非常快速地迭代并获得一些东西。真是太棒了。然而,在我们达到一定的团队规模之后,它的灵活性也允许我们用技术债务的长绳来吊死自己,这就拖慢了随后的特性进化进程。慎用。
仔细思考你的数据的本质是什么。它是你应用程序的基础。随着时间的推移,数据将如何使用。又如何可能发生变化呢?
鉴于这个问题/答案已经获得了一些流行,我认为它值得更新。
当这个问题最初发布时,MySQL还不支持JSON数据类型,PostgreSQL中的支持还处于起步阶段。从5.7开始,MySQL现在支持JSON数据类型(二进制存储格式),并且PostgreSQL JSONB已经显著成熟。这两个产品都提供了可以存储任意文档的Performit JSON类型,包括支持索引JSON对象的特定键。
但是,我仍然坚持我最初的声明,即当使用关系数据库时,默认首选项仍然应该是每值列。关系数据库仍然是建立在这样一个假设上的,即其中的数据将相当好地规范化。查询规划器在查看列时比查看JSON文档中的键时有更好的优化信息。可以在列之间(但不能在JSON文档中的键之间)创建外键。重要的是:如果您的模式大部分都是易变的,足以证明使用JSON是正确的,那么您可能至少需要考虑一下关系数据库是否是正确的选择。
也就是说,很少有应用程序是完全关系型的或面向文档的。大多数应用程序都有两者的混合。以下是我个人发现JSON在关系数据库中很有用的一些示例:
>
当存储联系人的电子邮件地址和电话号码时,将它们作为值存储在JSON数组中比多个单独的表更容易管理
保存任意键/值用户首选项(其中值可以是布尔值、文本值或数值值,并且您不希望为不同的数据类型拥有单独的列)
存储没有定义模式的配置数据(如果您正在构建Zapier或IFTTT并且需要为每个集成存储配置数据)
我相信还有其他的,但这些只是一些简单的例子。
如果您真的希望能够添加任意多个字段而不受任何限制(除了任意的文档大小限制),请考虑MongoDB这样的NoSQL解决方案。
对于关系数据库:每个值使用一列。将JSON blob放入列中会使查询几乎不可能(当您真正找到一个可以工作的查询时,查询速度会非常慢)。
关系数据库在索引时利用数据类型,并打算用规范化的结构来实现。
作为附带说明:这并不是说您永远不应该将JSON存储在关系数据库中。如果您要添加真正的元数据,或者如果您的JSON描述的信息不需要查询,只用于显示,那么为所有数据点创建一个单独的列可能会有些过分。
问题内容: 使用ruby-on-rails,我想存储3个元素的数组:帖子的最后3条评论。我知道我可以将Comment表加入Post 1,但是我会避免出于扩展目的而进行大量的请求。 所以我想知道什么是存储这三个元素的最佳方法,因为我想在每次发表新评论时轻松地更新它们:删除最后一条评论并添加新评论。 正确的方法是什么?将其存储在序列化数组还是JSON对象中? 问题答案: 您可以使用ActiveReco
又不想工作,我不知道是怎么回事。 日志包含以下消息: 将项目放在github https://github.com/romanych2021/testjpaspring上
问题内容: 是否可以为分配一个特定的? 我想创建一个测试环境,通常我想在其中使用测试数据源,但是有一些应该在不同的数据库(生产数据库;只读操作)上运行。 我可以明确告诉Spring将哪个数据源用于存储库吗? 问题答案: 是您问题的答案。这应该根据非正式文件一起使用。 请参阅此详细教程,以了解如何执行此操作。我并没有尽力在此处发布代码,因为您可以直接在其中更清楚地引用它们。 链接到教程…
是否可以将特定的分配给?
问题内容: 因此,在C ++ / C#中,您可以创建标志枚举来保存多个值,并且在数据库中存储单个有意义的整数当然是微不足道的。 在Java中,您有EnumSets,这似乎是在内存中传递枚举的一种很好的方法,但是如何将组合的EnumSet输出为整数进行存储?还有另一种方法可以解决这个问题吗? 问题答案:
问题内容: 如何在SQLite数据库中存储JSON对象?正确的方法是什么? 一个地方是Blob类型列。如果我可以将JSON对象转换为字节数组并使用Fileoutputstream 另一个想法是将文本列存储为字符串 问题答案: 将JSONObject转换为String并另存为TEXT / VARCHAR。 在检索同一列时,将String转换为JSONObject。 例如 写入数据库 从数据库读取