週末寫了兩個腳本,用以統計詩詞中的高頻字,並抽取其中意象做爲飛花令的令字。這兩個腳本的地址以及所作以下javascript
redis.incr
計數,存入 redis
中redis
中的數據遷移到 postgres
中那爲何不直接存到 postgres
中,非要在 redis
中走一遭呢?java
incr
保證原子性 (postgres 須要設置事務和隔離級 RR/ 或者 select for update / 或者加一個分佈式鎖)如下是兩種方案的僞代碼對比:git
key
根據字、朝代、做者生成count
表明該 key
出現的次數// 使用 redis
redis.incr(key, 1)
// 使用 postgres
// 不只須要額外保證原子性,並且代碼也更復雜一些
const id = lock(key)
const cloud = models.cloud.findOne({ key })
if (cloud) {
cloud.increment('count', 1)
} else {
models.cloud.create({ key, count: 1 })
}
unlock(id)
複製代碼
雖然在我腳本中並無使用 postgres
,但我也把它拿出來分析一下github
當每來一個關鍵字時,所要執行的 SQL
以下redis
begin;
select key, count from cloud where key = $key;
-- 若是存在
-- Question 2: 此時的 count 若是在 R/W 之間恰好改變呢
update cloud set count = $count + 1 where key = $key;
-- 若是不存在
-- Question 1: 在判斷爲不存在的時候,此時確實不存在嗎?若是剛好在 R/W 之間插入一條數據呢
insert into cloud (key, value) value ($key, 1);
commit;
複製代碼
使用 select for update
加一個悲觀鎖解決問題sql
begin;
-- 鎖住該行,知道 commit/rollback
select key, count from cloud where key = $key for update;
update cloud set count = $count + 1 where key = $key;
insert into cloud (key, value) value ($key, 1);
commit;
複製代碼
不必定,特別是在這種求 TOP 的狀況下,他只須要得出相對排序便可。也就是說,你即便不對 postgres
作一些原子性保證的處理,最後獲得的數據也會差不了多少。分佈式
select array_to_string(array(select char from char_cloud GROUP BY char ORDER BY sum(count) desc limit 500), '')
複製代碼
寫一個 SQL 查出來數據以下post
不人一風山無有天雲日來何花春中年生月如時自水上爲相心此長我清江秋知君未雨歸白得子千高三今空見青行裏去明老下萬是夜事寒誰玉在家可酒南客與聲處東飛金已落流多門前新欲西煙成書道深更海古香出看詩開地重石做黃頭光夢之能朝草盡世入幾色遊十同林城遠從還當情氣間回樹名思意亦馬紅雪大愁平猶百難將然塵龍路似公過獨陽舊身小到滿衣歌莫華復好仙望應聞向分方後樓非起五笑問故安外歲文別真竹神醉須言初孤發陰留以坐邊臺幽霜松葉北吾豈影兩半溪少所綠四語雙傳又晚先其正翠物湖隨碧王野餘共九柳波枝驚吹露曾懷浮國河斷輕樂鳥吟微暮芳堂舟殘對眼離畫手經蒼關逢尋只久若尚數兮兒卻居梅照憐聽才木二興曲窗臨忽堪魚漢星峯泉終官宮近疏且足者涼蕭於閒喜絕鄉鳴車太苦士依庭紫亭夕首鶴燕使往轉連登丹常憶期動園遙靈節晴勝愛垂昔窮載至容倚學虛和曉送橫淚寄度池識休雁沙州田桃病鳳忘散隱夫羣恨早爾悲六元斜荒覺遺女合靜都珠解便燈易親亂說信許待杯閒隔但功通火冷絲唯定令鬥寂死論因會霞蘭賢用立而細紛筆奇徑景陵爭顏面屋帶翁吳羅錦力郎主結舞著觀化佳點疑冰浪跡川閣巖雖楚賦遲薄交尺直簾目飄章歡食願船憂橋鼓臥鍾字魂念村消乃寧破本底圖帝乘異悠那谷移飲翻步啼勞諸原端想皇素息蓬冠朱民尊性能
只保留一些關於表意向的詞,保留前一百20個表意向的字。春花秋月齊了,春江花月夜也齊了ui
人風山天雲日花春月水心江秋君雨夜玉酒客聲
最後,歡迎關注個人公衆號山月行進行交流