以高效方式存储每小时数据

Store hourly data efficient way

需要在 SQL Server 2016 中存储每小时数据并进行检索。这是一个 OLTP 数据库。

我举个例子说明一下:我们需要采集一个国家每个城市的温度,并按小时进行存储。什么是最好和最有效的设计来做到这一点。数据将存储一年然后存档

这是我的计划。有人可以评论一下,让我知道这种方法是否合适吗?

CREATE TABLE [dbo].[CityMaster]
(
    [CityId] [int] NULL,
    [CityName] [varchar](300) NULL
) ON [PRIMARY]

--OPTION 1
CREATE TABLE [dbo].[WeatherData]
(
    [Id] [bigint] NULL,
    [CityId] [int] NULL,
    [HrlyTemp] [decimal](18, 1) NULL,
    [CapturedTIme] [datetime] NULL
) ON [PRIMARY]
GO

--OPTION2
CREATE TABLE [dbo].[WeatherData_JSon] 
(
    [Id] [bigint] NULL,
    [CityId] [int] NULL,
    [Month] [varchar](50) NULL,
    [Hrlytemp] [nvarchar](max) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

选项2不可行。
选项 1 更好。

我认为 HrlyTemp 列的大小应为 [decimal](4, 1)[decimal](5, 1) 最大值。

如果你处理世界上所有城市的数据,基于世界上约 1000 个城市的近似值。

那么您每年需要存储 365*24*1000 = 8,760,000 ~ 9M 行。为了安全起见,我们可以假设我们必须存储 10M 数据。

SQL 服务器可以。

CREATE TABLE [dbo].[WeatherData]
(
    [Id] [bigint] NULL,
    [CityId] [int] NULL,
    [HrlyTemp] [decimal](18, 1) NULL,
    [CapturedTIme] [datetime] NULL,
    [DailyTempRepo] nvarchar(max) * record create and update per day
) ON [PRIMARY]
GO
* you can normalize more your table.

how to store data in DailyTempRepo column as json :

[{"TempDate":"2021-03-06","CityId":"2","CapturedTIme":"09:30","HrlyTemp":"70"},
{"TempDate":"2021-03-06","CityId":"2","CapturedTIme":"10:30","HrlyTemp":"78"},
{"TempDate":"2021-03-06","CityId":"2","CapturedTIme":"11:30","HrlyTemp":"81"}]

在某种程度上,这取决于数据的使用方式。最自然的解决方案是调整第一个选项并使用分区 table:

CREATE TABLE [dbo].CityHourlyTemperatures (
    Id bigint NULL,
    CityId int NULL,
    HrlyTemp decimal(6, 1) NULL,
    CapturedTIme datetime NULL
) ;

请注意,我将名称更改为似乎更贴切名称的名称。

即使在全球变暖的情况下,我认为 4 或 5 位温度精度也足够了——18 位太过分了。

此处每行8 + 4 + 5 + 8字节= 25字节(如果有对齐限制,可能会四舍五入)。一年大约有 8,766 小时。所以,如果你有 100 个城市,每年不到一百万行,每年只有几十兆字节。

这是非常可行的,但您可能要考虑对 table 进行分区——较旧的分区可以像“存档”一样使用。

您的第二个选项将温度存储为 blob。这仅在一种情况下有意义:您不关心温度,但您需要 return 将数据发送到关心温度的应用程序。

顾名思义,您希望将值存储为 JSON。与使用本机类型存储数据相比,这通常需要 更多 的开销——而且通常效率较低。 JSON 对于某些类型的数据非常强大和有用,尤其是稀疏数据。但是,您的数据非常相关,可以以关系格式存储。

如果你想节省space,你可以考虑以下方法:

  • hourId 列替换 datetime 值。如果您只需要几年的数据,这可能是一个 shortint。
  • 删除 id 列并将 cityid/hourid 定义为主键。

但是,从您的数据量来看,似乎没有必要采用这种方法。