¿Cuál es la mejor manera de almacenar datos históricos en SQL Server 2005/2008?


Mi ejemplo simplificado y artificial es el siguiente: -

Digamos que quiero medir y almacenar la temperatura (y otros valores) de todas las ciudades del mundo diariamente. Estoy buscando una forma óptima de almacenar los datos para que sea tan fácil obtener la temperatura actual en todas las ciudades, como lo es obtener toda la temperatura históricamente en una ciudad.

Es un problema bastante fácil de resolver, pero estoy buscando la mejor solución.

Los 2 principales las opciones que se me ocurren son las siguientes: -

Opción 1-La misma tabla almacena registros actuales e históricos

Almacene todos los registros actuales y archivados en la misma tabla.

Es decir,

CREATE TABLE [dbo].[WeatherMeasurement](
  MeasurementID [int] Identity(1,1) NOT Null,
  TownID [int] Not Null,
  Temp [int] NOT Null,
  Date [datetime] NOT Null,
)

Esto mantendría todo simple, pero ¿cuál sería la consulta más eficiente para obtener una lista de ciudades y la temperatura actual? ¿Esta escala una vez que la tabla tiene millones de filas? ¿Hay algo que ganar por tener algún tipo de bandera IsCurrent en el ¿mesa?

Opción 2-Almacenar todos los registros de archivo en una tabla separada

Habría una tabla para almacenar las mediciones actuales en vivo en

CREATE TABLE [dbo].[WeatherMeasurement](
  MeasurementID [int] Identity(1,1) NOT Null,
  TownID [int] Not Null,
  Temp [int] NOT Null,
  Date [datetime] NOT Null,
)

Y una tabla para almacenar la fecha archivada histórica (insertada por un disparador quizás)

CREATE TABLE [dbo].[WeatherMeasurementHistory](
  MeasurementID [int] Identity(1,1) NOT Null,
  TownID [int] Not Null,
  Temp [int] NOT Null,
  Date [datetime] NOT Null,
)

Esto tiene las ventajas de mantener los principales datos actuales magros, y muy eficiente para consultar, a expensas de hacer el esquema más complejo y la inserción de datos más caro.

¿Cuál es la mejor opción? ¿Hay algo mejor opciones no he mencionado?

NOTA: He simplificado el esquema para ayudar a enfocar mejor mi pregunta, pero asumo que habrá una gran cantidad de datos insertados cada día (100,000 s de registros), y los datos están actualizados por un día. Es tan probable que se consulten los datos actuales como los históricos.

Author: Tom H, 2008-11-17

7 answers

DEPENDE de los patrones de uso de las aplicaciones... Si los patrones de uso indican que los datos históricos se consultarán con más frecuencia que los valores actuales, colóquelos todos en una tabla... Pero si las consultas históricas son la excepción (o menos del 10% de las consultas), y el rendimiento de la consulta de valor actual más común sufrirá al poner todos los datos en una tabla, entonces tiene sentido separar esos datos en su propia tabla...

 13
Author: Charles Bretana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-17 16:23:54

Mantendría los datos en una tabla a menos que tenga un sesgo muy serio para los datos actuales (en uso) o los datos históricos (en volumen). Un índice compuesto con FECHA + TOWNID (en ese orden) eliminaría el problema de rendimiento en la mayoría de los casos (aunque claramente no tenemos los datos para estar seguros de esto en este momento).

La única cosa que me preguntaría es si alguien querrá datos de los datos actuales e históricos de una ciudad. Si es así, acaba de crear al menos una nueva vista para preocupación y posible problema de rendimiento en esa dirección.

Esta es desafortunadamente una de esas cosas en las que puede necesitar perfilar sus soluciones contra datos del mundo real. Personalmente, he utilizado índices compuestos como los especificados anteriormente en muchos casos, y sin embargo, hay algunos casos extremos en los que he optado por dividir el historial en otra tabla. Bueno, en realidad otro archivo de datos, porque el problema era que el historial era tan denso que creé un nuevo archivo de datos para él solo para evitar la hinchazón de todo el conjunto de archivos de datos primarios. Los problemas de rendimiento rara vez se resuelven por la teoría.

