2009-05-25 15 views
5

Ecco la mia situazione: sto cercando di seguire il più possibile il modello a 3 livelli (cioè il livello Presentazione, Business e Dati). Quando ho bisogno di dati dal DB, il livello Business chiama il livello dati che restituisce le informazioni. Il livello dati non restituisce mai un oggetto SqlDataReader o DataTable, ma spesso un'enumerazione di oggetto personalizzato noto da Data Access Layer. Funziona piuttosto bene quando il livello dati deve restituire una lista con pochi oggetti.Schema a 3 livelli e grandi quantità di dati

Sono ora di fronte a questo problema, la mia applicazione (il livello aziendale) deve elaborare 500000 record. Potrei semplicemente aggiungere un altro metodo al mio livello dati e restituire un oggetto IEnumerable ma questo mi sembra molto brutto. Non voglio caricare mezzo milione di record in memoria.

La mia domanda è, considerando il modello a 3 livelli, come devo gestire questo caso? Se non avessi uno schema a 3 livelli, userò semplicemente SqlDataReader nelle mie lezioni di business. Eventuali suggerimenti?

UPDATE: I dati non verranno visualizzati, quindi questo non è un problema di impaginazione (il livello di presentazione non è affatto coinvolto qui). Devo semplicemente analizzare ogni record e poi conservarne alcuni.

Grazie

risposta

2

Suppongo che tu non sei la visualizzazione di 500.000 record al front-end in una sola volta? Probabilmente stai facendo qualche impaginazione, giusto? Quindi, restituire una sola volta il valore di una pagina di dati dal database contemporaneamente.

1

Sì, il tuo istinto è corretto.

Scommetto che il tuo client di interfaccia utente non vuole guardare mezzo milione di record contemporaneamente. Google non restituisce ogni hit in una singola pagina; non lo farai neanche tu.

È possibile scegliere dove e quando l'applicazione elabora tali mezzo milione di record. Puoi dividerli in unità di lavoro più piccole; puoi elaborarli in modo asincrono; è possibile scrivere una procedura memorizzata ed elaborarli nel database senza portarli al livello intermedio.

Il pattern MVC è meraviglioso, ma non è scritto santo. Fai le scelte che funzionano per la tua app.

0

Questo non è un problema raro e si verifica frequentemente in situazioni in cui è necessario consolidare grandi quantità di dati e presentare riepiloghi all'utente (i report sono un tipico esempio). La tua soluzione dovrebbe essere progettata tenendo conto di queste considerazioni. Non ha senso ignorare le efficienze offerte dai lettori di sql (o strumenti simili) quando la stretta coerenza con alcuni particolari modelli architettonici rende l'applicazione inefficiente. Spesso è possibile superare alcuni di questi problemi adattando un modello architettonico alle proprie esigenze. I modelli architettonici generici sono raramente applicabili fuori dalla scatola. Sono linee guida che dovrebbero essere applicate alle tue particolari esigenze.

1

Un pezzo di carta non può mai superare la realtà. Se il tuo problema specifico richiede di rompere il paradigma a 3 livelli, fallo.

0

Non c'è da vergognarsi nel fare qualsiasi analisi è necessario a livello di database. Se riesci a tagliare e a tagliare ciò di cui hai bisogno con la stored procedure o a fare le necessarie correlazioni con le stored procedure e ad usare un'applicazione per operazioni più complesse, dovresti stare bene.

La domanda è: l'utente si aspetta di premere un pulsante ed elaborare tutti i record di 500K e vedere un risultato? Se è così, sono disposti a sedersi e guardare una gif girevole o sarà soddisfacente ricevere un qualche tipo di notifica quando il processo è completo?Se l'elaborazione del 500K è della massima importanza, il tuo modello di dati necessita di modifiche per supportare questo processo? Esistono metodi di elaborazione come Hadoop e message queues adatti per questo volume elevato, ma è necessario andare in questa misura? Potresti essere in grado di impostare le aspettative dei tuoi utenti prima di tirarti i capelli sulle prestazioni.

1

In alcuni casi, è necessario interrompere i confini a 3 livelli. Ma prima di farlo, si potrebbe chiedere a te stesso:

  1. Quando si "analizzano ogni record e poi tenere alcuni di loro," è che in realtà parte della logica di business? O è una funzione di accesso ai dati? Potrebbe essere il caso che questo appartenga al livello di accesso ai dati.

  2. Se è parte della logica di business, avete bisogno di tutti i 500000 record al fine di prendere una decisione sull'opportunità di "tenere" ogni singolo record? Potrebbe essere che il livello aziendale debba elaborare un record alla volta. Fare 500000 chiamate di database consecutive non è bello, ma se questo è ciò che l'app dovrebbe fare da un punto di vista concettuale, ci sono modi per mitigarlo.

Non consiglio di fare qualcosa di stupido solo per tenere separati i 3 livelli. Ma a volte, quando pensi di dover superare la linea, è perché c'è qualcosa nel design che ha bisogno di un secondo sguardo.

-
BMB

1

Si può costruire un'astrazione sulla parte superiore della classe SqlReader. In questo modo non è necessario passare direttamente SqlReader, ma è comunque possibile elaborare gli oggetti uno alla volta.

Think Iterators.

0

Se sto capendo correttamente questo, si vuole "analizzare" i record e poi tenerne alcuni e sbarazzarsi del resto di essi. Bene in quel caso penso che sarà meglio gestirlo all'interno del database stesso (PL/SQL o T/SQL). Requisiti come questi dovrebbero essere una priorità assoluta e non l'architettura. Dal momento che non stai visualizzando solo l'analisi, è meglio farlo nella procedura stessa.

1

Effettua il filtraggio nel database. non è necessario portare oltre 500000 record che filtrerai comunque. Perché portarli tutti al livello intermedio solo per rimuoverli. Prenditi cura dell'operazione (dati) il prima possibile usando l'SQL Engine nel back-end (sproc). Più efficiente, simile alla verifica dei controlli di input di base sul livello di presentazione prima dell'invio a IIS.

Problemi correlati