当前位置:  开发笔记 > 编程语言 > 正文

将数据存储在MySQL中作为JSON

如何解决《将数据存储在MySQL中作为JSON》经验,为你挑选了10个好方法。

我认为这是件好事.所以,我从来没有这样做过.然后我看到FriendFeed做到了这一点并且实际上使他们的DB规模更好并且减少了延迟.我很好奇我是否应该这样做.如果是这样,那么正确的方法是什么?

基本上,什么是学习如何将所有内容存储在MySQL中作为CouchDB类DB的好地方?将所有内容存储为JSON似乎更容易,更快(不构建,减少延迟).

此外,在DB上存储为JSON的内容是否易于编辑,删除等?



1> Lewis Richar..:

每个人评论似乎都是从错误的角度来看这个,通过PHP在关系数据库中存储JSON代码是很好的,实际上加载和显示这样的复杂数据会更快,但是你会有设计考虑因素,比如搜索,索引等

这样做的最好方法是使用混合数据,例如,如果你需要根据日期时间进行搜索,MySQL(性能调整)将比PHP快得多,而且搜索场地的距离也应该是很多的MySQL更快(注意搜索不访问).然后,您不需要搜索的数据可以以JSON,BLOB或您认为必要的任何其他格式存储.

您需要访问的数据非常容易存储为JSON,例如基本的每个案例的发票系统.如果你有正确的HTML表单结构,它们根本不会从RDBMS中受益很多,只能通过json_encoding($ _ POST ['entires'])存储在JSON中.

我很高兴你使用MongoDB很开心,我希望它能继续为你服务,但是不要认为MySQL总是不受你的关注,因为你的应用程序的复杂性增加你可能最终需要一个RDBMS一些功能和特性(即使它只是用于退出存档数据或业务报告)


如上所述,这取决于您存储的内容,即对于发票,您是否真的需要单独存储每个条目?不,你的评论就像你知道的那样,但1NF并不适用于每个领域,或者不会有BLOB和文本类型......这对于生产系统来说是纯粹的废话,你只需要优化你需要搜索的内容即日期,关键和一些数据的设置索引.我没有说将所有内容都存储为JSON,我说如果它有助于解决您的问题,那么将一些数据存储为JSON.
你假设我在这个问题上没有咨询过DBA而且不明白你在说什么.对于小型系统和更进一步的系统,我并没有完全了解这对于它的影响,但我所说的是你错了,你指出的研究是陈旧的而不是使用我们的应用程序战略.它只是完全错误,并且在这个过程的不良实现中存在问题.例如,我并不是说只有一个模型或者不使用RDBMS,我说要明智地使用RDBMS以及不需要的地方.
-1表示"可以通过PHP在关系数据库中存储JSON代码" - 在单个字段中存储JSON(可以将整个实体表示为非原子数据)会违反关系模型并阻止1NF.此外,如果没有指标支持您,请不要对性能做出全面的声明.
根据我的经验,这是最好的答案.您可以使用RDBMS但仅在特定情况下存储JSON,如果您知道自己在做什么.事实上,我已经将它用于阵列数据的临时缓存存储以及其他一些可以实现更快结果和更少代码的情况.实际上许多项目都有一些混合特征.
你说的是可能和方便的,但偏离良好的关系意味着做更多的工作来适应和维持所述偏差.对关系模型进行混淆需要比你提供的更好的理由.有关与答案相关的复杂性的更多信息,请参阅Kroenke和Auer的数据库处理,因为它们涉及关系中属性的滥用.

2> eecue..:

MySQL 5.7现在支持类似于MongoDB和其他无模式文档数据存储的本机JSON数据类型:

JSON支持

