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降到最小?每次只更新一小段。
在不采取分表的情况下,大家还有更好的方案吗?
实际方案2跑起来也不快,更新1.3s,方案1是1.8s,咋回事呢?字段里面的数据很多的,500人,大概有500-800K
我这是测试极限业务,一半很少能到到这种情况
这是设计有问题,改数据结构,用另一张表记录user_data 数据,这张表只记录uid集合就行,获取数据就查uid集合然后whereIn把另一张表user_data数据找出来合并.
业务能支撑,改起来太麻烦,只能在不大改的情况下,优化现有的
试试blob类型呢
json 类型