Citus触发器实现方法

触发器

citus不支持标准意义上的触发器,但是可以通过特定方法绕过去,称为wordaround.

单分布表触发器

示例中将自动触发author_name列为用户的名字
* 创建表

CREATE TABLE events (
  id bigserial PRIMARY KEY,
  description text NOT NULL,
  author name NOT NULL
);
SELECT create_distributed_table('events', 'id');
  • 在work上创建触发器所用的存储过程
SELECT run_command_on_workers($cmd$
  CREATE OR REPLACE FUNCTION set_author() RETURNS TRIGGER AS $$
    BEGIN
      NEW.author := current_user;
      RETURN NEW;
    END;
  $$ LANGUAGE plpgsql;
$cmd$);
  • 设置触发器给引用的表
SELECT `run_command_on_placements`(
  'events',
  $cmd$
    CREATE TRIGGER events_set_author BEFORE INSERT OR UPDATE ON %s
      FOR EACH ROW EXECUTE PROCEDURE set_author()
  $cmd$
);

双分布表触发器(必须共址表)

触发器所用的两个表必须共址,向little_vals插入val数据时,触发向big_vals插入双倍数据。
* 创建触发器所需要的表

CREATE TABLE little_vals (key int, val int);
CREATE TABLE big_vals    (key int, val int);
SELECT create_distributed_table('little_vals', 'key');
SELECT create_distributed_table('big_vals',    'key')
  • 在work上创建触发器所用的存储过程
SELECT run_command_on_workers($cmd$
  CREATE OR REPLACE FUNCTION embiggen() RETURNS TRIGGER AS $$
    BEGIN
      IF (TG_OP = 'INSERT') THEN
        EXECUTE format(
          'INSERT INTO %s (key, val) SELECT ($1).key, ($1).val*2;',
          TG_ARGV[0]
        ) USING NEW;
      END IF;
      RETURN NULL;
    END;
  $$ LANGUAGE plpgsql;
$cmd$)
  • 设置触发器所引用的表
SELECT `run_command_on_colocated_placements`(
  'little_vals',
  'big_vals',
  $cmd$
    CREATE TRIGGER after_insert AFTER INSERT ON %s
      FOR EACH ROW EXECUTE PROCEDURE embiggen(%s)
  $cmd$
)

双参考表触发器

参考表非共址,但是方法更简单
* 创建需要的表

CREATE TABLE insert_target (
  value text
);
CREATE TABLE audit_table(
  author name NOT NULL,
  value text
);
SELECT create_reference_table('insert_target');
SELECT create_reference_table('audit_table')
  • 创建存储过程
SELECT run_command_on_placements(
  'audit_table',
  $cmd$
    CREATE OR REPLACE FUNCTION process_audit() RETURNS TRIGGER AS $$
      BEGIN
        INSERT INTO %s (author,value)
          VALUES (current_user,NEW.value);
        RETURN NEW;
      END;
    $$ LANGUAGE plpgsql;
  $cmd$
)
  • 设置触发器所引用的表
SELECT run_command_on_placements(
  'insert_target',
  $cmd$
    CREATE TRIGGER emp_audit
    AFTER INSERT OR UPDATE ON %s
      FOR EACH ROW EXECUTE PROCEDURE process_audit();
  $cmd$
)
文章浏览总量 1,254 次

要发表评论,您必须先登录