在MySQL 5.7中,新的数据类型用于在JSON表中存储JSON数据。
添加。 显然,这将是MySQL的巨大变化。 他们列出了一些好处
Document Validation - Only valid JSON documents can be stored in a
JSON column, so you get automatic validation of your data.
Efficient Access - More importantly, when you store a JSON document in a JSON column, it is not stored as a plain text value. Instead, it is stored
in an optimized binary format that allows for quicker access to object
members and array elements.
Performance - Improve your query
performance by creating indexes on values within the JSON columns.
This can be achieved with"functional indexes" on virtual columns.
Convenience - The additional inline syntax for JSON columns makes it
very natural to integrate Document queries within your SQL. For
example (features.feature is a JSON column): SELECT feature->"$.properties.STREET" AS property_street FROM features WHERE id = 121254;
哇 ! 它们包括一些很棒的功能。 现在,更容易操作数据。 现在可以在列中存储更复杂的数据。
因此,MySQL现在具有NoSQL的味道。
现在我可以想象对JSON数据的查询类似
SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN
(
SELECT JSON_EXTRACT(data,"$.inverted")
FROM t1 | {"series": 3,"inverted": 8}
WHERE JSON_EXTRACT(data,"$.inverted")<4 );
那我可以在几个json列中存储巨大的小关系吗? 好吗? 它破坏规范化了吗? 如果可能的话,我想它会像MySQL列中的NoSQL一样。 我真的很想了解更多有关此功能的信息。 MySQL JSON数据类型的优缺点。
哦,请不要说我想你在说什么。在这里,阅读。您的又一个坏主意。
@德鲁你给了一个很大的答案。但这不是我的问题。我只想知道,如果我们为json数据编写查询,那么我们可能会跳过sql规则。因为我们不需要很多桌子
您说Now it is possible to store more complex data in column。小心
是的,我认为仅适用于json表。他们创建了许多功能和功能来从json检索数据
我觉得这很好。小心将mysql转换为文档数据库。我们知道有什么更好的方法:)
Json数据类型支持索引,并且具有智能大小:64K和4G。那么,如果我想存储2000个数据并添加5个嵌套标签而不是5个具有关系的表,会出现什么问题呢?
我想时间会证明一切。如果并且当我们发现它确实可以是nosql乱码而无模式(以前??为模式)的窥视效果时,它的性能是很糟糕的。我们会看到。将mysql转换为hbase :)
"我真的很想了解更多有关此功能的信息。"和" MySQL JSON数据类型的优缺点"。不是问题,如果措辞过于笼统,请改写。"因此,我从没想到MySQL中有复杂的架构结构和外键。我仅使用几个表来存储复杂的关系。"是自相矛盾的,因为JSON不是关系和FK。对"这是一件好事"的解释只是对关系模型的介绍,因此,它又太宽泛了。通过一些示例工作,列出自己的优缺点和参考文献,并询问出错的地方。
@NeilLunn标记nosql在这里似乎很合理。即使该问题最具体地涉及MySQL中的原始类型与JSON类型,甚至该问题本身也承认核心问题是关系与非关系表示,这是用SQL vs NoSQL来表征的。正确答案必须解决关系模型相对于其他模型的特殊属性。
@philipxy我要问的是NoSQL到底"哪个"?基本上,比较是从苹果到橙子再到蓝莓等。由于没有"标准",所以实际上没有比较的基点。如果问题是比较的"特定"之处,则应使用"特定"技术进行标记。没有?对我而言,NoSQL是与"编程语言"一样有用的分类。它只是意味着太多的事情,或者更多的是"什么都不是"。因此,我看不到增加的价值。也没有人特别"监视"" nosql"的新帖子。问题是关于MYSQL JSON。
MySQL 5.7中的以下内容对JSON听起来很性感,对我来说很不错:
Using the JSON Data Type in MySQL comes with two advantages over
storing JSON strings in a text field:
Data validation. JSON documents will be automatically validated and
invalid documents will produce an error. Improved internal storage
format. The JSON data is converted to a format that allows quick read
access to the data in a structured format. The server is able to
lookup subobjects or nested values by key or index, allowing added
flexibility and performance.
...
Specialised flavours of NoSQL stores
(Document DBs, Key-value stores and Graph DBs) are probably better
options for their specific use cases, but the addition of this
datatype might allow you to reduce complexity of your technology
stack. The price is coupling to MySQL (or compatible) databases. But
that is a non-issue for many users.
请注意有关文档验证的语言,因为它是一个重要因素。我猜想需要对这两种方法进行一系列测试。那两个是:
具有JSON数据类型的MySQL
MySQL没有
到目前为止,从我所看到的内容来看,关于mysql / json /性能的话题,网络上只有很少的幻灯片分享。
也许您的帖子可以成为它的中心。也许性能是经过深思熟虑的(不确定),而您很高兴不创建一堆表。
一弊Mysql内存表不支持JSON数据类型,例如数据类型TEXT和BLOB。这意味着如果需要一个临时表,它将创建一个基于磁盘的表而不是内存。此处概述了一些使用临时表的情况:dev.mysql.com/doc/refman/5.7/en/internal-temporary-tables.html
@raizmedia您能否详细说明为什么基于磁盘的表与内存(我猜是基于表)有问题?
@lapin可能是由于速度限制。
@LittleHelper如果使用PCI 4x 40 Gb / s M.2插槽并插入支持的40 Gb / s驱动器,则可以避免使用。这与记忆一样快。您可以将特殊格式应用于用于格式化内存的驱动器。
SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN ...
在这样的表达式或函数中使用列会浪费使用索引来帮助优化查询的任何机会。上面显示的查询被强制执行表扫描。
关于"有效访问"的说法具有误导性。这意味着在查询检查了带有JSON文档的行之后,它可以提取一个字段,而不必解析JSON语法的文本。但是仍然需要进行表格扫描来搜索行。换句话说,查询必须检查每一行。
以此类推,如果我在电话簿中搜索名字为"比尔"的人,即使我的名字被突出显示以使其更快地发现它们,我仍然必须阅读电话簿中的每一页。
MySQL 5.7允许您在表中定义虚拟列,然后在虚拟列上创建索引。
ALTER TABLE t1
ADD COLUMN series AS (JSON_EXTRACT(data, '$.series')),
ADD INDEX (series);
然后,如果您查询虚拟列,它可以使用索引并避免进行表扫描。
或者,即使您查询虚拟列所基于的确切表达式(如在原始查询中一样),它也可以使用索引。
很好,但是有点遗漏了使用JSON的意义。使用JSON的吸引力在于,它允许您添加新属性,而无需执行ALTER TABLE。但是事实证明,如果要在索引的帮助下搜索JSON字段,则无论如何都必须定义一个额外的(虚拟)列。
但是,您不必为JSON文档中的每个字段定义虚拟列和索引,而只需定义要搜索或排序的列和索引。 JSON中可能还有其他属性,您只需要将它们提取到选择列表中,如下所示:
SELECT JSON_EXTRACT(data, '$.series') AS series FROM t1
WHERE
我通常会说这是在MySQL中使用JSON的最佳方法。仅在选择列表中。
当您在其他子句(JOIN,WHERE,GROUP BY,HAVING,ORDER BY)中引用列时,使用常规列而不是JSON文档中的字段会更有效。
我在2018年4月的Percona Live会议上发表了名为"如何在MySQL错误中使用JSON的JSON"的演讲。我将在秋季在Oracle Code One上更新并重复该演讲。
JSON还有其他问题。例如,在我的测试中,JSON文档所需的存储空间是存储相同数据的常规列的2-3倍。
MySQL正在积极地推广其新的JSON功能,主要目的是劝说人们不要迁移到MongoDB。但是像MongoDB这样的面向文档的数据存储从根本上讲是一种非关系式的数据组织方式。它不同于关系型。我并不是说一个比另一个更好,这只是一种不同的技术,适用于不同类型的查询。
当JSON使查询更高效时,您应该选择使用JSON。
不要仅仅因为一项新技术或为了时尚而选择一项技术。
值得跟随幻灯片的链接
好的一点是,这两种技术本身都具有优势,我们可以决定哪种技术可以满足我们的需求,以及在安全性和性能方面给我们带来更多优势。
问题的症结在于,仍然需要ALTER TABLE来利用JSON中每个新键的生成列上的索引。很高兴看到有人指出。
仅当您需要添加虚拟列和/或索引时。如果将JSON数据视为"黑匣子",并且不尝试对JSON中的子字段进行搜索或排序的任何查询,那么您就不需要这样做。因此,我建议避免在JOIN,WHERE或其他子句中引用JSON。只需获取选择列表中的JSON列即可。
我最近遇到了这个问题,并总结了以下经验:
1,没有办法解决所有问题。
2,您应该正确使用JSON。
一种情况:
我有一个名为:CustomField的表,它必须有两列:name,fields。
name是本地化的字符串,其内容应类似于:
{
"en":"this is English name",
"zh":"this is Chinese name"
...(other languages)
}
并且fields应该是这样的:
[
{
"filed1":"value",
"filed2":"value"
...
},
{
"filed1":"value",
"filed2":"value"
...
}
...
]
如您所见,name和fields都可以另存为JSON,并且可以使用!
但是,如果我经常使用name搜索该表,该怎么办?使用JSON_CONTAINS,JSON_EXTRACT ...?显然,将其另存为JSON并不是一个好主意,我们应该将其保存到一个独立的表:CustomFieldName中。
从上述情况来看,我认为您应该牢记以下想法:
为什么MYSQL支持JSON?
为什么要使用JSON?您的业??务逻辑只需要这个吗?还是还有别的?
永远不要偷懒
谢谢
您可能对使用VIRTUAL列感兴趣。 percona.com/blog/2016/03/07/
根据我的经验,至少在MySql 5.7中,JSON实现由于性能不佳而不太有用。
好吧,对于读取数据和验证来说还不错。但是,使用MySql进行JSON修改的速度比使用Python或PHP慢10到20倍。
让我们想象一下非常简单的JSON:
{"name":"value" }
假设我们必须将其转换为类似的内容:
{"name":"value","newName":"value" }
您可以使用Python或PHP创建简单的脚本,该脚本将选择所有行并逐一更新它们。您不必为此进行一项大事务,因此其他应用程序可以并行使用该表。当然,如果需要,您也可以进行一个巨大的事务,因此可以保证MySql将执行"全部或不执行",但是其他应用程序很可能在事务执行期间无法使用数据库。
我有4000万行表,Python脚本会在3-4小时内更新它。
现在我们有了MySql JSON,因此我们不再需要Python或PHP,我们可以执行以下操作:
UPDATE `JsonTable` SET `JsonColumn` = JSON_SET(`JsonColumn`,"newName", JSON_EXTRACT(`JsonColumn`,"name"))
它看起来简单而出色。但是,它的速度比Python版本慢10到20倍,并且它是单个事务,因此其他应用程序无法并行修改表数据。
因此,如果我们只想在4000万行表中复制JSON键,则在30-40个小时内根本不需要使用表。它没有感觉。
关于读取数据,根据我的经验,通过WHERE中的JSON_EXTRACT直接访问JSON字段也非常慢(比未索引列上的TEXT和LIKE慢得多)。虚拟生成的列的执行速度要快得多,但是,如果我们事先知道我们的数据结构,则不需要JSON,而可以使用传统列。当我们在真正有用的地方使用JSON时,i。即当数据结构未知或经常更改(例如,自定义插件设置)时,定期为任何可能的新列创建虚拟列似乎不是一个好主意。
Python和PHP像使JSON验证一样具有吸引力,因此是否需要在MySql端进行JSON验证是一个问题。为什么不同时验证XML,Microsoft Office文档或检查拼写? ;)