Recomendaría leer las sugerencias de consulta para el uso de índices y "cubriendo índices" para obtener más información sobre problemas de rendimiento.

 5
Author: Godeke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-17 16:30:11

Su tabla es muy estrecha y probablemente funcionaría en una sola tabla correctamente indexada que nunca superaría la capacidad de SQL Server en un modelo OLTP normalizado tradicional, incluso para millones y millones de filas. Incluso con el modelo de tabla dual, las ventajas se pueden mitigar mediante el uso de particiones de tabla en SQL Server. Por lo tanto, no tiene mucho que recomendar sobre el modelo de mesa única. Este sería un escenario tipo Inmon o "Almacén de Datos empresariales".

En mucho más grande escenarios, transferiría los datos a un almacén de datos (modelado con un modelo dimensional al estilo de Kimball) de forma regular y simplemente purgaría los datos en vivo-en algunos escenarios simples como el suyo, podría efectivamente haber NO datos en vivo - todo va directamente al almacén. El modelo dimensional tiene muchas ventajas al cortar datos de diferentes maneras y almacenar un gran número de hechos con una variedad de dimensiones. Incluso en el escenario del almacén de datos, a menudo las tablas de hechos son dividido por fecha.

Puede parecer que sus datos no tienen esto (Ciudad y Fecha son sus únicas dimensiones explícitas), sin embargo, en la mayoría de los almacenes de datos, las dimensiones pueden copo de nieve o puede haber redundancia, por lo que habría otras dimensiones sobre el hecho almacenado en el momento de la carga en lugar de copo de nieve para una mayor eficiencia, como Estado, Código postal, WasItRaining, IsStationUrban (artificial).

Esto puede parecer tonto, pero cuando comience a extraer los datos para obtener resultados en almacenes de datos, esto hace que hacer preguntas como-en un día con lluvia en entornos urbanos, ¿cuál fue la temperatura promedio en Maine? - solo que un poco más fácil de conseguir sin unirse a un montón de tablas (es decir, no requiere mucha experiencia en su modelo normalizado y se realiza muy rápidamente). Algo así como estadísticas inútiles en el béisbol, pero algunas aparentemente resultan útiles.

 3
Author: Cade Roux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-17 16:37:54

Sugiero que se mantenga en la misma tabla ya que los datos históricos se consultan con la misma frecuencia. A menos que vaya a agregar muchas más columnas a la tabla.

Cuando el tamaño se convierte en un problema, puede particionarlo por década y tener un procedimiento almacenado que una las filas solicitadas.

 1
Author: Gordon Bell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-17 16:20:29

Otra alternativa podría ser ir por una tabla para todos los datos y tener una vista de la temperatura actual. Esto no ayudará al rendimiento, pero bien podría ayudar a la legibilidad/mantenibilidad. Incluso podría optar por una vista indexada para mejorar el rendimiento si tiene la versión adecuada de sql .

 1
Author: PhilHoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-17 16:26:37

Usaría una sola tabla con vistas de índice para proporcionarme la información más reciente. SQL 2005 y 2008 server están diseñados para el almacenamiento de datos, por lo que debe funcionar bien bajo esta condición.

Si tiene un patrón de datos que requiere escribir en la base de datos a menudo, entonces la mejor opción sería tener una tabla activa y una tabla de archivo que actualice por lotes en algún intervalo.

 0
Author: Aaron Fischer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-17 16:37:27

Si almacena todo en una tabla, cómo va a crear una base de datos relacional.

Ejemplo:

Id--------------GUID----PK

Record_id - - - - - - - GUID

Cada vez que se inserte un nuevo registro, [id] cambiará, pero [record_id] permanecerá igual. Ahora, si tienes que vincularlo con la tabla de direcciones ¿cómo vas a hacer eso?

 0
Author: Talha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-27 08:11:56