从MySQL 5.7.8开始,MySQL支持本机JSON类型.JSON值不存储为字符串,而是使用允许对文档元素进行快速读取访问的内部二进制格式.存储在JSON列中的JSON文档会在插入或更新时自动验证,并且无效文档会产生错误.JSON文档在创建时进行了规范化,可以使用大多数比较运算符进行比较,例如=,<,<=,>,> =,<>,!=和<=>; 有关受支持的运算符以及MySQL在比较JSON值时遵循的优先级和其他规则的信息,请参阅JSON值的比较和排序.

MySQL 5.7.8还引入了许多用于处理JSON值的函数.这些功能包括这里列出的功能:

    创建JSON值的函数:JSON_ARRAY(),JSON_MERGE()和JSON_OBJECT().请参见第12.16.2节"创建JSON值的函数".

    搜索JSON值的函数:JSON_CONTAINS(),JSON_CONTAINS_PATH(),JSON_EXTRACT(),JSON_KEYS()和JSON_SEARCH().请参见第12.16.3节"搜索JSON值的函数".

    修改JSON值的函数:JSON_APPEND(),JSON_ARRAY_APPEND(),JSON_ARRAY_INSERT(),JSON_INSERT(),JSON_QUOTE(),JSON_REMOVE(),JSON_REPLACE(),JSON_SET()和JSON_UNQUOTE().请参见第12.16.4节"修改JSON值的函数".

    提供有关JSON值的信息的函数:JSON_DEPTH(),JSON_LENGTH(),JSON_TYPE()和JSON_VALID().请参见第12.16.5节"返回JSON值属性的函数".

在MySQL 5.7.9及更高版本中,您可以使用column-> path作为JSON_EXTRACT(列,路径)的简写.这可以作为列的别名,只要在SQL语句中可以出现列标识符,包括WHERE,ORDER BY和GROUP BY子句.这包括SELECT,UPDATE,DELETE,CREATE TABLE和其他SQL语句.左侧必须是JSON列标识符(而不是别名).右侧是引用的JSON路径表达式,它根据作为列值返回的JSON文档进行评估.

有关 - >和JSON_EXTRACT()的更多信息,请参见第12.16.3节"搜索JSON值的函数".有关MySQL 5.7中的JSON路径支持的信息,请参阅搜索和修改JSON值.另请参见二级索引和虚拟生成的列.

更多信息:

https://dev.mysql.com/doc/refman/5.7/en/json.html



3> deceze..:

CouchDB和MySQL是两种非常不同的野兽.JSON是在CouchDB中存储东西的本地方式.在MySQL中,您可以做的最好的事情是将JSON数据作为文本存储在单个字段中.这完全违背了将其存储在RDBMS中的目的,并且会使每个数据库事务复杂化.

别.

话虽如此,FriendFeed似乎在MySQL之上使用了极其自定义的架构.这实际上取决于你想要存储什么,关于如何滥用数据库系统几乎没有一个明确的答案,所以它对你有意义.鉴于文章非常陈旧,他们反对Mongo和Couch的主要原因是不成熟,如果MySQL没有为你剪掉它,我会重新评估这两个.他们现在应该已经成长了很多.


肯定存在用于在RDBMS中存储JSON blob的有效情况.如果您只想存储和检索不透明的JSON数据blob而不需要查询该数据(这在某些情况下经常发生),您可能会很好地执行此操作.
@markus我实际上在我的一个网站上这样做,特别是在MySQL查询中没有直接搜索的复杂表单的字段,但在查看表单时使用(从表视图或直接通过链接).它可能并不理想,但它确实使实现更快,并且不再需要过多的表或表列.
这是很短的建议,也许是某个在堆栈交换上花费太多时间的人提供的建议?当我有一个要存储的包含100个字段的记录并且只需要搜索3个或4个字段时,创建一个包含100个字段的表是没有意义的。您可以将客户记录及其整个地址簿存储在JSON的1字段中,只需添加客户ID,姓氏,公司等其他字段即可用于搜索记录。它是。节省大量时间。
是的,我正在看Mongo,php有它的扩展,数据库事务的实际语法似乎比MySQL更容易,整体使用它似乎更容易couchDB.谢谢,我想我会选择MongoDB :)

