2009-05-25 20 views
5

Aquí está mi situación: estoy tratando de seguir lo más posible el patrón de 3 niveles (es decir, presentación, negocio y capa de datos). Cuando necesito datos de la base de datos, la capa empresarial llama a la capa de datos que devuelve la información. La capa de datos nunca devuelve un objeto SqlDataReader o DataTable, pero a menudo una enumeración de un objeto personalizado conocido por la capa de acceso a datos. Funciona bastante bien cuando la capa de Datos tiene que devolver una lista con pocos objetos.patrón de 3 niveles y grandes cantidades de datos

Ahora me enfrento a este problema, mi aplicación (la capa de negocios) debe procesar 500000 registros. Podría simplemente agregar otro método a mi capa de datos y devolver un IEnumerable, pero esto me parece muy malo. No quiero cargar medio millón de registros en la memoria.

Mi pregunta es, teniendo en cuenta el modelo de 3 niveles, ¿cómo debo manejar este caso? Si no tuviera un patrón de 3 niveles, simplemente usaría SqlDataReader en mis clases de negocios. ¿Alguna sugerencia?

ACTUALIZACIÓN: No se mostrarán los datos, por lo que este no es un problema de búsqueda (aquí la capa de presentación no está involucrada en absoluto). Simplemente tengo que analizar cada registro y luego conservar algunos de ellos.

Gracias

Respuesta

2

que asumen esta sección está oculta 500.000 registros en el extremo delantero a la vez? Probablemente estés haciendo una paginación, ¿verdad? Por lo tanto, solo devuelve una página con los datos de la base de datos al mismo tiempo.

1

Sí, su instinto es correcto.

Estoy apostando a que su cliente de interfaz de usuario no quiere ver medio millón de registros a la vez. Google no devuelve todos los aciertos en una sola página; tampoco lo harás.

Tiene la opción de elegir dónde y cuándo su aplicación procesa esos medio millón de registros. Puedes dividirlos en unidades de trabajo más pequeñas; puedes procesarlos de forma asincrónica; puede escribir un procedimiento almacenado y procesarlo en la base de datos sin llevarlos al nivel intermedio.

El patrón MVC es maravilloso, pero no es una escritura sagrada. Haga las elecciones que funcionan para su aplicación.

0

Esto no es un problema poco común y ocurre con frecuencia en situaciones en las que necesita consolidar grandes cantidades de datos y presentar resúmenes al usuario (los informes son un ejemplo típico). Su solución debe diseñarse teniendo en cuenta estas consideraciones. No tiene sentido ignorar las eficiencias que ofrecen los lectores sql (o herramientas similares) cuando la coherencia estricta con algún modelo arquitectónico particular hace que su aplicación sea ineficiente. A menudo es posible superar algunos de estos problemas adaptando un modelo arquitectónico a sus necesidades. Los modelos genéricos de arquitectura rara vez son aplicables de inmediato. Son pautas que se deben aplicar a sus necesidades particulares.

1

Un pedazo de papel nunca puede superar la realidad. Si su problema específico pide romper el paradigma de 3 niveles, hágalo.

0

No hay que avergonzarse de hacer cualquier análisis que necesite a nivel de la base de datos. Si puede cortar y cortar lo que necesita con el procedimiento almacenado o realizar las correlaciones necesarias con los procedimientos almacenados y usar una aplicación para operaciones más complejas, debería estar bien.

La pregunta es, ¿el usuario espera presionar un botón y procesar todos los 500K registros y ver un resultado? Si es así, ¿están dispuestos a sentarse y mirar un gif giratorio o será satisfactorio recibir algún tipo de notificación cuando el proceso esté completo?Si el procesamiento de los 500K es de la máxima importancia, ¿necesita modificar su modelo de datos para respaldar este proceso? Existen métodos de procesamiento como Hadoop y message queues que están diseñados para este gran volumen, pero ¿necesita ir a este punto? Es posible que pueda establecer las expectativas de sus usuarios antes de sacarle el pelo por encima del rendimiento.

1

En algunos casos, debe romper los límites de 3 niveles. Pero antes de hacerlo, usted podría preguntarse:

  1. Cuando "analizar cada registro y luego mantener algunos de ellos," es que realmente parte de la lógica de negocio? ¿O es una función de acceso a datos? Podría ser el caso de que esto pertenezca a la capa de acceso a datos.

  2. Si es parte de la lógica de negocios, ¿necesita todos los 500000 registros para tomar una decisión acerca de si "mantener" un registro individual? Es posible que la capa empresarial deba procesar un registro a la vez. Realizar 500000 llamadas a bases de datos consecutivas no es agradable, pero si eso es lo que debería hacer la aplicación desde un punto de vista conceptual, existen formas de mitigar eso.

No recomiendo hacer nada tonto solo para mantener los 3 niveles separados. Pero a veces, cuando piensas que tienes que cruzar la línea, es porque hay algo en el diseño que necesita una segunda mirada.

-
BMB

1

Se puede construir una abstracción en la parte superior de la clase SqlReader. De esta forma, no tiene que pasar el SqlReader directamente, pero puede procesar los objetos de uno en uno.

Think Iterators.

0

Si estoy entendiendo esto correctamente, quiere "Analizar" los registros y luego conservar algunos de ellos y deshacerse del resto de ellos. Bueno, en ese caso, creo que será mejor manejar esto dentro de la base de datos (PL/SQL o T/SQL). Los requisitos como estos deberían ser una prioridad máxima y no la arquitectura. Como no muestra solo analizar, lo mejor es hacerlo en el procedimiento en sí.

1

Filtra en la base de datos. no es necesario traer de todos modos 500000 registros que va a filtrar. Por qué llevarlos a todos al nivel intermedio solo para eliminarlos. Cuide la operación (datos) tan pronto como sea posible usando SQL Engine en el back-end (sproc). Más eficiente, similar a verificar las comprobaciones básicas de entrada en la capa de presentación antes de enviar a IIS.

Cuestiones relacionadas