No me importan las diferencias generales entre SQL y NoSQL (o sus diferencias tradicionales).
Actualmente estoy buscando alterar el almacenamiento de nuestras series temporales internas. Todos contienen datos financieros de varias fuentes diferentes. Actualmente, estamos almacenando nuestros datos en una base de datos propietaria. Es mucho NoSQL, que tiene su propio lenguaje de consulta.
Estoy interesado en el aporte de la comunidad: ¿Cómo almacenaría los datos en una base de datos SQL? ¿Qué ventajas hay para usar SQL sobre un NoSQL, específicamente para series de tiempo? ¿Estoy loco por considerar almacenar esto en SQL?
Nuestro conjunto de datos consta de millones de series temporales, de las cuales alrededor del 10% contienen millones de registros cada una. Las series temporales se organizan jerárquicamente: / Mercado / Instrumento / Valor / Frecuencia, donde:
- El mercado es un intercambio de valores, etc., básicamente una colección de instrumentos, generalmente instrumentos similares.
- El instrumento es un instrumento. Esto podría ser un indicador (Brent Crude), una equidad (GOOG), etc.
- El valor es uno de los múltiples tipos de datos para un instrumento. Esto podría ser un cierre, alto, bajo, etc.
- La frecuencia es la frecuencia de los valores de una serie de tiempo particular. Semanal, diario, mensual, tick, arbitrario, etc.
¿Cómo se almacenarían los datos en una base de datos SQL? Una tabla grande (quizás dividida por algo), una tabla por mercado o instrumento, una tabla por serie temporal.
Gracias de antemano.
Respuestas:
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:
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 :).
fuente
Use MongoDB, puede crear colecciones sobre la marcha muy rápidamente. Mire cómo organizar sus datos en bases de datos separadas y colecciones dentro de esas bases de datos. Considere cuánta memoria necesitaría para tratar de mantener cada fragmento dentro de la memoria del sistema, si necesita una recuperación rápida. Es tonto seguir con una solución interna, si hay algo más fresco que evolucionará en la línea que necesita. Suena como una buena iniciativa.
fuente