在数据库中存储JSON与为每个密钥创建一个新列?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (24)

我正在实现下面的模型来存储用户相关的数据在我的表中 - 我有2列 - 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']}
--------------------------------------------------

这是一个更好的方式(性能明智的,设计明智)比一列,每个属性模型,其中表将不得不像许多列uidnameemailid

我喜欢的第一个模型是,您可以添加尽可能多的字段,没有限制。

另外,我想知道,现在我已经实现了第一个模型。我如何对其执行查询,例如,我想获取所有名称为“foo”的用户?

问题 - 在数据库中使用-JSON或者每场都存储用户相关数据的更好方法(记住字段数目不固定)?另外,如果实施第一个模型,如何按上述方式查询数据库?我是否应该使用这两种模型,将所有可能由查询搜索的数据存储在单独的行中,并将其他数据存储在JSON中(是不同的行)?

提问于
用户回答回答于

像大多数事情“取决于”。在数据列或JSON中存储数据本身并不是对或错/好或坏。这取决于你以后需要做什么。你预计访问这些数据的方式是什么?你需要交叉引用其他数据吗?

其他人已经很好地回答了技术权衡的问题。

没有多少人讨论过你的应用和功能会随着时间的推移而发生变化,以及此数据存储决策如何影响您的团队。

因为使用JSON的诱惑之一是为了避免迁移模式,所以如果团队没有遵守规则,那么将另一个键/值对插入JSON字段非常容易。没有任何迁移,没有人记得它的用途。没有验证。

我的团队在postgres的侧面传统栏目中使用了JSON。JSON很吸引人,而且功能强大,直到有一天我们意识到灵活性是以牺牲成本为代价的,这突然成为一个真正的痛点。有时候,这一点非常迅速地升高,然后变得很难改变,因为我们在这个设计决策的基础上构建了很多其他的东西。

加班时,添加新功能,使用JSON中的数据导致查询查询比查看传统列时可能添加的查询更复杂。因此,我们开始将某些关键值捕获到列中,以便我们可以进行连接并对值进行比较。馊主意。现在我们有重复。一个新的开发者会加入并且感到困惑?我应该挽回的价值是什么?JSON一个还是列?

JSON字段成为这个和那个小部分的垃圾抽屉。数据库级没有数据验证,文档之间没有一致性或完整性。这将所有责任推入应用程序,而不是从传统列中获取硬性类型和约束检查。

回顾一下,JSON使我们能够快速迭代并获得一些东西。太好了。然而,在我们达到一定团队规模后,它的灵活性也使我们能够用一长串技术债务来悬挂自己,然后减慢随后的特征演变进程。谨慎使用。

用户回答回答于

从5.7开始,MySQL 现在支持JSON数据类型(采用二进制存储格式),而PostgreSQL JSONB已经显着成熟。这两种产品都提供可以存储任意文档的高性能JSON类型,包括支持索引JSON对象的特定键。

但是,我仍然坚持我原来的声明,即在使用关系数据库时,您的默认首选项仍应为每列值。关系数据库仍然建立在假设它们内部的数据将被很好地标准化的基础上。在查看列时,查询规划器比查看JSON文档中的键时具有更好的优化信息。可以在列之间创建外键(但不能在JSON文档中的键之间)。重要的是:如果大部分模式足够易于使用JSON,那么您可能至少要考虑关系数据库是否是正确的选择。

也就是说,很少的应用程序完全是关系型或面向文档的。大多数应用程序都有一些混合使用。以下是我个人发现JSON在关系数据库中有用的一些示例:

  • 存储联系人的电子邮件地址和电话号码时,将它们作为JSON数组中的值进行存储比多个单独的表格更容易管理
  • 保存任意键/值用户首选项(值可以是布尔值,文本值或数字值,并且不希望为不同的数据类型分开列)
  • 存储没有定义模式的配置数据(如果您正在构建Zapier或IFTTT并需要为每个集成存储配置数据)

扫码关注云+社区