1. php存入数据库 如何将json格式的数据直接存入mysql数据库
把json字符串存入数据库,如果数据库里面存储的字段是字符串类型或者text的话是可以直接存入的。
例如:
$sql="insertintotablename(fieldname)values('$jsondata')";
mysql_query($sql);
这样就好了。
2. mysql数据库中某个字段存的是json数据,如何对json数据中的数据进行操作
这个可以吧json格式的字符串解析成数组json_decode()函数,变成数组以后就可以方便操作了,可以删除数组中的任意一项,也可以增加一项比如:array_push($data,['sort'=>3,'catentryId'=>10003]),再变成json格式的存入数据库。方法有多种,这里简单的示例下
3. mysql使用什么类型存 json数据
JSON (JavaScriptObject Notation) 是一种轻量级的数据交换格式,主要用于传送数据。JSON采用了独立于语言的文本格式,类似XML,但是比XML简单,易读并且易编写。对机器来说易于解析和生成,并且会减少网络带宽的传输。由于JSON格式可以解耦javascript客户端应用与Restful服务器端的方法调用,因而在互联网应用中被大量使用。
JSON的格式非常简单:名称/键值。之前MySQL版本里面要实现这样的存储,要么用VARCHAR要么用TEXT大文本。 MySQL5.7发布后,专门设计了JSON数据类型以及关于这种类型的检索以及其他函数解析。我们先看看MySQL老版本的JSON存取。
示例表结构:
CREATE TABLE json_test(
id INT,
person_desc TEXT
)ENGINE INNODB;
我们来插入一条记录:
INSERT INTO json_test VALUES (1,'{
"programmers": [{
"firstName": "Brett",
"lastName": "McLaughlin",
"email": "aaaa"
}, {
"firstName": "Jason",
"lastName": "Hunter",
"email": "bbbb"
}, {
"firstName": "Elliotte",
"lastName": "Harold",
"email": "cccc"
}],
"authors": [{
"firstName": "Isaac",
"lastName": "Asimov",
"genre": "sciencefiction"
}, {
"firstName": "Tad",
"lastName": "Williams",
"genre":"fantasy"
}, {
"firstName": "Frank",
"lastName": "Peretti",
"genre": "christianfiction"
}],
"musicians": [{
"firstName": "Eric",
"lastName": "Clapton",
"instrument": "guitar"
}, {
"firstName": "Sergei",
"lastName": "Rachmaninoff",
"instrument": "piano"
}]
}');
那一般我们遇到这样来存储JSON格式的话,只能把这条记录取出来交个应用程序,由应用程序来解析。如此一来,JSON又和特定的应用程序耦合在一起,其便利性的优势大打折扣。
现在到了MySQL5.7,可以支持对JSON进行属性的解析,我们重新修改下表结构:
ALTER TABLE json_test MODIFY person_desc json;
先看看插入的这行JSON数据有哪些KEY:
mysql> SELECT id,json_keys(person_desc) as "keys" FROM json_test\G
*************************** 1. row***************************
id: 1
keys: ["authors", "musicians","programmers"]
1 row in set (0.00 sec)
我们可以看到,里面有三个KEY,分别为authors,musicians,programmers。那现在找一个KEY把对应的值拿出来:
mysql> SELECT json_extract(AUTHORS,'$.lastName[0]') AS 'name', AUTHORS FROM
-> (
-> SELECT id,json_extract(person_desc,'$.authors[0][0]') AS "authors" FROM json_test
->UNION ALL
-> SELECT id,json_extract(person_desc,'$.authors[1][0]') AS "authors" FROM json_test
-> UNION ALL
-> SELECT id,json_extract(person_desc,'$.authors[2][0]') AS "authors" FROM json_test
-> ) AS T1
-> ORDER BY NAME DESC\G
*************************** 1. row***************************
name:"Williams"
AUTHORS: {"genre": "fantasy","lastName": "Williams", "firstName":"Tad"}
*************************** 2. row***************************
name:"Peretti"
AUTHORS: {"genre":"christianfiction", "lastName": "Peretti","firstName": "Frank"}
*************************** 3. row***************************
name:"Asimov"
AUTHORS: {"genre": "sciencefiction","lastName": "Asimov", "firstName":"Isaac"}
3 rows in set (0.00 sec)
现在来把详细的值罗列出来:
mysql> SELECT
->json_extract(AUTHORS,'$.firstName[0]') AS "firstname",
-> json_extract(AUTHORS,'$.lastName[0]')AS "lastname",
-> json_extract(AUTHORS,'$.genre[0]') AS"genre"
-> FROM
-> (
-> SELECT id,json_extract(person_desc,'$.authors[0]')AS "authors" FROM json
_test
-> ) AS T\G
*************************** 1. row***************************
firstname: "Isaac"
lastname:"Asimov"
genre:"sciencefiction"
1 row in set (0.00 sec)
我们进一步来演示把authors 这个KEY对应的所有对象删掉。
mysql> UPDATE json_test
-> SET person_desc =json_remove(person_desc,'$.authors')\G
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
查找下对应的KEY,发现已经被删除掉了。
mysql> SELECT json_contains_path(person_desc,'all','$.authors')as authors_exists FROM json_test\G
*************************** 1. row***************************
authors_exists: 0
1 row in set (0.00 sec)
总结下,虽然MySQL5.7开始支持JSON数据类型,但是我建议如果要使用的话,最好是把这样的值取出来,然后在应用程序段来计算。毕竟数据库是用来处理结构化数据的,大量的未预先定义schema的json解析,会拖累数据库的性能。
4. mysql5.7支持json是要干掉mongodb吗
在MySQL与PostgreSQL的对比中,PG的JSON格式支持优势总是不断被拿来比较。其实早先MariaDB也有对非结构化的数据进行存储的方案,称为dynamic column,但是方案是通过BLOB类型的方式来存储。这样导致的问题是查询性能不高,不能有效建立索引,与一些文档数据库对比,优势并不大,故在社区的反应其实比较一般。当然,MariaDB的dynamic column功能还不仅限于非结构化数据的存储,但不在本文进行展开。
MySQL 5.7.7 labs版本开始InnoDB存储引擎已经原生支持JSON格式,该格式不是简单的BLOB类似的替换。原生的JSON格式支持有以下的优势:
JSON数据有效性检查:BLOB类型无法在数据库层做这样的约束性检查
查询性能的提升:查询不需要遍历所有字符串才能找到数据
支持索引:通过虚拟列的功能可以对JSON中的部分数据进行索引
mysql> create table user ( uid int auto_increment, -> data json,primary key(uid))engine=innodb; Query OK, 0 rows affected (0.01 sec) mysql> insert into user values (NULL, -> '{"name":"David","mail":"[email protected]","address":"Shangahai"}'); Query OK, 1 row affected (0.00 sec) mysql> insert into user values (NULL,'{"name":"Amy","mail":"[email protected]"}'); Query OK, 1 row affected (0.00 sec)
可以看到我们新建了表user,并且将列data定义为了JSON类型。这意味着我们可以对插入的数据做JSON格式检查,确保其符合JSON格式的约束,如插入一条不合法的JSON数据会报如下错误:
mysql> insert into user values (NULL,"test"); ERROR 3130 (22032): Invalid JSON text: "Invalid value" at position 2 in value (or column) 'test'.
此外,正如前面所说的,MySQL 5.7提供了一系列函数来高效地处理JSON字符,而不是需要遍历所有字符来查找,这不得不说是对MariaDB dynamic column的巨大改进:
mysql> select jsn_extract(data, '$.name'),jsn_extract(data,'$.address') from user; +-----------------------------+-------------------------------+ | jsn_extract(data, '$.name') | jsn_extract(data,'$.address') | +-----------------------------+-------------------------------+ | "David" | "Shangahai" | | "Amy" | NULL | +-----------------------------+-------------------------------+ 2 rows in set (0.00 sec)
当然,最令人的激动的功能应该是MySQL 5.7的虚拟列功能,通过传统的B+树索引即可实现对JSON格式部分属性的快速查询。使用方法是首先创建该虚拟列,然后在该虚拟列上创建索引:
mysql> ALTER TABLE user ADD user_name varchar(128) -> GENERATED ALWAYS AS (jsn_extract(data,'$.name')) VIRTUAL; Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> select user_name from user; +-----------+ | user_name | +-----------+ | "Amy" | | "David" | +-----------+ 2 rows in set (0.00 sec) mysql> alter table user add index idx_username (user_name); Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0
然后可以通过添加的索引对用户名进行快速的查询,这和普通类型的列查询一样。而通过explain可以验证优化器已经选择了在虚拟列上创建的新索引:
mysql> explain select * from user where user_name='"Amy"'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: user partitions: NULL type: ref possible_keys: idx_username key: idx_username key_len: 131 ref: const rows: 1 filtered: 100.00 Extra: NULL 1 row in set, 1 warning (0.00 sec)
5. mysql存储过程处理json格式内容
找MYSQL JSON UDF吧,原生并没有JSON解码支持
6. mysql使用什么类型存json数据
JSON (JavaScriptObject Notation) 是一种轻量级的数据交换格式,主要用于传送数据。JSON采用了独立于语言的文本格式,类似XML,但是比XML简单,易读并且易编写。对机器来说易于解析和生成,并且会减少网络带宽的传输。由于JSON格式可以解耦javascript客户端应用与Restful服务器端的方法调用,因而在互联网应用中被大量使用。
7. 如果将json格式数据存储到类似mysql这样的关系型数据库中,怎么查
在MySQL与PostgreSQL的对比中,PG的JSON格式支持优势总是不断被拿来比较。其实早先MariaDB也有对非结构化的数据进行存储的方案,称为dynamic column,但是方案是通过BLOB类型的方式来存储。这样导致的问题是查询性能不高,不能有效建立索引,与一些文档数据库对比,优势并不大,故在社区的反应其实比较一般。当然,MariaDB的dynamic column功能还不仅限于非结构化数据的存储,但不在本文进行展开。
MySQL 5.7.7 labs版本开始InnoDB存储引擎已经原生支持JSON格式,该格式不是简单的BLOB类似的替换。原生的JSON格式支持有以下的优势:
JSON数据有效性检查:BLOB类型无法在数据库层做这样的约束性检查
查询性能的提升:查询不需要遍历所有字符串才能找到数据
支持索引:通过虚拟列的功能可以对JSON中的部分数据进行索引
首先我们来看如何在MySQL中使用原生的JSON格式:
mysql> create table user ( uid int auto_increment,
-> data json,primary key(uid))engine=innodb;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into user values (NULL,
-> '{"name":"David","mail":"[email protected]","address":"Shangahai"}');
Query OK, 1 row affected (0.00 sec)
mysql> insert into user values (NULL,'{"name":"Amy","mail":"[email protected]"}');
Query OK, 1 row affected (0.00 sec)
可以看到我们新建了表user,并且将列data定义为了JSON类型。这意味着我们可以对插入的数据做JSON格式检查,确保其符合JSON格式的约束,如插入一条不合法的JSON数据会报如下错误:
mysql> insert into user values (NULL,"test");
ERROR 3130 (22032): Invalid JSON text: "Invalid value" at position 2 in value (or column) 'test'.
此外,正如前面所说的,MySQL 5.7提供了一系列函数来高效地处理JSON字符,而不是需要遍历所有字符来查找,这不得不说是对MariaDB dynamic column的巨大改进:
mysql> select jsn_extract(data, '$.name'),jsn_extract(data,'$.address') from user;
+-----------------------------+-------------------------------+
| jsn_extract(data, '$.name') | jsn_extract(data,'$.address') |
+-----------------------------+-------------------------------+
| "David" | "Shangahai" |
| "Amy" | NULL |
+-----------------------------+-------------------------------+
2 rows in set (0.00 sec)
当然,最令人的激动的功能应该是MySQL 5.7的虚拟列功能,通过传统的B+树索引即可实现对JSON格式部分属性的快速查询。使用方法是首先创建该虚拟列,然后在该虚拟列上创建索引:
mysql> ALTER TABLE user ADD user_name varchar(128)
-> GENERATED ALWAYS AS (jsn_extract(data,'$.name')) VIRTUAL;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select user_name from user;
+-----------+
| user_name |
+-----------+
| "Amy" |
| "David" |
+-----------+
2 rows in set (0.00 sec)
mysql> alter table user add index idx_username (user_name);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
然后可以通过添加的索引对用户名进行快速的查询,这和普通类型的列查询一样。而通过explain可以验证优化器已经选择了在虚拟列上创建的新索引:
mysql> explain select * from user where user_name='"Amy"'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user
partitions: NULL
type: ref
possible_keys: idx_username
key: idx_username
key_len: 131
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
可以发现MySQL 5.7对于JSON格式堪称完美,相信PostgreSQL阵营需要寻找新的策略来“攻击”MySQL了吧。如无意外,还是会停留在优化器这块,毕竟这块是目前MySQL必须要克服的最大问题,好在MySQL团队已经在重构优化器代码,相信更好的优化器将会在下一个版本中全面爆发。而一大堆文档数据库们已经哭晕在厕所了吧。
8. mongodb和mysql5.7的json哪个更好,优缺点比较
与关系型数据库相比,MongoDB的优点:
①弱一致性(最终一致),更能保证用户的访问速度:
举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精确值。这在某些情况下,例 如通过ATM查看账户信息的时候很重要,但对于Wordnik来说,数据是不断更新和增长的,这种“精确”的保证几乎没有任何意义,反而会产生很大的延 迟。他们需要的是一个“大约”的数字以及更快的处理速度。
但某些情况下MongoDB会锁住数据库。如果此时正有数百个请求,则它们会堆积起来,造成许多问题。我们使用了下面的优化方式来避免锁定:
每次更新前,我们会先查询记录。查询操作会将对象放入内存,于是更新则会尽可能的迅速。在主/从部署方案中,从节点可以使用“-pretouch”参数运行,这也可以得到相同的效果。
使用多个mongod进程。我们根据访问模式将数据库拆分成多个进程。
②文档结构的存储方式,能够更便捷的获取数据。
对于一个层级式的数据结构来说,如果要将这样的数据使用扁平式的,表状的结构来保存数据,这无论是在查询还是获取数据时都十分困难。
举例1:
就拿一个“字典项”来说,虽然并不十分复杂,但还是会关系到“定义”、“词性”、“发音”或是“引用”等内容。大部分工程师会将这种模型使用关系型数据库 中的主键和外键表现出来,但把它看作一个“文档”而不是“一系列有关系的表”岂不更好?使用 “dictionary.definition.partOfSpeech='noun'”来查询也比表之间一系列复杂(往往代价也很高)的连接查询方便 且快速。
举例2:在一个关系型数据库中,一篇博客(包含文章内容、评论、评论的投票)会被打散在多张数据表中。在MongoDB中,能用一个文档来表示一篇博客, 评论与投票作为文档数组,放在正文主文档中。这样数据更易于管理,消除了传统关系型数据库中影响性能和水平扩展性的“JOIN”操作。
CODE↓
> db.blogposts.save({ title : "My First Post", author: {name : "Jane", id :1},
comments : [{ by: "Abe", text: "First" },
{ by : "Ada", text : "Good post" }]
})
> db.blogposts.find( { "author.name" : "Jane" } )
> db.blogposts.findOne({ title : "My First Post", "author.name": "Jane",
comments : [{ by: "Abe", text: "First" },
{ by : "Ada", text : "Good post" } ]
})
> db.blogposts.find( { "comments.by" : "Ada" } )
> db.blogposts.ensureIndex( { "comments.by" : 1 } );
举例③:
MongoDB是一个面向文档的数据库,目前由10gen开发并维护,它的功能丰富,齐全,完全可以替代MySQL。在使用MongoDB做产品原型的过程中,我们总结了MonogDB的一些亮点:
使用JSON风格语法,易于掌握和理解:MongoDB使用JSON的变种BSON作为内部存储的格式和语法。针对MongoDB的操作都使用JSON风格语法,客户端提交或接收的数据都使用JSON形式来展现。相对于SQL来说,更加直观,容易理解和掌握。
Schema-less,支持嵌入子文档:MongoDB是一个Schema-free的文档数据库。一个数据库可以有多个Collection,每 个Collection是Documents的集合。Collection和Document和传统数据库的Table和Row并不对等。无需事先定义 Collection,随时可以创建。
Collection中可以包含具有不同schema的文档记录。 这意味着,你上一条记录中的文档有3个属性,而下一条记录的文档可以有10个属 性,属性的类型既可以是基本的数据类型(如数字、字符串、日期等),也可以是数组或者散列,甚至还可以是一个子文档(embed document)。这 样,可以实现逆规范化(denormalizing)的数据模型,提高查询的速度。
③内置GridFS,支持大容量的存储。
GridFS是一个出色的分布式文件系统,可以支持海量的数据存储。
内置了GridFS了MongoDB,能够满足对大数据集的快速范围查询。
④内置Sharding。
提供基于Range的Auto Sharding机制:一个collection可按照记录的范围,分成若干个段,切分到不同的Shard上。
Shards可以和复制结合,配合Replica sets能够实现Sharding+fail-over,不同的Shard之间可以负载均衡。查询是对 客户端是透明的。客户端执行查询,统计,MapRece等操作,这些会被MongoDB自动路由到后端的数据节点。这让我们关注于自己的业务,适当的 时候可以无痛的升级。MongoDB的Sharding设计能力最大可支持约20 petabytes,足以支撑一般应用。
这可以保证MongoDB运行在便宜的PC服务器集群上。PC集群扩充起来非常方便并且成本很低,避免了“sharding”操作的复杂性和成本。
⑤第三方支持丰富。(这是与其他的NoSQL相比,MongoDB也具有的优势)
现在网络上的很多NoSQL开源数据库完全属于社区型的,没有官方支持,给使用者带来了很大的风险。
而开源文档数据库MongoDB背后有商业公司10gen为其提供供商业培训和支持。
而且MongoDB社区非常活跃,很多开发框架都迅速提供了对MongDB的支持。不少知名大公司和网站也在生产环境中使用MongoDB,越来越多的创新型企业转而使用MongoDB作为和Django,RoR来搭配的技术方案。
⑥性能优越:
在使用场合下,千万级别的文档对象,近10G的数据,对有索引的ID的查询不会比mysql慢,而对非索引字段的查询,则是全面胜出。 mysql实际无法胜任大数据量下任意字段的查询,而mongodb的查询性能实在让我惊讶。写入性能同样很令人满意,同样写入百万级别的数 据,mongodb比我以前试用过的couchdb要快得多,基本10分钟以下可以解决。补上一句,观察过程中mongodb都远算不上是CPU杀手。
与关系型数据库相比,MongoDB的缺点:
①mongodb不支持事务操作。
所以事务要求严格的系统(如果银行系统)肯定不能用它。(这点和优点①是对应的)
②mongodb占用空间过大。
关于其原因,在官方的FAQ中,提到有如下几个方面:
1、空间的预分配:为避免形成过多的硬盘碎片,mongodb每次空间不足时都会申请生成一大块的硬盘空间,而且申请的量从64M、128M、256M那 样的指数递增,直到2G为单个文件的最大体积。随着数据量的增加,你可以在其数据目录里看到这些整块生成容量不断递增的文件。
2、字段名所占用的空间:为了保持每个记录内的结构信息用于查询,mongodb需要把每个字段的key-value都以BSON的形式存储,如果 value域相对于key域并不大,比如存放数值型的数据,则数据的overhead是最大的。一种减少空间占用的方法是把字段名尽量取短一些,这样占用 空间就小了,但这就要求在易读性与空间占用上作为权衡了。我曾建议作者把字段名作个index,每个字段名用一个字节表示,这样就不用担心字段名取多长 了。但作者的担忧也不无道理,这种索引方式需要每次查询得到结果后把索引值跟原值作一个替换,再发送到客户端,这个替换也是挺耗费时间的。现在的实现算是 拿空间来换取时间吧。
3、删除记录不释放空间:这很容易理解,为避免记录删除后的数据的大规模挪动,原记录空间不删除,只标记“已删除”即可,以后还可以重复利用。