2009-12-18 3 views
5

Tengo una gran cantidad de datos almacenados en un archivo XML, 173 MB (4.6 millones de líneas), que he almacenado en el directorio de trabajo de mi aplicación Windows Forms. Es el resultado de escribir una tabla de datos en un archivo XML. La tabla de datos se llenó originalmente de una consulta a un servidor SQL. El motivo por el que lo almacené localmente en lugar de solicitarlo al servidor es que la solicitud de datos tomó más de 40 segundos y en algunos casos expiró y los datos son estáticos y nunca cambiarán, además el usuario puede estar desconectado y aún usar los datos.Buscando ideas sobre el almacenamiento de datos en el disco local

Volver a cargar el archivo en la tabla de datos lleva de 20 a 30 segundos. No estoy demasiado preocupado sobre el tiempo que tardó en cargarse desde el disco, ya que dejo saber al usuario que los datos se están cargando y que soy paciente. Sin embargo, no me gusta el formato de archivo XML y estoy buscando otras ideas para el almacenamiento en disco.

La tabla de datos solo se usa como intermediario para la población final de un objeto de colección. Si tienes sugerencias, me gustaría escucharlas.

Espero estar lejos de una solución de base de datos e inclinarme hacia un enfoque de archivo binario. A continuación es mi primer intento, pero me da una excepción de memoria insuficiente:

byte[] b = null; 

using (MemoryStream stream = new MemoryStream()) 
{ 
    BinaryFormatter bformatter = new BinaryFormatter(); 
    bformatter.Serialize(stream, timeData); 
    b = stream.ToArray(); 
} 

using (FileStream fileStream = new 
    FileStream("brad.bin", FileMode.Create, FileAccess.Write)) 
{ 
    fileStream.Write(b, 0, b.Length); 
} 
+0

puedes decir por qué está "esperando a permanecer lejos de una solución de base de datos"? Como muchos encuestados han señalado, esto parece una opción perfecta para una base de datos local ligera: si explica la restricción de diseño que cree que hace que esto sea incorrecto, tal vez la gente podría sugerir alternativas. – itowlson

+0

Solo esperaba evitarlo. Parece que hay que trabajar mucho con muy poco beneficio. – Brad

+0

Es muy poco trabajo extra. SQLite incluso se factura a sí mismo como una 'base de datos de cero administración'. – Joe

Respuesta

11

Me gustaría ver una base de datos compacta (local) como SQL Server CE o SQLite. Las bases de datos están diseñadas para esto exactamente.

+0

SQL CE se integra completamente en la línea de herramientas de Visual Studio, debería ser más fácil dado que el DB maestro es SQL Server, y es libre y libremente redistribuible. –

+0

Al haber usado SQLite, me encanta. Puedes usar LINQ con eso también. – jcollum

+0

+1 para SQLite Lo he usado en numerosos escenarios ahora y es simplemente increíble. –

2

Usted puede intentar usar SQLite o CSV-archivo, por ejemplo.

5

SQLite is pretty nice, puede elegir entre una variedad de soluciones DB desconectadas, pero realmente depende del trabajo que desea realizar y del conjunto de datos que tenga.

1

si está utilizando la tabla de datos como intermediario y luego la carga desde allí en una colección, ¿qué hay de usar XMLSerialize para cargar directamente en su colección? Saltarse al intermediario debería darte algunas mejoras en el rendimiento.

0

En primer lugar ... que era un párrafo fea para leer: P

cuanto a su pregunta, si está utilizando .NET, por qué no ir con SQL Server Compact (archivo MDF)? Es como trabajar con SQL Server, pero los datos se almacenan en un archivo.

yo personalmente creo que es el mejor camino a seguir, pero si quieres opciones entonces yo supongo que se podría considerar el archivo

  • Excel
  • separados por comas archivo de texto
  • MS Access Database
  • ?
+0

¡Maldición! ¡No había respuestas cuando comencé a escribir!¡Creo que debería publicar mis respuestas de una manera más rápida/más sucia y luego editarlas para corregirlas/mejorarlas/"estilizarlas"! –

1

¿Por qué la aplicación solicita todo el conjunto de datos todo el tiempo? Si está utilizando una base de datos, debe (imho) tratar la base de datos de manera similar a su pila ...
- Solicitar lo que se necesita

Algunas operaciones pueden requerir la comparación de diferentes datos en toda la base de datos , pero para eso es SQL. Realice esas operaciones en la base de datos, no en la aplicación.

¿Tiene un escenario de caso de uso en el que necesita absolutamente todo el conjunto de datos en la memoria?

2

Si se puede nunca cambiar, ¿por qué no le está dando la instalación de la aplicación en primer lugar?

¿Está confundido acerca de lo que realmente significan los términos "nunca va a cambiar"?

En cuanto a las soluciones de almacenamiento local, hay mucho para elegir, como SQLite que le permitiría utilizar una solución de base de datos, incluso localmente, sin problemas de instalación.

+0

Estoy ofreciendo con la instalación de la aplicación. Me gustaría tenerlo como un archivo de recursos. – Brad

+0

Si realmente nunca cambiará, y proporcionarle la aplicación es un enfoque viable, buscaría simplemente instalar un archivo de base de datos SQLite o similar, o dejar que la aplicación cree ese archivo de base de datos desde la primera vez que ejecute . En ningún caso, cargaría un archivo XML de varios megabytes para cargar datos, a menos que lo necesite * todo *. Si solo necesito partes de los datos, cargaría esa parte, y nada más, y eso significa algo distinto de XML (o tendrá que comer ese XML por partes para extraer las piezas relevantes). –

+0

Los datos están histórico y se utiliza para crear gráficos de datos de rendimiento. Se aplicarán los datos al recurso mes por mes; el programa solicitará estos pequeños fragmentos de datos. ¿SQLite es solo un archivo y no una aplicación? - porque podría simplemente suministrar el archivo y dejar que el programa anexe el archivo según sea necesario – Brad

0

Tampoco me gusta XML, pero creo que es el camino a seguir si los datos son de solo lectura.

Creo que bien podría estar escribiendo un texto XML en formato de texto XML estándar en el disco, a pesar de que utiliza una clase con Binary en el nombre. Ábrelo, mira. (Utilice la herramienta dd Unix (descargue algunas herramientas de Unix si todavía no tiene dd) para tomar un archivo de muestra de solo los primeros megabytes, ábralo en Wordpad o similar y eche un vistazo.)

Si desea hacer que no sea fácilmente legible por humanos, considere usar encriptación.

EDITAR

eso es si las estaciones de trabajo son más o menos dedicados a la tarea y pegando 173 MB de datos en la memoria RAM, y trabajando desde que en lugar de tocar el violín con SQL pasa a hacer un buen negocio.

0

¿Por qué no dejar los datos en el servidor y usar algún caché de DataSet estándar? Crear una consulta que devuelva 180Mb de datos suena como un problema de diseño.

Creo que una solución más apropiada para una tendencia histórica sería recuperar solo aquellos registros que se muestran actualmente. Cuando desee ampliar una parte de su gráfico, recupere solo los datos ampliados.

En cuanto a su serialización binaria, debe serializar directamente aFileStream:

using (FileStream fileStream = new 
    FileStream("brad.bin", FileMode.Create, FileAccess.Write)) 
{ 
    new BinaryFormatter().Serialize(fileStream, timeData); 
} 
Cuestiones relacionadas