把業務邏輯寫入應用程式,而不是資料庫

網路通訊頻道 發表於 2021-11-26
資料庫

我們都有過這樣的經歷,從SQL資料庫中提取資料,而需要提取資料的查詢是一個複雜的查詢,有多個表連線、過濾條件和複雜的WHERE語句。像MySQL和PostgreSQL這樣的資料庫,非常擅長執行復雜的連線、過濾和排序,以便從查詢中準確獲得所需的資料。

如果在資料庫中執行這些操作,所做的實際上是將業務邏輯從應用程式裡抽出,並將其移到資料庫邏輯當中。最終你會使用更多的資料庫資源和更少的應用伺服器資源,來實現所期望的資料檢索結果。

在實現資料插入要求時,也是如此。在執行資料插入之前,不必驗證所插入的資料是否有效、無衝突且在應用程式中完全正確,而是讓資料庫執行驗證,將衝突標準放入資料庫模式需求中,並讓資料庫在插入的資料中丟擲錯誤。

把業務邏輯寫入應用程式,而不是資料庫

應用程式資源更容易擴充套件

在某些情況下,你需要資料庫做這些型別的驗證和檢查。並不是說,不要讓你的資料庫做任何應用邏輯。而是,應該讓資料庫儘可能少地做應用業務邏輯,儘可能多地在應用程式程式碼本身中執行應用業務邏輯。

一般來說,擴充套件應用伺服器資源比擴充套件資料庫伺服器資源要容易得多。

對於大多數網路應用程式而言,當流量增加時,通常可以輕鬆地增加應用伺服器,來處理增加的負載。但是,除非資料庫也能擴充套件到處理增加的負載,否則額外的應用伺服器並沒有什麼幫助。

觀察應用程式的可用資源。您應該將資料庫看作是由稀缺的計算資源組成的,而應用程式程式碼層(包括服務)是由隨時可用的計算資源組成的,這些計算資源可以很容易地擴充套件。

資料庫資源是稀缺的,計算資源隨時可用。

一旦你能理解這種思維方式,你就會意識到在應用程式層中,放置儘可能多的邏輯,將有助於更容易地擴充套件。而將業務邏輯放在資料庫層會極大地限制該業務邏輯的可伸縮性。

讓資料庫處理複雜的過濾問題

不可能總是把所有的業務邏輯放在應用層。有時,你必須把某些查詢放在資料庫裡。這樣做的一個有效原因,可能是為了控制返回結果的數量。假設一個查詢在一個非常大的資料庫表上有一個複雜的過濾條件:

把業務邏輯寫入應用程式,而不是資料庫

在大型資料集上,執行復雜的過濾查詢後,預期的結果可能只有表中的幾條記錄。*將從這幾行返回所有資料。但是,如果希望在應用層,而不是資料庫中,執行復雜的過濾查詢,則通常需要先從資料庫中檢索所有的資料。你最終可能會出現這樣的結果: 把業務邏輯寫入應用程式,而不是資料庫

這將把mytable中所有資料返回給應用層。然後,應用層將扔掉任何沒有通過它在資料上執行的過濾條件的行。這樣做的問題是,為了執行這個需求,mytable的全部內容都必須被轉移到應用層。對於大型資料集來說,這是不可接受的。

在許多情況下,簡單地重構一個查詢或一系列查詢,可以避免此類問題,並允許你在應用程式中執行更多的邏輯,而不會產生不必要的資料流量。做到這一點的一個方法是將資料過濾與資料檢索分離開來。

過濾與檢索分離

我們經常把過濾結果和檢索結果的概念合併到單個查詢中。特別是當我們檢視有很多資料的大表時,編寫一個查詢,執行所有的過濾和規範,選擇我們需要的行,然後讓查詢從選擇的行中,返回需要的所有資料,這是非常方便的。

把業務邏輯寫入應用程式,而不是資料庫

就其本身而言,這似乎沒什麼問題。但是,當查詢涉及到複雜的連線或其他複雜的操作時,它就會給資料庫帶來不小的負荷,使資料庫資源緊張。

解決這個問題的方法是執行一個初始查詢,只簡單地從所有行中返回過濾查詢所需的欄位,然後在應用程式中執行過濾邏輯。讓我們假設field1和field2是上述<複雜的過濾查詢>中實際涉及的欄位。所以,讓我們在初始查詢中只獲得這些資料:

把業務邏輯寫入應用程式,而不是資料庫

然後,我們可以在你的應用程式程式碼中對field1和field2執行復雜過濾器查詢邏輯。這將導致我的表格中符合複雜查詢的行的ID列表。一旦你有了匹配的ID列表,你就可以執行後續的查詢,從預過濾的行中獲取實際資料:

把業務邏輯寫入應用程式,而不是資料庫

這兩個查詢都是非常簡單的查詢,不需要在資料庫中進行復雜的操作。選擇返回資料的必要業務邏輯是在應用層執行的,但需要從資料庫傳輸到應用的無關資料很少。通過將查詢分割成獨立的過濾和資料檢索查詢,你已經重構了你的請求,並允許複雜的、資源密集的業務邏輯在應用程式中執行,而不是資料庫。

避免對返回的結果進行操作

將業務邏輯從資料庫移到應用程式層的另一種簡單方法是避免對資料庫中返回的結果執行計算;而是在應用程式中執行它們。因此,不要做這樣的事情。

把業務邏輯寫入應用程式,而不是資料庫

你可以這樣做:

把業務邏輯寫入應用程式,而不是資料庫

然後,在應用程式中對返回的結果執行POWER(SQRT(field1)*SIN(field2),5)的等效計算。其結果是,執行計算所需的所有計算都利用了現成的應用程式資源,而不是稀缺的資料庫資源。

將連線轉移到應用層

複雜的連線是需要大量資料庫資源。與其在資料庫中連線資料,不如將盡可能多地連線邏輯轉移到應用層中。以這種方式重構程式碼,可以顯著減少資料庫的負載,同時提高可伸縮性。

當然,不可能總是以這些方式重構查詢。有時,只需要在資料庫本身中執行一個複雜的查詢。但是,通過儘可能多地刪除這些複雜的查詢,你可以減少對稀缺的資料庫資源的依賴,增加對高可用的應用級資源的依賴。

因此,下次當你看到使用多個連線和複雜過濾邏輯的大型、長且複雜的查詢時,不要為此感到困難。相反,考慮用更簡單的查詢(可能是多個查詢)和在應用程式層中執行的業務邏輯替換它的方法。

隨著應用程式的擴充套件,你會感受到改進的靈活性。

來自 “ https://www.infoworld.com/article/3633005/put-busi ”,原文連結:http://blog.itpub.net/31545813/viewspace-2844221/,如需轉載,請註明出處,否則將追究法律責任。