mysql里面有個字段用于存放用戶的數(shù)據(jù),每個用戶都會增加一個json數(shù)組,例子:100個用戶,就有100個json數(shù)組,
[{"uid":1646,"nickName":"微信大sss號"},{"uid":1646,"nickName":"微信大sss號"},{"uid":1646,"nickName":"微信大sss號"},................]
方案1:每個用戶新增數(shù)據(jù)都是取之前的數(shù)據(jù),然后php往頭部插入,再轉(zhuǎn)json全部更新到mysql。
【弊端】實際測試我的業(yè)務(wù),當達到140多人時,text類型已經(jīng)存不下了,然后改成longtext,當達到500人時(500個json數(shù)組),更新速度越來越慢,I/O應(yīng)該很高(讀寫)。
方案2:采用concat_ws方案,每次在mysql前部插入新的json字符串,不用全部讀取和全部更新,只是往前插入一個json串,實際測試500人,更新速度快了一點點
//本次用戶數(shù)組json中文不轉(zhuǎn)碼
$userInfoJsonStr = json_encode($userInfoJson, JSON_UNESCAPED_UNICODE);
//單獨用戶uid
$uid = $userData['id'];
//數(shù)據(jù)庫前綴
$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數(shù)組(只關(guān)注這個字段)
大家覺得方案2有問題嗎?能將磁盤I/O降到最???每次只更新一小段。
在不采取分表的情況下,大家還有更好的方案嗎?
這是設(shè)計有問題,改數(shù)據(jù)結(jié)構(gòu),用另一張表記錄user_data 數(shù)據(jù),這張表只記錄uid集合就行,獲取數(shù)據(jù)就查uid集合然后whereIn把另一張表user_data數(shù)據(jù)找出來合并.