4> RobertPitt..:

json字符在存储,字符等方面没有什么特别之处

{,},[,],',a-z,0-9......真的没什么特别的,并且可以存储为文本.

你要遇到的第一个问题就是这个问题

{profile_id:22,用户名:'Robert',密码:'skhgeeht893htgn34ythg9er'}

存储在数据库中的更新并不是那么简单,除非你有自己的进行并为mysql开发了一个jsondecode

UPDATE users SET JSON(user_data,'username') = 'New User';

所以当你不能这样做时,你必须首先选择json,解码它,更改它,更新它,所以从理论上讲你可能会花更多的时间来构建一个合适的数据库结构!

我确实使用json来存储数据,但只使用Meta Data,不经常更新的数据,与用户特定的相关...例如,如果用户添加帖子,并且在该帖子中他添加了图像,解析图像并创建拇指和然后使用json格式的拇指网址.



5> Jorjon..:

为了说明使用查询获取JSON数据有多困难,我将分享我为处理此问题而进行的查询.

它不考虑数组或其他对象,只考虑基本数据类型.您应该将的4个实例更改为存储JSON的列名,并将myfield的4个实例更改为您要访问的JSON字段.

SELECT
    SUBSTRING(
        REPLACE(REPLACE(REPLACE(column, '{', ''), '}', ','), '"', ''),
        LOCATE(
            CONCAT('myfield', ':'),
            REPLACE(REPLACE(REPLACE(column, '{', ''), '}', ','), '"', '')
        ) + CHAR_LENGTH(CONCAT('myfield', ':')),
        LOCATE(
            ',',
            SUBSTRING(
                REPLACE(REPLACE(REPLACE(column, '{', ''), '}', ','), '"', ''),
                LOCATE(
                    CONCAT('myfield', ':'),
                    REPLACE(REPLACE(REPLACE(column, '{', ''), '}', ','), '"', '')
                ) + CHAR_LENGTH(CONCAT('myfield', ':'))
            )
        ) - 1
    )
    AS myfield
FROM mytable WHERE id = '3435'


你不会查询这个服务器端.这将是存储blob并将其返回到客户端.然后你只需使用JS来查询它.这是很久以前的事情:)我已经移动到MongoDB这个东西:) Upvote这个漂亮的光滑查询.

6> Phil LaNasa..:

这真的取决于你的用例.如果您存储的信息在报告中绝对没有价值,并且不会通过JOIN与其他表进行查询,那么将数据存储在一个编码为JSON的单个文本字段中可能是有意义的.

这可以大大简化您的数据模型.但是,正如RobertPitt所提到的,不要指望能够将这些数据与已经规范化的其他数据相结合.


我的想法完全正确 如果其数据从未加入/搜索或甚至很少更新,为什么不在TEXT字段中使用json.一个很好的例子是fooditem表,其中每个食品需要存储营养信息.服务大小,蛋白质,碳水化合物,脂肪总量,脂肪坐等等.但不仅如此,您需要存储值(0.2)和测量单位(g,oz,fl oz,ml).考虑到数据(取决于你在做什么,我猜)不需要搜索我会说1 TEXT vs 16 int/varchar/enum列是一个很好的权衡.

7> cytsunny..:

这是一个老问题,但我仍然可以在谷歌搜索结果的顶部看到这一点,所以我想在提出问题4年后添加一个新答案是有意义的.

首先,在RDBMS中存储JSON有更好的支持.您可以考虑切换到PostgreSQL(尽管MySQL自v5.7.7起支持JSON).PostgreSQL使用与MySQL非常相似的SQL命令,除了它们支持更多功能.他们添加的一个功能是它们提供JSON数据类型,您现在可以查询存储的JSON.(有些参考)如果您没有直接在程序中编写查询,例如,在php中使用PDO或在Laravel中使用eloquent,您只需在服务器上安装PostgreSQL并更改数据库连接设置即可.您甚至不需要更改代码.

