【发布时间】:2014-09-29 00:20:53
【问题描述】:
问题来了:
我们有一个存储 JSON 字符串的 MySQL 数据库。到现在为止这都没问题,但突然我们的客户要求我们对这些对象进行搜索/订购/其他操作。由于项目处于相当晚的状态,去Mongo不是团队领导想要做出的选择,所以我想问有没有一种快速的方法来使用这些JSON字符串?
【问题讨论】:
标签: mysql json database-design architecture
问题来了:
我们有一个存储 JSON 字符串的 MySQL 数据库。到现在为止这都没问题,但突然我们的客户要求我们对这些对象进行搜索/订购/其他操作。由于项目处于相当晚的状态,去Mongo不是团队领导想要做出的选择,所以我想问有没有一种快速的方法来使用这些JSON字符串?
【问题讨论】:
标签: mysql json database-design architecture
JSON 作为意图
在 MySQL 中无法使用 JSON。一些 DBMS 可能支持 JSON,但这是不可能的,此外,任何类型的“支持”只是关于执行一些特定于 JSON 的操作,而不是关于对你的架构进行建模(这两件事完全不同) ,完全意义上,MySQL 的模型概念(即关系)与 JSON 不同的是:作为关系型 DBMS,它遵循relational data model,而 JSON 是完全不同的格式。您会将其存储为纯字符串值,因此,如果不使用字符串函数,则无法以其他方式对其进行任何操作。因此,即使使用 JSON,您也不会在关系模型中执行此操作,因此无法维护关系特性,例如引用完整性。
解决方案
您有多种选择:
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';
之后,您就可以尝试它们了。
【讨论】:
between separate 实体吗? 不。你真的可以保持 JSON 数据的引用完整性吗? 不。我可以继续,但概念显示:如果您可以使用 JSON 结构,这并不意味着它们与模型本身对齐。但感谢 dv 解释。
如果您不使用任何 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" }';
【讨论】:
MySQL5.7 现在支持 JSON 数据类型 - https://dev.mysql.com/doc/refman/5.7/en/json.html
似乎他们不想被排除在 NoSQL 对话之外。
mysql> SELECT JSON_ARRAY('a', 1, NOW());
【讨论】: