在 timescaleDB postgresql 上的 CAGG 之上进行黑客攻击以实现(连续聚合)CAGG

hacking to achieve (continuous aggregate) CAGG on top of CAGG on timescaleDB postgresql

只是想跟进这个话题https://github.com/timescale/timescaledb/issues/1400,是否可以在另一个连续聚合之上创建一个连续聚合? (通过执行一些黑客攻击?)

我打算将分时数据插入数据库(可能每0.1s),并在1s、1min、1hour、1day、1个月、1年、10年上进行连续聚合。根据我目前对 CAGG 的理解,从时间上看,在 10 年内执行聚合将花费 ~3600* 24* 365* 10 倍于 1 秒的 CAGG,但如果我们在 CAGG 之上执行 CAGG(通过创建新的超表来跟踪变化进行黑客攻击以前的物化视图),我们可能会以指数方式加速......

我的想法有效吗?因为我之前没有在postgresql上写过任何触发函数...

这是一个简单的原型,您可以破解自己来喂养第二个超级table,就像在另一个之上的连续聚合:

-- DROP TABLE ticks CASCADE;
-- DROP TABLE ohlc_1s CASCADE;
CREATE TABLE ticks ( time TIMESTAMP NOT NULL, symbol varchar, price decimal, volume int);
CREATE TABLE ohlc_1s ( time TIMESTAMP NOT NULL, symbol varchar, o decimal, h decimal, l decimal, c decimal, v int);
SELECT create_hypertable('ticks', 'time');
SELECT create_hypertable('ohlc_1s', 'time');

您还可以使用触发器来喂 ohlc_1s table:

CREATE OR REPLACE FUNCTION feed_ohlc_1s() RETURNS trigger AS
$BODY$
DECLARE
    last_time timestamp;
BEGIN
   SELECT time_bucket('1 second', time) INTO last_time
   FROM ticks WHERE symbol = NEW.symbol
   ORDER BY time DESC LIMIT 1;

   -- When turn next second
   IF NEW.time - last_time >= INTERVAL '1 second' THEN
      INSERT INTO ohlc_1s (time, symbol, o, h, l, c, v)
        SELECT time_bucket('1 second', time) as time,
          symbol,
          FIRST(price, time) as open,
          MAX(price) as high,
          MIN(price) as low,
          LAST(price, time) as close,
          SUM(volume) as volume FROM ticks
        GROUP BY 1, 2 ORDER BY 1 DESC LIMIT 1;
  END IF;
  RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;

CREATE TRIGGER feed_ohlc_every_new_second
               BEFORE INSERT
               ON ticks
               FOR EACH ROW
               EXECUTE PROCEDURE feed_ohlc_1s();

下面是一些插入示例:

INSERT INTO ticks VALUES 
('2021-08-26 10:09:00.01'::timestamp, 'SYMBOL', 10.1, 100),
('2021-08-26 10:09:00.08'::timestamp, 'SYMBOL', 10.0, 100),
('2021-08-26 10:09:00.23'::timestamp, 'SYMBOL', 10.2, 100),
('2021-08-26 10:09:00.40'::timestamp, 'SYMBOL', 10.3, 100);
table ticks;
table ohlc_1s;

如您所见,当我们处于同一秒时,它不会生成任何新数据:

┌────────────────────────┬────────┬───────┬────────┐
│          time          │ symbol │ price │ volume │
├────────────────────────┼────────┼───────┼────────┤
│ 2021-08-26 10:09:00.01 │ SYMBOL │  10.1 │    100 │
│ 2021-08-26 10:09:00.08 │ SYMBOL │  10.0 │    100 │
│ 2021-08-26 10:09:00.23 │ SYMBOL │  10.2 │    100 │
│ 2021-08-26 10:09:00.4  │ SYMBOL │  10.3 │    100 │
└────────────────────────┴────────┴───────┴────────┘
(4 rows)

┌──────┬────────┬───┬───┬───┬───┬───┐
│ time │ symbol │ o │ h │ l │ c │ v │
├──────┼────────┼───┼───┼───┼───┼───┤
└──────┴────────┴───┴───┴───┴───┴───┘
(0 rows)

现在插入更多 2 秒的刻度:

INSERT INTO ticks VALUES 
('2021-08-26 10:09:01.02'::timestamp, 'SYMBOL', 10.0, 100),
('2021-08-26 10:09:01.04'::timestamp, 'SYMBOL', 14.0, 200),
('2021-08-26 10:09:01.42'::timestamp, 'SYMBOL', 12.3, 200),
('2021-08-26 10:09:01.62'::timestamp, 'SYMBOL', 8.3, 200),
('2021-08-26 10:09:02.80'::timestamp, 'SYMBOL', 9.0, 500);
table ticks;
table ohlc_1s;

这是输出:

┌────────────────────────┬────────┬───────┬────────┐
│          time          │ symbol │ price │ volume │
├────────────────────────┼────────┼───────┼────────┤
│ 2021-08-26 10:09:00.01 │ SYMBOL │  10.1 │    100 │
│ 2021-08-26 10:09:00.08 │ SYMBOL │  10.0 │    100 │
│ 2021-08-26 10:09:00.23 │ SYMBOL │  10.2 │    100 │
│ 2021-08-26 10:09:00.4  │ SYMBOL │  10.3 │    100 │
│ 2021-08-26 10:09:01.02 │ SYMBOL │  10.0 │    100 │
│ 2021-08-26 10:09:01.04 │ SYMBOL │  14.0 │    200 │
│ 2021-08-26 10:09:01.42 │ SYMBOL │  12.3 │    200 │
│ 2021-08-26 10:09:01.62 │ SYMBOL │   8.3 │    200 │
│ 2021-08-26 10:09:02.8  │ SYMBOL │   9.0 │    500 │
└────────────────────────┴────────┴───────┴────────┘
(9 rows)

┌─────────────────────┬────────┬──────┬──────┬──────┬──────┬─────┐
│        time         │ symbol │  o   │  h   │  l   │  c   │  v  │
├─────────────────────┼────────┼──────┼──────┼──────┼──────┼─────┤
│ 2021-08-26 10:09:00 │ SYMBOL │ 10.1 │ 10.3 │ 10.0 │ 10.3 │ 400 │
│ 2021-08-26 10:09:01 │ SYMBOL │ 10.0 │ 14.0 │  8.3 │  8.3 │ 700 │
└─────────────────────┴────────┴──────┴──────┴──────┴──────┴─────┘
(2 rows)

可能将其链接到更大的时间范围内也会使其变得非常简单。