場景描述
原始文本格式:
pid1 kid1
pid3 kid1
pid1 kid2
pid1 kid3
pid2 kid3
pid2 kid4
需要統(tǒng)計(jì)的結(jié)果:每條pid可以跟哪幾個(gè)kid關(guān)聯(lián),最終結(jié)果格式:
pid1 kid1,kid2,kid3
pid2 kid3,kid4
pid3 kid1
** 原始文本大概有2億多行 **
處理思路
- 將文本按第一列排序纸俭,排序后效果:
pid1 kid1
pid1 kid2
pid1 kid3
pid2 kid3
pid2 kid4
pid3 kid3 - 將第一列相同的行合并,效果:
pid1 kid1,kid2,kid3
pid2 kid3,kid4
pid3 kid1
具體解決代碼
# sort -k 1 -n src.txt > sort1.txt
# cat sort1.txt | php -B '
$pidtmp = 0;
$kidtmp = array();
' -R '
list($pid, $kid) = explode("\t", $argn);
if($pid != $pidtmp) {
echo "\n".$pidtmp."\t".implode(",", array_keys($kidtmp));
$pidtmp = $pid;
$kidtmp = array();
}
$kidtmp[$kid] = 1;
'
** 以上兩條命令可實(shí)現(xiàn)需求南窗,共耗時(shí)半個(gè)小時(shí)左右 **
其它說明
本需求中存在一個(gè)原始文檔揍很,這個(gè)文檔是通過其它程序生成的。那么存在一個(gè)疑問万伤,為什么其它程序生成文檔時(shí)窒悔,不直接生成所需要的格式(即以上示例的最終格式),而是生成一個(gè)中間格式的文檔壕翩。
其實(shí)在設(shè)計(jì)之前的程序時(shí)蛉迹,確實(shí)就是期望直接輸出以上的最終文檔傅寡,但出現(xiàn)一個(gè)問題就是這個(gè)最終文檔要怎么存儲(chǔ)放妈,存mysql還是nosql北救。嘗試過mysql,一共有2億行結(jié)果芜抒,每一行就需要讀珍策、寫一次mysql,時(shí)間成本太高宅倒。然后也嘗試了redis攘宙,使用列表存儲(chǔ),每一行原數(shù)據(jù)拐迁,只需要寫一次redis的列表蹭劈,可以減少一次讀,然而時(shí)間還是太長线召,所以才將中間結(jié)果輸入到文本铺韧。再使用以上提到的2條命令將結(jié)果轉(zhuǎn)換為最終格式,時(shí)間成本大降低缓淹。
如果有另外一個(gè)程序需要根據(jù)pid來搜索以上生成的最終文檔哈打,可以借鑒另一篇文章 ,入口