2009-07-20 44 views
1

假設您正在編寫零售連鎖店的應用程序。所以,你可以設計你的對象模型,以便將'Store'定義爲核心業務對象和大量支持對象。比方說,「商店」看起來如下:什麼時候「進入」和何時不到?

class Store implements Validatable{ 
int storeNo; 
int storeName; 
... etc.... 
} 

所以,你的客戶會告訴你,你必須從一個Excel工作表到應用程序中導入商店的時間表,你將不得不對「時間運行一系列驗證的。例如,'StoreIsInSameCountry','StoreIsValid'等等。因此,您將設計一個Rule界面來檢查所有的業務條件。類似這樣的:

interface Rule T extends Validatable> { 
public Error check(T value) throws Exception; 
} 

現在,問題來了。我從這張Excel表格上傳了2000家商店。所以,我最終會運行爲商店定義的每個規則多次。如果我對數據庫有4條規則= 8000條查詢,即對連接池有16000條命中。對於一個簡單的檢查,我就只需要檢查商店是否存在,查詢將是:

SELECT STORE_ATTRIB1, STORE_ATTRIB2... from STORE where STORE_ID = ? 

這樣,我會得到讓我的「商店」的對象。當我沒有從數據庫中得到任何東西時,那個商店就不存在了。所以,對於這樣一個簡單的檢查,我將不得不在2000個商店中打2000個數據庫。

另外,我可能只是這樣做:

該查詢實際上返回比做它上面的2000倍,一個快得多。 但是,它的設計並不適用於只能爲單個商店運行規則。

我知道使用IN不是建議的方法。那麼,你認爲我應該怎麼做?我應該繼續並在此使用IN,因爲它會在這種情況下提供更好的性能?還是應該改變我的設計?

如果你在我的鞋子裏,你會怎麼做?最佳做法是什麼?

回答

0

我認爲這更像是一個帶有參數的業務問題,即客戶端運行導入的頻率,實現這個解決方案需要多長時間,以及每小時的時間是多少。

如果是偶爾運行一次,我認爲可以接受一些不好的性能,尤其是如果您可以使用乾淨的代碼快速完成工作。

1
SELECT store_id FROM store WHERE store_active = 1 

甚至

SELECT store_id FROM store 

會告訴你在一個查詢所有活動的商店。您現在可以對已知存在的商店進行其他測試,並將自己的1,999次點擊保存到數據庫。

如果您擁有相對無爭議的數據庫訪問權限,並且沒有時間限制整個事情需要花費多長時間,那麼您無需擔心一次又一次地連接連接池。畢竟這就是它的設計目的!

+1

爲了做你所說的話,如果我要將結果集緩存到某個地方,那麼這樣做會很有意義。即使採用上述方法,我也必須一次驗證一個商店,而不是緩存結果集,我不知道如何將自己的1999年點擊數據庫。 – Jay 2009-07-20 14:14:32

2

這樣我就可以從數據庫中獲得'Store'對象。當我沒有從數據庫中得到任何東西時,那個商店就不存在了。所以,對於這樣一個簡單的檢查,我將不得不在2000個商店中打2000個數據庫。

這就是你應該不是做的。

創建一個臨時表,填寫表格與你的價值觀和JOIN這個表,就像這樣:

SELECT STORE_ATTRIB1, STORE_ATTRIB2... 
FROM temptable tt 
JOIN STORE s 
ON  s.STORE_ID = t.id 

或本:

SELECT STORE_ATTRIB1, STORE_ATTRIB2... 
FROM STORE s 
WHERE s.STORE_ID IN 
     (
     SELECT id 
     FROM temptable tt 
     ) 

我知道使用IN不是建議方法。那麼,你認爲我應該怎麼做?我應該繼續並在此使用IN,因爲它會在這種情況下提供更好的性能?還是應該改變我的設計?

IN過濾器重複出來。

如果您希望爲列表中的每個重複值選擇每個符合條件的行,請使用JOIN

IN決不是「不建議的方法」。

事實上,有些數據庫並不支持IN有效查詢,這就是爲什麼民間智慧仍然建議不要使用它。

但如果你store_id正確索引(它很可能是,如果它是一個PRIMARY KEY它看起來像),那麼主要數據庫的所有現代版本(即OracleSQL ServerMySQLPostgreSQL)將使用高效計劃執行此查詢。

看到這篇文章在我的博客的性能細節SQL Server

注意,在適當設計的數據庫,驗證規則也被設置爲主。

I.e。您執行您的驗證規則作爲針對temptable的查詢。

但是,爲了支持傳統規則,您可以從臨時排序行中選擇值,應用規則並刪除未通過驗證的值。

相關問題