矽谷之路29:如何設計用戶系統(三)
查看完整視頻:http://www.bittiger.io/classes
如何在用戶系統中支持membership?
當然要有一個membership的類,偷窺一下:
我們只記錄一個endTime就好了,startTime不用記呀,因為買membership只用增加endTime就好了,關startTime什麼事。然後再講一個小妙招:用double存餘額可能精度不準的(這是一個事實),怎麼辦呢?可以把錢數乘一百然後用int保存。
t如果我們把數據存在資料庫里,用資料庫來操作,資料庫會保證ACID(什麼是ACID?要講,不要急),應該不會有什麼問題。可是如果你偏不用資料庫,你自己隨便存一存,會出現什麼問題呢?我們來看一看,讓你知道資料庫的好。
t先看看這個情況:
假設用戶買一個月的音樂會員(10刀),好的情況就是錢減了,endTime加了。壞了情況是錢減了,系統掛了。竹籃打水一場空,錢沒了,endTime也沒有增加(好慘)。
t資料庫怎麼解決的呢?加log。在扣錢之前先寫好原始的狀態,這樣一旦系統崩了,就查log把原始狀態恢復出來,廣大人民群眾的財產就不會收到損失。所以資料庫有Atomicity(原子性),要麼不做,要麼做完,不會做一半。
再看看這個情況:
來找不同:首先左面的表沒有18,右邊的有18(影子用戶);還有右邊的表有兩個4(重複用戶)。資料庫可以很容易地解決這些問題,比如設為distinct就不會有重複用戶,影子用戶用外鍵解決,所以資料庫可以保證Consistency(一致性)。
t再看看這個情況:
用戶購買了兩次會員,如果兩次獨立沒什麼問題,可是假如因為網路等原因伺服器端兩次請求幾乎同時就可能有問題:
兩個線程都讀到錢是20,然後線程1完成了,結束時間增加了一個月,線程2讀到了增加以後的時間,可是因為它讀到的也是20,所以最後用戶只花了一次錢買了兩次服務(超值)。
解決方法是加鎖,當線程1開始讀寫了的時候它就會將表鎖起來,線程2就進入等待,直到線程1結束。 資料庫的Isolation(隔離性)說的就是這個,兩次transaction之間要互不干擾。
最後,數據可能丟失(真的),所以資料庫會備份。這就是Durability(持久性)。
本文整理作者:Mengying Tian,查看完整視頻:http://www.bittiger.io/classes
更多精彩內容, 請掃描下面二維碼,關注微信公眾賬號「論碼農的自我修養」
推薦閱讀:
※PostgreSQL通信協議
※TiKV 源碼解析系列 - Lease Read
※MySQL中單引號和反引號的區別是什麼?
※消息隊列如果持久化到資料庫的話,相對於直接操作資料庫有啥優勢?