【问题标题】:Is there any way to use json objects in SQL有没有办法在 SQL 中使用 json 对象
【发布时间】:2014-09-29 00:20:53
【问题描述】:

问题来了:

我们有一个存储 JSON 字符串的 MySQL 数据库。到现在为止这都没问题,但突然我们的客户要求我们对这些对象进行搜索/订购/其他操作。由于项目处于相当晚的状态,去Mongo不是团队领导想要做出的选择,所以我想问有没有一种快速的方法来使用这些JSON字符串?

【问题讨论】:

    标签: mysql json database-design architecture


    【解决方案1】:

    JSON 作为意图

    在 MySQL 中无法使用 JSON。一些 DBMS 可能支持 JSON,但这是不可能的,此外,任何类型的“支持”只是关于执行一些特定于 JSON 的操作,而不是关于对你的架构进行建模(这两件事完全不同) ,完全意义上,MySQL 的模型概念(即关系)与 JSON 不同的是:作为关系型 DBMS,它遵循relational data model,而 JSON 是完全不同的格式。您会将其存储为纯字符串值,因此,如果不使用字符串函数,则无法以其他方式对其进行任何操作。因此,即使使用 JSON,您也不会在关系模型中执行此操作,因此无法维护关系特性,例如引用完整性。

    解决方案

    您有多种选择:

    • 迁移到 Postgree SQL,因为它扩展了对 json 的支持,从 9.4 版开始它是 jsonb,而且速度更快。这可能是最好的选择,因为它是 RDBMS,因此迁移不会像真正面向文档的 DBMS 那样困难。
    • 或者现在就迁移到 Mongo(如果这是您的意图),以免为时已晚。考虑到 Mongo 与 RDBMS 完全不同,它是面向文档的。我想这对您的项目和客户来说都是最好的选择(您的任务就是解释这一点)
    • 更改整个架构,这样您就不会存储 JSON 对象,而是使用规范化(就关系 DB 而言)实体。这意味着 - 是的,对所有代码进行全面重构、更改所有关系等。在实际情况下,这只是理论上的选择,不会给你时间和金钱。
    • 为 MySQL 实现您自己的 JSON 库。难吗?取决于您将使用 JSON 做什么,但 JSON 是公共格式,因此您至少会知道该怎么做。您可以使用UDF 或在用户区(使用CREATE FUNCTION 语句)来执行此操作。当然,这需要特定的技能和时间。坏事:错误。即使您能够比重新构建架构或迁移到 Mongo 更快地创建这些功能,您也永远无法确定这些功能的质量。没有办法在本地测试该代码。但是,我可能会针对用户域函数的情况给出提示 - 如果您的 MySQL 是 5.6 或更高版本,您可以使用mysql-unit 来测试您存储的代码(好吧,我已经编写了这个工具,但是......它可能包含也有错误)

    “标准”函数

    最后,如果您运行的是 MySQL 5.7,那么pre-release JSON functions 可能会有一线希望 - 所以,您可以尝试使用当前存在的 alfa 版本的 JSON 功能对于 MySQL 5.7。但我不会(强烈)建议在实际项目中使用它,因为这些功能既没有经过充分测试也没有完成。但是,要安装这些功能,您需要下载相应的软件包,然后将它们插入您的服务器,例如:

    CREATE FUNCTION json_append       RETURNS string  SONAME 'libmy_json_udf.so';
    CREATE FUNCTION json_valid        RETURNS integer SONAME 'libmy_json_udf.so';
    CREATE FUNCTION json_extract      RETURNS string  SONAME 'libmy_json_udf.so';
    CREATE FUNCTION json_replace      RETURNS string  SONAME 'libmy_json_udf.so';
    CREATE FUNCTION json_remove       RETURNS string  SONAME 'libmy_json_udf.so';
    CREATE FUNCTION json_set          RETURNS string  SONAME 'libmy_json_udf.so';
    CREATE FUNCTION json_merge        RETURNS string  SONAME 'libmy_json_udf.so';
    CREATE FUNCTION json_search       RETURNS string  SONAME 'libmy_json_udf.so';
    CREATE FUNCTION json_contains_key RETURNS integer SONAME 'libmy_json_udf.so';
    

    之后,您就可以尝试它们了。

    【讨论】:

    • 好吧,我们可能会去 Mongo,但是你激发了我对这些预发布 JSON 函数的好奇心。我在哪里可以了解更多关于它们的信息?
    • 我提供了一个链接。它们处于开发阶段(甚至不是测试版) - 因此根据定义,它们无法正确记录。尝试在 MySQL Labs 中找到更多信息 - 老实说,我从未使用过这些功能。
    • 关系模型不禁止使用 JSON。事实上,值可以任意复杂。例如,请参阅 Chris Date 的书 数据库系统简介,第 7 版,第 114 页。PostgreSQL 支持 JSON
    • 它与关系数据库概念有什么关系?PostgreSQL 有库来处理 JSON 吗?当然,我并没有说所有 DBMS 都不支持 JSON(如您所见,即使对于 MySQL,也有或多或少相关的库)。但简单想想这种支持是什么。 你真的可以在 JSON 条目中创建关系 between separate 实体吗? 不。你真的可以保持 JSON 数据的引用完整性吗? 不。我可以继续,但概念显示:如果您可以使用 JSON 结构,这并不意味着它们与模型本身对齐。但感谢 dv 解释。
    • 关系模型支持任意复杂的数据类型。这意味着它支持 XML、视频、音频和 JSON 等。当然,您不能为 JSON 值中的字段设置外键引用,但这无关紧要,并且对关系模型的含义存在相当深刻的误解。您也不能为日期值中的字段设置外键引用。 OP 的问题中没有任何内容表明他甚至 trying 设置外键引用。
    【解决方案2】:

    如果您不使用任何 MySQL 特定功能,您可以相对轻松地切换到 PostgreSQL,并利用其 JSONB 数据类型。

    如果您查看official wiki page regarding its inclusion in PostgreSQL 9.4,您会发现有了它,您可以存储原始 JSON 并对其进行查询。例如,给定这个 JSON 结构(我用标准类型替换了 PostgreSQL 特定的列类型,JSONB 类型除外:

    table booksdata ( 
        title text not null,
        isbn text not null primary key,
        pubinfo jsonb not null 
    )
    

    然后您可以查询它以找到来自单个出版商的所有书籍的平均成本,如下所示:

    SELECT avg((pubinfo #>> '{"cost"}')::NUMERIC) 
    FROM booksdata
    WHERE pubinfo @> '{ "publisher" : "It Books" }';
    

    【讨论】:

      【解决方案3】:

      MySQL5.7 现在支持 JSON 数据类型 - https://dev.mysql.com/doc/refman/5.7/en/json.html

      似乎他们不想被排除在 NoSQL 对话之外。

      mysql> SELECT JSON_ARRAY('a', 1, NOW());
      

      【讨论】:

        猜你喜欢
        • 2019-08-07
        • 2021-02-04
        • 2021-09-05
        • 2020-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-16
        相关资源
        最近更新 更多