大多数时候,正如其他答案所建议的那样,将数据直接存储在RDBMS中并不是一个好主意.但有一些例外.我能想到的一种情况是具有可变数量的链接条目的字段.

例如,为了存储博客文章的标签,通常需要有一个博客文章表,一个标签表和一个匹配表.因此,当用户想要编辑帖子并且您需要显示哪个标签与该帖子相关时,您将需要查询3个表格.如果匹配的表/标签表很长,这将大大损害性能.

通过将标记作为JSON存储在博客帖子表中,相同的操作仅需要单个表搜索.然后,用户将能够更快地看到要编辑的博客帖子,但如果您要报告哪些帖子链接到标签,或者可能按标签搜索,则会损害性能.

您也可以尝试对数据库进行反规范化.通过复制数据并以两种方式存储数据,您可以获得两种方法的好处.您只需要更多的时间来存储数据和更多的存储空间(与更高的计算能力相比,这是便宜的)



8> Brian..:

我想说的唯一两个理由是:

使用标准化方法,性能不够好

您无法轻易建模出特别流畅/灵活/变化的数据

我在这里写了一些关于我自己的方法:

使用NoSQL数据存储时遇到了哪些可伸缩性问题?

(见最佳答案)

即使JSON不够快,我们也使用了自定义文本格式方法.工作/继续为我们工作.

有没有理由你没有使用像MongoDB这样的东西?(可能是MySQL是"必需的";只是好奇)



9> CheddarMonke..:

在我看来,每个回答这个问题的人都会错过一个关键问题,除了@deceze - 使用正确的工具来完成工作.您可以强制关系数据库存储几乎任何类型的数据,您可以强制Mongo处理关系数据,但代价是什么?从架构设计到应用程序代码,您最终会在各个级别的开发和维护中引入复杂性; 更不用说性能打击了.

2014年,我们可以访问许多数据库服务器,这些服务器非常好地处理特定类型的数据.

Mongo(文件存储)

Redis(键值数据存储)

MySQL/Maria/PostgreSQL/Oracle/etc(关系数据)

CouchDB(JSON)

我敢肯定我错过了其他一些人,比如RabbirMQ和Cassandra.我的观点是,使用正确的工具来存储您需要的数据.

如果您的应用程序需要真正,非常快速地存储和检索各种数据,(并且没有)不要回避为应用程序使用多个数据源.最流行的Web框架提供对多个数据源(Rails,Django,Grails,Cake,Zend等)的支持.此策略将复杂性限制为应用程序的一个特定区域,ORM或应用程序的数据源接口.



10> Subin..:

这是一个保存/更新列中JSON数组的键的函数,以及另一个检索JSON值的函数.假设存储JSON数组的列名是json,创建此函数.它正在使用PDO.

保存/更新功能

function save($uid, $key, $val){
 global $dbh; // The PDO object
 $sql = $dbh->prepare("SELECT `json` FROM users WHERE `id`=?");
 $sql->execute(array($uid));
 $data      = $sql->fetch();
 $arr       = json_decode($data['json'],true);
 $arr[$key] = $val; // Update the value
 $sql=$dbh->prepare("UPDATE `users` SET `json`=? WHERE `id`=?");
 $sql->execute(array(
   json_encode($arr), 
   $uid
 ));
}

其中$ uid是用户的id,$ key - 要更新的JSON密钥,它的值被称为$ val.

获得价值功能

function get($uid, $key){
 global $dbh;
 $sql = $dbh->prepare("SELECT `json` FROM `users` WHERE `id`=?");
 $sql->execute(array($uid));
 $data = $sql->fetch();
 $arr  = json_decode($data['json'], true);
 return $arr[$key];
}

其中$ key是我们需要值的JSON数组的键.

推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有