MySql:在DB中附加到当前值的最快方法

时间:2014-08-11 11:55:05

标签: php mysql database

我有一张包含32,000个条目的表格。

每个条目都有一个JSON blob:

{
    "property1": "someValue",
    "property2": "AnotherValue"
}

我现在需要为每个参赛者追加另一个属性到这个blob,以便我们拥有:

{
    "property1": "someValue",
    "property2": "AnotherValue",
    "property3": "YetAnotherValue"
}

由于someValueAnotherValue对于不同的条目会有所不同,因此我不能仅使用新记录替换旧记录。相反(我猜)我应该解析JSON,添加property3并将其返回到DB,以获取32,000条记录中的每一条。

实现这一目标的最佳方法是什么?我有一个MySql数据库,我通过PhpMyAdmin进行交互。

我尝试编写一个PHP脚本,它基本上会选择并遍历每一行,解析并附加到我的JSON blob并为每条记录重新启动它。然而,当我在浏览器中运行它之后,它只会超时我,因为它需要很长时间才能执行(我怀疑它是拉动blob并将其上传回每条记录之间的等待时间)。

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:1)

我会质疑是否需要直接将JSON保存到MySQL数据库中。我们假设您的带有JSON blob的表名为my_table,并且它有一个id字段。我要创建另一个表格,例如my_json_properties。在那里,我创建了三列:my_table_idproperty_nameproperty_value。然后只使用JSON属性填充该表,添加新属性是微不足道的。还记得删除blob列,当然还要更新数据访问对象。

注意:使用InnoDB存储引擎,以便将my_json_properties.my_table_id转换为引用my_table.id的外键。 MySQL还会自动使用外键列创建索引,因此当您只知道原始表中的id时,查询属性非常有效。

答案 1 :(得分:1)

如果json是常规的,你可以使用UPDATE语句将这个新属性添加到你的json blob,即在最后一个属性之后没有空白,并且}在下一行中有一个固定的位置。在你的例子的基础上,并假设\ n作为行尾你可以这样做:

UPDATE example
SET json = REPLACE(
               json, 
               '"\n}', 
               '",\n    "property3": "some value"\n}');

演示(http://sqlfiddle.com/#!2/db972/1

Marcus Adams建议采用更有力的方法:

UPDATE example
SET json = 
    CONCAT(
        TRIM(
            TRAILING FROM TRIM(
                TRAILING '\n' FROM TRIM(
                    TRAILING FROM SUBSTRING_INDEX(json, '}', 1)
                )
            )
        ),
        ',\n    "property3": "some value"\n}'
    );

这将独立于}之前的最后一个属性和前导空格之后的尾随空格,但它仍然依赖于\n作为行尾。

注意:

这些语句通常比使用脚本逐行更新快得多。

答案 2 :(得分:0)

这取决于用例。 如果这是一次性任务,那么从shell而不是从浏览器运行脚本会更好,以避免Web服务器和浏览器超时。

php -f my_update_script.php

如果由于某种原因无法从shell运行脚本,您可以尝试欺骗浏览器和Web服务器,如下所示:

set_time_limit(3600*2); // two hours should be enougth?
// turn off output buffering
while (ob_end_flush());
ob_implicit_flush();

// Your mysql fetch..update loop here
// begin loop
echo 'Something useful every iteration to let them know your script is alive :)';
// end loop

但是,如果在Web服务器前面存在缓存反向代理,则此方法可能会失败。

MariaDb本身支持JSON格式(从版本10开始),您可以考虑切换到MariaDb。