1

假设您有一个程序每 30 秒将 (timestamp, stock_price) 记录到 SQL 数据库,并且您想要生成不同时间尺度的股票价格图。如果您绘制 1 小时范围内的测量值,则可以使用在此期间采集的所有 120 个样本。但是,如果您想绘制 1 年范围内的价格,您显然不想从数据库中提取超过 100 万个样本。最好从数据库中提取一些有代表性的样本子集。

这让我想起了计算机图形学中的细节层次技术——当你远离 3d 模型时,可以使用模型的低保真版本。

是否有表示数据库中详细信息级别信息的常用技术,或用于快速查询均匀分布的数据子集(例如,给我 2009 年 1 月的 100 个均匀分布的样本)?


到目前为止,我提出的解决方案是在数据库表中包含一个 level_of_detail 列。如果 level_of_detail=0,则该行包含一个瞬时样本。如果 level_of_detail=n,则该行包含最后 (sample_interval*(2^n)) 秒数据的平均值,并且此级别的行数为 1/(2^n)。该表在 (level_of_detail, timestamp) 上有一个索引,当您想要生成绘图时,您可以根据您想要的样本数量计算适当的 level_of_detail 值并使用该约束进行查询。缺点是:

  • 对于 N 个样本,该表需要存储 2*N 行
  • 客户端必须知道指定适当的 level_of_detail 约束
  • 当样本被添加到表中时,一些进程需要负责构建平均行
4

1 回答 1

2

对于 SQL Server,您可以使用ntile. 这会对数据集进行排序,然后将其分成 N 个不同的组,第一组返回 1,最后一组返回 N。

select  MIN(MeasureTime) as PeriodStart
,       MAX(MeasureTime) as PeriodEnd
,       AVG(StockPrice) as AvgStockPrice
from    (
        select  MeasureTime
        ,       StockPrice
        ,       NTILE(100) over (order by MeasureTime) as the_tile
        from    @t YourTable
        ) tiled
group by
        the_tile

这将返回正好 100 行。如果您有兴趣尝试查询,这里是测试数据的副本:

declare @t table (MeasureTime datetime, StockPrice int)
declare @dt date
set @dt = '2010-01-01'
while @dt < '2011-01-01'
    begin
    insert @t values (@dt, DATEDIFF(day,'2010-01-01',@dt))
    select @dt = DATEADD(day,1,@dt)
    end
于 2011-01-20T18:40:18.347 回答