超大数组update数据库,采用什么方案比较好呢?

问题描述

mysql里面有个字段用于存放用户的数据,每个用户都会增加一个json数组,例子:100个用户,就有100个json数组,

[{"uid":1646,"nickName":"微信大sss号"},{"uid":1646,"nickName":"微信大sss号"},{"uid":1646,"nickName":"微信大sss号"},................]

方案1:每个用户新增数据都是取之前的数据,然后php往头部插入,再转json全部更新到mysql。
【弊端】实际测试我的业务,当达到140多人时,text类型已经存不下了,然后改成longtext,当达到500人时(500个json数组),更新速度越来越慢,I/O应该很高(读写)。

方案2:采用concat_ws方案,每次在mysql前部插入新的json字符串,不用全部读取和全部更新,只是往前插入一个json串,实际测试500人,更新速度快了一点点

 //本次用户数组json中文不转码
$userInfoJsonStr = json_encode($userInfoJson, JSON_UNESCAPED_UNICODE);
//单独用户uid
$uid = $userData['id'];
//数据库前缀
$prefix = Db::getConfig('prefix');
//更新语句
$updateSQL = "UPDATE {$prefix}_options
        SET num       = num - 1,
            user_num  = user_num + 1,
            user_data =
        CASE
            WHEN
                (user_data IS NULL OR user_data = '')
            THEN
                '[{$userInfoJsonStr}]'
            ELSE
                concat_ws(',','[{$userInfoJsonStr}',substring(user_data,2))
            END,
                uid_data =
        CASE
            WHEN
                (uid_data IS NULL OR uid_data = '')
            THEN
                {$uid}
            ELSE
                concat_ws(',',{$uid}, uid_data)
            END
        WHERE
            id = " . $edit_id;

为此你搜索到了哪些方案及不适用的原因

user_data存放超大json数组(只关注这个字段)
截图
大家觉得方案2有问题吗?能将磁盘I/O降到最小?每次只更新一小段。
在不采取分表的情况下,大家还有更好的方案吗?

1114 3 0
3个回答

PHP甩JAVA一条街

实际方案2跑起来也不快,更新1.3s,方案1是1.8s,咋回事呢?字段里面的数据很多的,500人,大概有500-800K

2548a

这是设计有问题,改数据结构,用另一张表记录user_data 数据,这张表只记录uid集合就行,获取数据就查uid集合然后whereIn把另一张表user_data数据找出来合并.

  • PHP甩JAVA一条街 2023-03-13

    业务能支撑,改起来太麻烦,只能在不大改的情况下,优化现有的

小W

试试blob类型呢

年代过于久远,无法发表回答
×
🔝