PostgreSQL: Как разработать схему БД для временных рядов с большим количеством вставок и удалений - PullRequest
0 голосов
/ 11 февраля 2020

Мне нужно, чтобы данные были ВСТАВЛЕНЫ на основе даты и времени (достаточно мелкой детализации), но я также УДАЛЮ все строки по мере их обработки

Так что вы догадались, что-то будет выполнено, но не сейчас, поэтому отложенные действия, я полагаю, вы могли бы сказать.

expiry | action
2020-01-30T10:45 | Action1
2020-01-30T10:45 | Action2
2020-02-05T00:00 | Action3
2020-02-05T00:00 | Action4

У меня будут миллионы строк в определенные дни и часы дня, и ни одной - в другие. Я хотел бы сделать что-то вроде

SELECT expiry,action FROM <table> WHERE expiry > '2020-01-30T00:00' AND expiry < '2020-01-30T23:59'

, а затем в конце концов я бы сделал что-то вроде

DELETE FROM <table> WHERE expiry > '2020-01-30T00:00' AND expiry < '2020-01-30T23:59'

или даже

DELETE FROM <table> WHERE expiry < '2020-01-30T23:59'

Какой лучший способ смоделировать это в Postgres? И что мне нужно остерегаться?

1 Ответ

0 голосов
/ 11 февраля 2020

Посмотрите, можете ли вы использовать Timescaledb, некоторые тесты и информацию здесь:

Ссылка

Есть несколько других опций, с которыми это можно сделать в PG также, но на всякий случай, если PG - не единственное, на что вы смотрите.

EDIT


Создайте функцию для создания разделов и индексов

drop function test_partition_creation ();

CREATE OR REPLACE FUNCTION test_partition_creation( DATE, DATE )
returns void AS $$
DECLARE
    create_query text;
    index_query text;
BEGIN
    FOR create_query, index_query IN SELECT
            'create table test_'
            || TO_CHAR( d, 'YYYY_MM' )
            || ' ( check( time >= date '''
            || TO_CHAR( d, 'YYYY-MM-DD' )
            || ''' and time < date '''
            || TO_CHAR( d + INTERVAL '1 month', 'YYYY-MM-DD' )
            || ''' ) ) inherits ( test );',
            'create index test_'
            || TO_CHAR( d, 'YYYY_MM' )
            || '_time on test_' 
            || TO_CHAR( d, 'YYYY_MM' )
            || ' ( time );'
        FROM generate_series( $1, $2, '1 month' ) AS d
    LOOP
        EXECUTE create_query;
        EXECUTE index_query;
    END LOOP;
END;
$$
language plpgsql;

Создание раздела за заданный период времени

SELECT test_partition_creation( '2010-01-01', '2012-01-01' ) ;

Создание функции триггера

    CREATE OR REPLACE FUNCTION test_partition_function()
    RETURNS TRIGGER AS $$
    BEGIN
        EXECUTE 'insert into test_'
            || to_char( NEW.TIME, 'YYYY_MM' )
            || ' values ( $1, $2 )' USING NEW.id, NEW.TIME ;
        RETURN NULL;
    END;

$$
LANGUAGE plpgsql;

Активация триггера

CREATE TRIGGER test_partition_trigger
    BEFORE INSERT
    ON test
    FOR each ROW
    EXECUTE PROCEDURE test_partition_function() ;

См. Ссылка для получения более подробной информации.

...