我正在实现以下模型存储用户相关的数据在我的表-我有2列- uid(主键)和一个元列,其中存储关于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数据库)?
2017年6月4日更新
鉴于这个问题/答案已经获得了一些欢迎,我认为它值得更新。
当这个问题最初发布时,MySQL还不支持JSON数据类型,而PostgreSQL的支持还处于起步阶段。从5.7开始,MySQL现在支持JSON数据类型(二进制存储格式),而PostgreSQL JSONB已经显著成熟。这两个产品都提供了可以存储任意文档的高性能JSON类型,包括支持索引JSON对象的特定键。
However, I still stand by my original statement that your default preference, when using a relational database, should still be column-per-value. Relational databases are still built on the assumption of that the data within them will be fairly well normalized. The query planner has better optimization information when looking at columns than when looking at keys in a JSON document. Foreign keys can be created between columns (but not between keys in JSON documents). Importantly: if the majority of your schema is volatile enough to justify using JSON, you might want to at least consider if a relational database is the right choice.
也就是说,很少有应用程序是完全关系的或面向文档的。大多数应用程序都是两者的混合。以下是我个人认为JSON在关系数据库中很有用的一些例子:
在存储联系人的电子邮件地址和电话号码时,将它们存储为JSON数组中的值要比管理多个单独的表容易得多
保存任意键/值用户首选项(其中值可以是布尔值、文本值或数字值,并且您不希望为不同的数据类型设置单独的列)
存储没有定义模式的配置数据(如果您正在构建Zapier或IFTTT,并且需要为每个集成存储配置数据)
我相信还有其他的例子,但这只是几个简单的例子。
原来的答案
如果您真的希望能够添加任意数量的字段,而不受任何限制(除了任意文档大小限制之外),可以考虑使用NoSQL解决方案,例如MongoDB。
对于关系数据库:每个值使用一列。将JSON blob放在列中几乎不可能进行查询(并且当您真正找到一个有效的查询时,会非常缓慢)。
关系数据库在建立索引时利用了数据类型的优势,并打算用规范化的结构来实现。
顺便说一句:这并不是说永远不应该在关系数据库中存储JSON。如果要添加真正的元数据,或者JSON描述的信息不需要查询,只用于显示,那么为所有数据点创建一个单独的列可能有些过分。
2017年6月4日更新
鉴于这个问题/答案已经获得了一些欢迎,我认为它值得更新。
当这个问题最初发布时,MySQL还不支持JSON数据类型,而PostgreSQL的支持还处于起步阶段。从5.7开始,MySQL现在支持JSON数据类型(二进制存储格式),而PostgreSQL JSONB已经显著成熟。这两个产品都提供了可以存储任意文档的高性能JSON类型,包括支持索引JSON对象的特定键。
However, I still stand by my original statement that your default preference, when using a relational database, should still be column-per-value. Relational databases are still built on the assumption of that the data within them will be fairly well normalized. The query planner has better optimization information when looking at columns than when looking at keys in a JSON document. Foreign keys can be created between columns (but not between keys in JSON documents). Importantly: if the majority of your schema is volatile enough to justify using JSON, you might want to at least consider if a relational database is the right choice.
也就是说,很少有应用程序是完全关系的或面向文档的。大多数应用程序都是两者的混合。以下是我个人认为JSON在关系数据库中很有用的一些例子:
在存储联系人的电子邮件地址和电话号码时,将它们存储为JSON数组中的值要比管理多个单独的表容易得多
保存任意键/值用户首选项(其中值可以是布尔值、文本值或数字值,并且您不希望为不同的数据类型设置单独的列)
存储没有定义模式的配置数据(如果您正在构建Zapier或IFTTT,并且需要为每个集成存储配置数据)
我相信还有其他的例子,但这只是几个简单的例子。
原来的答案
如果您真的希望能够添加任意数量的字段,而不受任何限制(除了任意文档大小限制之外),可以考虑使用NoSQL解决方案,例如MongoDB。
对于关系数据库:每个值使用一列。将JSON blob放在列中几乎不可能进行查询(并且当您真正找到一个有效的查询时,会非常缓慢)。
关系数据库在建立索引时利用了数据类型的优势,并打算用规范化的结构来实现。
顺便说一句:这并不是说永远不应该在关系数据库中存储JSON。如果要添加真正的元数据,或者JSON描述的信息不需要查询,只用于显示,那么为所有数据点创建一个单独的列可能有些过分。
只是随便说说,但是WordPress有一个关于这类东西的结构(至少WordPress是我第一个观察到它的地方,它可能起源于其他地方)。
它允许无限的键,并且比使用JSON blob搜索更快,但不如一些NoSQL解决方案快。
uid | meta_key | meta_val
----------------------------------
1 name Frank
1 age 12
2 name Jeremiah
3 fav_food pizza
.................
EDIT
用于存储历史记录/多个键
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