Ответы пользователя по тегу Партиционирование и шардинг баз данных
  • Нужна помощь с партицированием в MySQL?

    @galaxy
    По-моему, там максимум два уровня (партиции и субпартиции).

    Можете, в конце концов, сделать RANGE партиции по дате на уровне месяца (и субпартиции по серверу):
    PARTITION BY RANGE COLUMNS(datetime) (
        PARTITION 2019_01 VALUES LESS THAN ('2019-02-01'),
        PARTITION 2019_02 VALUES LESS THAN ('2019-03-01'),
        ...
    );
    Ответ написан
    1 комментарий
  • Обновление партицированных таблиц в PostgreSQL?

    @galaxy
    Нетипичная задача, обычно данные не таскают из партиции в партицию.
    Тем не менее, ничего сложного нет. Делаете BEFORE UPDATE FOR EACH ROW триггер на дочерние таблицы. При апдейте на родительской таблице автоматически будет сделана попытка проапдейтить соответствующую строку дочерней и вызовется триггер. Триггерная функция должна проверить, должны ли данные остаться в текущей партиции (и в этом случае ничего не трогать) или, соответственно, удалить их из текущей и перенести в нужную. Короткий пример:
    -- ключ нужен, чтобы точно идентифицировать строку таблицы
    create table t(id int primary key);
    
    -- партиции, без триггеров на INSERT
    create table t1(primary key (id), check(id > 0 and id <= 10)) inherits(t);
    create table t2(primary key (id), check(id > 10 and id <= 20)) inherits(t);
    
    insert into t1 values (1), (4);
    insert into t2 values (15);
    
    test=# select * from t;
     id
    ----
      1
      4
     15
    
    test=# select * from t1;
     id
    ----
      1
      4
     
    test=# select * from t2;
     id
    ----
     15
    
    
    create or replace function t_tg_proc() returns trigger as $$
    begin
    	raise notice 't_tg_proc called';
    	if TG_TABLE_NAME = 't1' and NEW.id > 10 then
    		delete from t1 where id = OLD.id; -- без primary key можно удалить лишнего
    		insert into t2 values (NEW.*);
    		return null; -- проигнорировать UPDATE
    	end if;
    	
    	if TG_TABLE_NAME = 't2' and NEW.id <= 10 then
    		delete from t2 where id = OLD.id;
    		insert into t1 values (NEW.*);
    		return null; -- проигнорировать UPDATE
    	end if;
    	
    	return new; -- нормальный UPDATE
    end $$ language plpgsql;
    
    create trigger t1_tg before update on t1 for each row execute procedure t_tg_proc();
    create trigger t2_tg before update on t2 for each row execute procedure t_tg_proc();
    
    -- обычный UPDATE
    update t set id = 5 where id = 4;
    ЗАМЕЧАНИЕ:  t_tg_proc called
    UPDATE 1
    
    select * from t;
     id
    ----
      1
      5
     15
     
    -- необычный UPDATE
    update t set id = 11 where id = 1;
    ЗАМЕЧАНИЕ:  t_tg_proc called
    UPDATE 0
    
    select * from t;
     id
    ----
      5
     15
     11
     
    test=# select * from t1;
     id
    ----
      5
     
    test=# select * from t2;
     id
    ----
     15
     11
    
    Ответ написан
    1 комментарий