我正在实现以下模型来在我的表中存储与用户相关的数据-我有两列- 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‘的用户?
field-在数据库中使用- JSON或按字段列存储与用户相关的数据(请记住字段的数量不固定),哪种方法更好?另外,如果实现了第一个模型,如何按照上述方式查询数据库?我是否应该同时使用这两个模型,将查询可以搜索的所有数据存储在单独的行中,而将其他数据存储在JSON中(是不同的行)?
更新
既然不会有太多的列需要执行搜索,那么同时使用这两个模型是否明智?我需要搜索的数据是每列一个键,而其他数据是JSON (在同一个MySQL数据库中)?
发布于 2013-03-13 01:15:18
更新2017年6月4日
鉴于这个问题/答案已经获得了一些人气,我认为它值得更新。
当这个问题最初发布时,MySQL还不支持JSON数据类型,而PostgreSQL对它的支持还处于起步阶段。从5.7开始,MySQL now supports a JSON data type (以二进制存储格式)和PostgreSQL JSONB已经明显成熟。这两种产品都提供了可以存储任意文档的高性能JSON类型,包括对JSON对象的特定键进行索引的支持。
但是,我仍然坚持我最初的声明,即在使用关系数据库时,您的默认首选项应该仍然是按值列。关系数据库仍然建立在这样的假设之上,即其中的数据将被相当好地规范化。与查看JSON文档中的键相比,查询规划器在查看列时具有更好的优化信息。外键可以在列之间创建(但不能在JSON文档中的键之间创建)。重要的是:如果您的大多数模式都不稳定到足以证明使用JSON的程度,那么您可能至少需要考虑一下关系数据库是否是正确的选择。
也就是说,很少有应用程序是完全面向关系或面向文档的。大多数应用程序都混合了这两种方法。以下是我个人发现JSON在关系数据库中很有用的一些示例:
我相信还有其他的,但这些只是几个简单的例子。
原始答案
如果您确实希望能够不受限制地添加任意数量的字段(除了任意的文档大小限制之外),可以考虑使用MongoDB这样的NoSQL解决方案。
对于关系数据库:每个值使用一列。将JSON blob放在一个列中会使查询变得几乎不可能(当您实际找到一个可以工作的查询时,速度会慢得令人痛苦)。
关系数据库在索引时利用数据类型,并打算使用规范化结构来实现。
附注:这并不是说您永远不应该将JSON存储在关系数据库中。如果您正在添加真正的元数据,或者如果您的JSON描述的是不需要查询且仅用于显示的信息,那么为所有数据点创建单独的列可能过于夸张了。
发布于 2016-02-11 00:08:10
就像大多数事情一样,“视情况而定”。将数据存储在列或JSON中本身并不是对或错/好或坏。这取决于您稍后需要如何处理它。您预测的访问此数据的方式是什么?您是否需要交叉引用其他数据?
其他人已经很好地回答了什么是技术上的权衡。
没有多少人讨论过你的应用程序和功能随着时间的推移而发展,以及这一数据存储决策如何影响你的团队。
因为使用JSON的诱惑之一是避免迁移模式,因此如果团队不守纪律,很容易将另一个键/值对插入到JSON字段中。它没有迁移,没有人记得它是用来做什么的。上面没有验证。
我的团队在postgres中使用了JSON和传统的列,一开始这是自切片面包以来最好的东西。JSON很有吸引力和强大,直到有一天我们意识到灵活性是有代价的,这突然成了一个真正的痛点。有时候,这一点很快就会出现,然后就很难改变了,因为我们已经在这个设计决策的基础上构建了很多其他的东西。
加班加点,添加新功能,将数据放在JSON中会导致比我们坚持使用传统列所添加的查询更复杂的查询。因此,我们开始将某些键值放回列中,以便我们可以进行连接并在值之间进行比较。馊主意。现在我们有了副本。新的开发人员会加入进来并感到困惑吗?我应该存回的值是什么?JSON one还是column?
JSON字段成了一个垃圾抽屉,里面放着一些零碎的东西。没有数据库级别的数据验证,文档之间没有一致性或完整性。这将所有的责任都推到了应用程序中,而不是从传统的列中获取硬类型和约束检查。
回过头来看,JSON让我们可以非常快速地迭代,并得到一些东西。真是太棒了。然而,当我们达到一定的团队规模后,它的灵活性也允许我们用一长串技术债务来拖累自己,这就减慢了随后的功能演化进程。请谨慎使用。
仔细考虑你的数据的性质。它是你的应用程序的基础。随着时间的推移,数据将如何使用。它可能会发生怎样的变化?
发布于 2013-03-13 01:49:06
简单地说,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
https://stackoverflow.com/questions/15367696
复制相似问题