矽谷之路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中單引號和反引號的區別是什麼?
消息隊列如果持久化到資料庫的話,相對於直接操作資料庫有啥優勢?

TAG:系统设计 | 数据库 |