2009-05-25 74 views
5

這是我的情況:我試圖儘可能遵循3層模式(即演示,業務和數據層)。當我需要來自數據庫的數據時,業務層會調用返回信息的數據層。數據層永遠不會返回SqlDataReader或DataTable對象,但通常是數據訪問層已知的自定義對象的枚舉。當數據層必須返回一個包含少量對象的列表時,它工作得非常好。3層模式和大量的數據

我現在正面臨這個問題,我的應用程序(業務層)必須處理500000條記錄。我可以簡單地將另一種方法添加到我的數據層並返回一個IEnumerable,但這個聲音對我來說很糟糕。我不想在內存中加載五十萬條記錄。

我的問題是,考慮到3層模型,我應該如何處理這種情況?如果我沒有3層模式,我只需在業務類中使用SqlDataReader。有什麼建議麼?

更新:數據將不會顯示,所以這不是一個分頁問題(表示層根本沒有涉及)。我只需要分析每條記錄,然後保留其中的一部分。

謝謝

回答

2

我假設你沒有一次向前端顯示500,000條記錄?你可能正在做一些分頁,對吧?所以,一次只能從數據庫中返回一頁數據。

1

是的,你的直覺是正確的。

我打賭你的UI客戶端不想一次查看50萬條記錄。 Google不會在單個頁面中返回每一次點擊;你也不會。

您可以選擇何時何地應用程序處理這些50萬條記錄。你可以把它們分成更小的工作單位;你可以異步處理它們;你可以編寫一個存儲過程並在數據庫中處理它們,而不必將它們全部帶到中間層。

MVC模式很棒,但它不是神聖的文字。選擇適用於您的應用程序的選項。

0

這不是一個不常見的問題,並且在您需要合併大量數據並向用戶顯示摘要(報告是一個典型示例)的情況下經常發生。考慮到這些考慮因素,應該設計您的解決方案。當對某些特定架構模型的嚴格一致性使您的應用程序效率低下時,忽略sql讀取器(或類似工具)提供的效率是毫無意義的。通過調整架構模型以滿足您的需求,通常可以克服其中一些問題。通用的架構模型很少適用於開箱即用。他們是應該適用於您的特定需求的指導方針。

1

一張紙永遠不會超過現實。如果您的具體問題要求打破三層模式,請執行此操作。

0

在數據庫級別進行所需的任何分析並不令人羞恥。如果你可以使用存儲過程切片和切片,或者與存儲過程進行必要的關聯,並使用應用程序進行更復雜的操作,那麼你應該沒問題。

問題是,用戶是否期望按下按鈕並處理所有500K記錄並查看結果?如果是這樣,他們是否願意坐下來觀看一個旋轉的GIF圖片,或者當這個過程完成時是否會收到某種類型的通知令人滿意?如果處理500K非常重要,那麼您的數據模型是否需要更改以支持此過程?有一些處理方法,如Hadoopmessage queues,適合這種高容量,但是你需要去這個程度嗎?您可以設置您的用戶的期望,然後拉動您的表現。

1

在某些情況下,您必須打破三層邊界。但在此之前,你可以問自己:

  1. 當你「分析每個記錄,然後保存其中的一些,」是業務邏輯的一部分真的?或者它是一個數據訪問功能?它可能屬於數據訪問層。

  2. 如果它是業務邏輯的一部分,你是否需要所有500000條記錄才能決定是否「保留」任何單獨的記錄?這可能是業務層應該一次處理一條記錄。進行500000次連續的數據庫調用並不好,但如果這是應用程序從概念角度來看應該做的事情,那麼有辦法來緩解這種情況。

我不建議做任何愚蠢的事情,只是爲了保持3層分開。但有時候,當你認爲必須跨越界限時,這是因爲設計中有某些東西需要再次觀看。

-
BMB

1

您可以在SQLReader的類之上構建一個抽象。這樣你就不必直接傳遞SqlReader,但你仍然可以一次處理一個對象。

認爲迭代器。

0

如果我正確理解這一點,你想「分析」記錄,然後保留其中的一部分並擺脫其餘部分。那麼在這種情況下,我認爲最好在數據庫本身(PL/SQL或T/SQL)中處理這個問題。像這些要求應該是最重要的,而不是架構。既然你不是隻顯示分析,最好在程序本身。

1

在數據庫中執行過濾。無論如何,您無需再提取超過500000條記錄。爲什麼要把它們全部帶到中間層去除它們呢?儘可能早地使用後端的SQL引擎(sproc)來處理操作(數據)。效率最高,類似於在發送到IIS之前檢查表示層上的基本輸入檢查。