一個電商專案的Web服務化改造3:改進方案の規範和約定、單表、單一職責

小雷FansUnion發表於2016-04-30
     最近一直在做一個電商專案,需要把原有單系統架構的專案,改造成基於服務的架構,SOA。
     有點挑戰,做完了,會有很大進步。

  上一篇,我們描述了原有專案中的問題。
  或者說是,本篇的基本背景。

  本篇開始,給出我們的改進方案和技術架構。
  不過,根據自己的理解,我先列出了“規範和約定”。

  因為,我認為“規範和約定”是具體方案和解決辦法的基石,也是很多網際網路專案的基本準則吧。

  
2.改進方案和技術架構
 
   2.1規範和約定
 
   2.1.1程式碼規範
      用準確的英文單詞,給類、函式名、變數名
      get,add,update
      更多細節,參考“Java程式碼規範-小雷.pdf”和“JAVA編碼規範.pdf
 
   2.1.2約定優於配置,約定優於註釋
         資料庫表名和欄位名、Java類、函式、變數名
 
        
約定優於配置
        
約定優於配置(convention over configuration),也稱作按約定程式設計,是一種軟體設計正規化,
旨在減少軟體開發人員需做決定的數量,獲得簡單的好處,而又不失靈活性。

本質是說,開發人員僅需規定應用中不符約定的部分。
例如,如果模型中有個名為Brand的類,那麼資料庫中對應的表就會預設命名為brand,Controller的名字預設命名為BrandController。
只有在偏離這一約定時,例如將該表命名為"product_brand",才需寫有關這個名字的配置。  

     約定優於註釋
    這個是我自己的見解。
     用標準,統一的英文單詞,給變數和函式等命名。
    比如資料庫表brand表有個欄位name。
    BrandDao有個add和update方法。

   brand:就是品牌的意思
   name:就是品牌的名稱
   add:就是增加一個品牌,BrandDao中,千萬別用addBrand這種囉嗦的命名方式,類名中已經包含了Brand,裡面的dao就是和brand相關的。
   update:就是更新一個品牌

  不用去寫註釋,也不用去和相關人士,過多解釋這個欄位的意思,這個函式的作用。
  望文生義,通過名字就可以知道準確的意思,就不用多費口舌了。

  對於那些複雜的程式碼,比如訂單支付過程中,有一些不好理解的業務邏輯程式碼,再寫簡潔的註釋。
 
   2.1.3單表 
       a.服務分離
          web服務比較多,到處都是, 一個服務和對應的資料庫是邏輯上在一起的。
          感覺有點說不通呢?多表憑啥不能做到“服務分離” 。
          更準確的理由,應該是下面提到的“分庫分表”,然後才是“服務分離”這個 。
 
       b.不方便快取
          單表的結果集,方便快取,而多表則不合適。
          比如user表有roleId欄位,查詢使用者的時候,查1個使用者,再根據roleId查角色資訊。
         但是,關聯的角色名稱可能變化了,或者user使用者資訊變了,而角色不變。
          那麼,可以單獨快取user或者role。
         而多表的情況下,還是都查詢了資料庫。 
 
       c.聯合查詢,效率低
         當資料量大的時候,笛卡爾積很大,10000*10000,佔用的記憶體很大。
         假設記憶體足夠的話,笛卡爾積的過程,也很需要時間。

        而單表查詢,沒有笛卡爾積的過程,先批量查A,比如10條,再批量去B查,1次10條,程式碼組裝,資料就夠了。

        這裡面存在一個問題,當A-B表關聯查詢,但是查詢條件是B表欄位的時候,這個是否必須“關聯查詢”。
        比如,根據使用者角色名稱,查詢使用者,獲得第1頁10條資料。

        如果還是單表的情況,就需要做“冗餘”。

       因此,我們說“單表”存在2個含義。
       一、只有自己一個表的資料,二、物理上是一個表,但邏輯上有2個表的資料。
 
       d. 併發
          每個表資料量、查詢查詢、修改次數等都不一樣。
          單個表,如果需要鎖住一行,也更加精準。
    
          這個地方,還不是特別確定。 
         單表鎖一行:select * from brand where id =1 for update
         多表鎖一行:select * from user left join  role on user.roleId = role.id where roleId = 1 for updte ?
 
         準確的說,以上是“併發修改” 中的1個例子,還有“併發查詢”等很多種併發場景吧。
 
       e. 如何分表、分庫
           資料量大的時候,需要分表分庫。
          分表分庫之後,聯合查詢就很廢材了。
 
        f.根據業務場景和特性,分別做優化
           實際情況,user、role、brand等查詢量、修改量等都是不同的。
           這一點,和把整個專案拆分成商品product、使用者user等思想是類似的。
           拆分成更小粒度的,方便做優化。

     疑問: 既然MySQL多表這麼廢材,為什麼當初設計MySQL等資料庫的時候,都有關聯查詢等一大堆功能特性呢?
    難道是因為網際網路崛起,超出了當初設計者的想象力? 

   2.1.4單一職責
         一個類、一個函式,只做一件事,只完成一個功能。
         一個介面集,對外提供的服務,也是緊密相關的。 

   個人觀察多問幾個為什麼,可以發現更多的問題,學到更多更深入的“知識點” 。
                    用單表是好,為啥不能用“多表聯合查詢” ,通過對這個問題的思考和交流,理解更近了一步。

   約定優於註釋,算是我的獨家見解吧~ 

相關文章