架構小白到磚家-09-【數據存儲問題】-ORM框架和純SQL的對比

通過前面對jpa提供的JpaRepository和JpaSpecificationExecutor兩種面向對象數據庫操作研究,已經解決了絕大多數開發工作中單表對象化操作。這兩種解決方案確實都非常優雅,省去了寫SQL的煩惱,甚至連接口的實現類都不需要我們去寫了。但是我們心中更加好奇,jpa難得真的就能將數據庫概念給抹殺掉了嗎?讓我們帶着疑問,再繼續整理一下,還有什麼數據庫使用場景咱們沒有討論到。
在這裏插入圖片描述
前面已經提到過,咱們一直討論的單表操作,那麼數據庫的多表查詢呢?我們先來看看jpa怎麼處理多表之間的關聯關係。數據庫理論中有範式概念,一共定義了六種範式,有興趣的同學可以自己去補充下這個知識,這裏就不展開討論了。我們可以簡單把範式理解爲將一個複雜數據模型從一張單表,拆解成多張子表的規範。這裏爲了討論方便,我們還是舉一個多表模型案例,就用戶權限模型吧。

用戶權限我們就簡化成用戶和角色兩個模型,用戶和角色是多對多的雙向關係,這種關係在數據庫範式中,我們需要建立除了用戶表和角色表之外,還要建立一張用戶角色關係表。那麼在ORM框架方案中,定義了數據庫表關係註解,@OneToOne,@OneToMany,@ManyToMany。由於這個方案的內容非常多,咱們就不展開討論這些註解的使用方法。咱們主要是爲了說明解數據庫多表之間關係,通過數據庫範式的要求,有主外鍵和關係表的概念,並且ORM框架提供了映射關係的方案。
在這裏插入圖片描述

我們已經定義好了用戶表、角色表、用戶角色關係表,不管是自己創建數據庫表,還是ORM框架自動生成,數據庫的理論都是不會改變的,都會生成這樣三張表。那麼我們在實際的開發過程中,使用的是對象,所以我們還是需要把JAVA的對象模型創建出來,爲了簡化討論範圍,我們只研究用戶對角色的一對多單向關係。
在這裏插入圖片描述

咱們的數據庫多表模型案例就準備就緒了,可以進行討論了。User和Role的單表映射,咱們都已經會了,只需要在User中添加一個@OneToMany關係。正常SQL操作來說,查詢用戶信息,先獲取User信息,然後在獲取用戶對應的角色信息放入User對象中roles。就需要發送兩條SQL,查詢用戶信息,查詢角色信息。存儲一個用戶時,也需要兩條SQL,存儲用戶信息,存儲用戶角色關係信息。

下面再來給幾個具體案例場景,看看SQL操作和ORM操作都怎麼處理。
第一修改用戶密碼,只需要用戶信息;
第二獲取菜單信息,需要用戶和角色信息;
第三刪除用戶信息。

使用SQL
第一個場景,只查詢用戶一條SQL,
第二個場景,發送兩條SQL。或者不在乎數據庫性能,第一和第二場景都發送兩條SQL。
第三個場景,先刪除user表信息,在刪除關係表信息。或者只刪除用戶表,關係表不刪除。當然這種操作需要降低數據庫範式要求,關係表不使用強制外鍵,就只是普通字段。這種操作雖然不合理,會造成關係表中有髒數據,但是可以快速滿足業務需求,實際場景中經常遇到很多非合理業務要求。

使用ORM框架
第一個場景,可以設置懶加載,進行延遲抓取,發一條SQL;
第二個場景,需要設置立即加載,發送兩條SQL。如果也是懶加載,就會在使用角色信息的時候,再發SQL獲取,會引發兩個問題,一個問題是使用角色信息的時候,超出了事務範圍,無法獲取數據了;另一個問題是造成N+1問題,每一個角色都會發送一條SQL。
第三個場景,只刪除user對象就可以了,會自動刪除關係表信息。表關係必須是強制外鍵,這種情況如果是一對一雙向關係,那就麻煩了,刪除一端,必須刪除另外一端,否則無法刪除。非常不靈活,特別是業務模型很複雜,關聯關係很多的情況。
在這裏插入圖片描述
簡單的從上面的對比中可以看出來,使用SQL會更加靈活,限制條件不多,可以降低數據庫範式等級來滿足複雜多變的業務場景需求;但是ORM方式就必須嚴格遵守數據庫強制外鍵的範式等級,理論上範式等級越高數據庫使用越合理,實際情況並不是這樣,範式的使用是需要特定業務場景的限制。另外還有數據加載時機問題,懶加載和立即加載只能二選一,引入更多的使用條件限制和N+1的難題。以前有過項目嘗試ORM強制外鍵關係,最後都是慘痛教訓收場。當然ORM這種方案還是有一定優點,對象化操作多表數據,自動聯動表關係處理,但是也帶來了更多壞處,屬於得不償失的情況。
在這裏插入圖片描述

結論,建議放棄ORM的多表方案,降低數據庫範式等級,不要使用強制外鍵,自己手動維護數據庫表關係。但是必須在有清晰的數據庫模型管理制度前提上。

回顧總結,數據存儲方案中,JPA沒法完全消除數據庫概念,需要原生SQL來解決多表查詢和特殊操作處理,比如報表查詢就是一個典型案例,報表涉及到大量的數據庫函數、多表連接、子視圖查詢等複雜SQL;還有一些特殊場景需要使用到數據庫存儲過程,來高效處理批量數據問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章