En general, para un conjunto de datos estructurado de este tipo, sospecho que podría escribir un formato de datos personalizado que fuera más rápido para la mayoría de las operaciones diarias (es decir, pequeños datos extraídos de un tiempo arbitrario). El beneficio de pasar a una herramienta de base de datos estándar es probable en algunos de los extras, por ejemplo, consultas ad hoc, acceso múltiple, replicación, disponibilidad, etc. También es más fácil contratar ayuda para mantener un almacén de datos basado en estándares.
Si me pidieran configurar una base de datos para almacenar esos datos, haría lo siguiente:
Esquema propuesto
(1) Los datos principales se colocan en numerosas (1000) de tablas individuales, cada una con dos columnas:
- tiempo: un tipo de datos SQL DATETIME o un tipo numérico de alguna época (esta es la clave principal)
- valor: escrito según corresponda para sus datos. De manera predeterminada, usaría un flotador de precisión simple, sin embargo, un tipo de datos de punto fijo puede ser más apropiado para transacciones financieras. Esto probablemente no está indexado.
Estas tablas serán bastante grandes, y es posible que desee particionarlas manualmente por (por ejemplo) año. Pero tendrá que verificar el rendimiento del sistema y ajustarlo según corresponda.
Estas tablas necesitan nombres únicos, y hay un par de opciones. Podrían ser legibles por humanos (por ejemplo, nyse_goog_dailyhighs_2010) o (mi preferencia) al azar. De cualquier manera, se requiere un conjunto de tablas de metadatos, y los nombres de tablas aleatorias evitan que los desarrolladores infieran algo en el nombre que no debe inferirse.
(2) Los metadatos se almacenan en tablas separadas, según lo requiera la aplicación :
Se requiere una tabla adicional o un conjunto de tablas para realizar un seguimiento de los metadatos. Estas tablas contendrán datos sobre el intercambio, el instrumento, el valor, la frecuencia, los rangos de fechas, la procedencia (de dónde provienen los datos), además de cualquier otra cosa que necesite. Estos se asignan a los nombres de la tabla de datos.
Si hay suficientes datos, esta búsqueda en realidad podría proporcionar un nombre de tabla y un nombre de base de datos, permitiendo una especie de fragmentación de datos auto implementada (si ese es el uso correcto del término). Pero lo mantendría en reserva.
Luego, en la capa de aplicación, consultaría las tablas de metadatos para determinar dónde estaban ubicados mis datos, y luego realizaría consultas relativamente simples en las tablas de datos grandes para obtener mis datos.
Ventajas:
Mi experiencia (relativamente limitada) es que las bases de datos generalmente pueden manejar una gran cantidad de tablas pequeñas más fácilmente que una cantidad menor de tablas grandes. Este enfoque también permite un mantenimiento más fácil (por ejemplo, depurar datos antiguos, reconstruir una tabla corrupta, crear / recargar desde copias de seguridad, agregar una nueva entidad). Esto desacopla completamente los diferentes tipos de datos, si (por ejemplo) tiene datos a diferentes velocidades, o si requiere diferentes tipos de datos.
Este concepto de tabla delgada también debería permitir un acceso rápido al disco para lo que sospecho que es la consulta más común, un rango contiguo de datos de una sola entidad. La mayoría de las aplicaciones de datos tienen una E / S de disco limitada, por lo que vale la pena considerarlo. Como un comentarista ya ha dado a entender, esta puede ser una aplicación ideal para una base de datos orientada a columnas, pero aún no he encontrado un producto orientado a columnas que sea lo suficientemente convencional como para apostar mi carrera. Este esquema se acerca bastante.
Desventajas
Aproximadamente la mitad de su espacio en disco se dedica a almacenar marcas de tiempo, cuando francamente 100 o 1000 de las tablas tendrán exactamente los mismos datos en la columna de marca de tiempo. (De hecho, este es un requisito si desea realizar uniones de tabla fáciles).
Almacenar nombres de tablas y realizar la búsqueda dinámica requiere una gran cantidad de complejidad de la aplicación y operaciones de cadena, lo que me hace temblar. Pero todavía parece mejor que las alternativas (discutidas a continuación).
Consideraciones:
Tenga cuidado de redondear en su campo de tiempo. Desea que sus valores sean lo suficientemente redondeados como para permitir combinaciones (si corresponde), pero lo suficientemente precisos como para no ser ambiguos.
Tenga cuidado con las zonas horarias y el horario de verano. Estos son difíciles de probar. Haría cumplir un requisito de UTC en el almacén de datos (lo que puede hacerme impopular) y manejaría las conversiones en la aplicación.
Variaciones:
Algunas variaciones que he considerado son:
Plegado de datos: si la serie de tiempo está igualmente espaciada, utilice una columna de marca de tiempo y (por ejemplo) 10 columnas de datos. La marca de tiempo ahora se refiere al tiempo de la primera columna de datos, y se supone que las otras columnas de datos están igualmente espaciadas entre esa marca de tiempo y la siguiente. Esto ahorra una gran cantidad de almacenamiento que se usaba anteriormente para almacenar marcas de tiempo, a un costo de consulta significativa y / o complejidad de la aplicación. Rango contiguo, las consultas de entidad única ahora requieren menos acceso al disco.
Multiplexación múltiple : si se sabe que varias series de tiempo usan la misma serie de tiempo, use una marca de tiempo y (por ejemplo) 10 columnas de datos como se describió anteriormente. Pero ahora cada columna representa una serie temporal diferente. Esto requiere una actualización de la tabla de metadatos, que no es una búsqueda en el nombre de la tabla y la columna. Se reduce el espacio de almacenamiento. Las consultas siguen siendo simples. Sin importar el rango contiguo, las consultas de una sola entidad ahora requieren mucho más acceso al disco.
Megatabla: Lleve al extremo el concepto de "multiplexación" y coloque todos los datos en una sola tabla, una vez series de tiempo por columna. Esto requiere grandes cantidades de acceso al disco para el rango contiguo, consultas de entidad única y es una pesadilla de mantenimiento. Por ejemplo, agregar una nueva entidad ahora requiere un comando MODIFICAR TABLA en muchas tablas de TB.
Para una discusión adicional sobre este formato, vea las diferentes respuestas en:
Demasiadas columnas en MySQL
Tabla completamente normalizada: en
lugar de usar muchas tablas de 2 columnas, puede usar una tabla de tres columnas, donde las columnas son tiempo, datos y valor. Ahora sus tablas de metadatos solo necesitan buscar valores de ID, en lugar de nombres de tablas o columnas, lo que permite insertar más lógica en las consultas SQL, en lugar de la capa de aplicación.
Aproximadamente 2/3 de almacenamiento ahora se consumen con las columnas de normalización, por lo que esto utilizará mucho espacio en disco.
Puede usar un orden de clave principal de (dataid, marca de tiempo) para consultas rápidas contiguas de una sola entidad. O bien, puede usar un orden de clave principal de (fecha y hora. Dataid) para inserciones más rápidas.
Sin embargo, incluso después de considerar estas variaciones, mi plan para mi próximo desarrollo es muchas tablas, dos columnas cada una. Eso, o el método que pronto publicará alguien más sabio que yo :).