我有这个想法,我使用PHP的json_encode
将多/非多维数组制作成JSON字符串,并将数据存储到我的SQL数据库中。
例如,我有一个名为'users'的表。表'用户'有3个字段:id,name,data
使用php,我想获取用户John的数据:SELECT data FROM users WHERE name='john'
现在,“数据”字段的值/文字将如下所示:{"gender":"male","birthday":"8-Jan-1991","country":"UK","city":"London"}
我将使用PHP的json_decode
解码'data'字段,然后我将使用我自己制作的PHP函数将stdClass对象转换为数组。然后我可以在任何地方显示John的信息:$user['data']['country']
。
这使我免受榛子在国家,城市,生日等数据库上创建额外字段。但是它安全吗?使用此方法在MySQL上存储数据是否有任何缺点或问题。
答案 0 :(得分:11)
正确转义,你很好但我必须补充一点,这是XML比json更好的格式,因为它还允许你在查询中使用xml内部的数据< / p>
<?xml version="1.0" encoding="UTF-8" ?>
<user>
<gender>male</gender>
<birthday>8-Jan-1991</birthday>
<country>UK</country>
<city>London</city>
</user>
选择
SELECT ExtractValue(data, '//gender') AS gender FROM users WHERE name='john' AND EXTRACTVALUE(data, '//country') != 'UK';
http://dev.mysql.com/doc/refman/5.1/en/xml-functions.html#function_extractvalue
答案 1 :(得分:5)
但这样安全吗?
只要您正确地转义输入,使用适当的库来访问数据库(或者至少使用mysql_real_escape_string)然后是的,这是安全的。或者至少,在黑客攻击数据库方面,存储其他任何东西的风险都不大。
使用此方法在MySQL上存储数据是否有任何缺点或问题
是的,这里有几个:
查询“数据”列中的任何内容都是不可能的,或者至少要困难得多。假设您想要所有居住在伦敦的用户。您必须获取整个数据库中的所有“数据”列并在PHP中进行搜索。
查询时,也无法按“数据”列中的任何内容进行排序。它必须在PHP中完成。
您必须注意确保存储的数据以正确的格式存储。无论如何你应该这样做,但它确实消除了对存储“坏”数据的额外保护。
看起来你已经基本上将MySQL变成了NoSQL数据库。虽然我的经验有限,但能够在一定程度上对存储的文档/ JSON数据中的数据进行索引+排序。作为关系数据库,MySQL不能:它只能对定义的列进行排序+索引。你正在获得最糟糕的MySQL,缩放的难度,而不是使用它的任何优势,即能够运行复杂的查询。
如果您确定自己永远不需要运行此类查询,那么如果您将内容存储为JSON,可能会更容易转移到NoSQL。
编辑:如果您担心使用空列空格,您可以随时添加表格。说一个用户地址表。如果您每个用户可能需要多个地址,这实际上是一种非常友好的方式。
答案 2 :(得分:3)
尝试添加新列。 JSON解码非常昂贵。但是,如果您的PHP应用程序无法承受停机时间,或者由于某种原因您无法添加更多列,则可以执行以下操作:
CLOB
中。BLOB
字段中。答案 3 :(得分:2)
如果我是你,我只需为数据集添加新列。
在MySQL字段中使用JSON并不是坏事。它给我带来了很多悲伤。但它确实引入了大量开销,并限制了您可以从数据库引擎中使用的功能。不断操作SQL模式不是最好的方法,但是当你不必要时,它们也不能解码JSON对象。
如果数据架构是相当静态的,例如您存储用户性别,生日等的示例,则最好使用列。然后,您可以使用SQL直接快速轻松地操作数据...排序,过滤,创建索引以便更快地查找等等。由于数据模式是相当静态的,因此除了少数几个之外,您不会从JSON获得任何东西。您创建列的时间分钟。最后,在应用程序的整个生命周期中,您将在机器周期中浪费更多的时间。
我在MySQL字段中使用JSON的地方是数据模式非常流畅的地方。作为测试工程师,这几乎是常态。例如,在我当前的一个项目中,目标指标列表(存储在MySQL中)会定期更改,具体取决于要解决的问题或正在调整的性能特征。这是开发工程师要求新指标的常规活动,他们当然希望这一切能够得到整齐的显示,并且可以快速进行更改。因此,我不是每天都使用SQL模式,而是将静态模式(测试类型,日期,产品版本等)存储为列,但将流畅的测试结果数据存储为JSON对象。这意味着我仍然可以使用基于测试类型,版本,日期等的SQL语句来查询数据,但在集成新指标时永远不必触及表模式。为了显示实际的测试数据,我只是迭代结果并将JSON对象解码为数组并从那里开始。随着这个项目的扩展,我最终将实现memcached来缓存所有内容。
这也有将100多个测试指标捆绑到一个文本blob中的副作用,整个我zlib压缩,使其大约为原始大小的10%。这可以节省相当多的数据存储空间,因为我们已经有7个行数。