有什么方法可以在PostgreSQL数据库上设置最大行数?

时间:2018-11-07 18:55:09

标签: postgresql heroku-postgres

问题很简单。有什么方法可以动态限制Postgres数据库的最大行数?

我不认为有可能,直到我看到Heroku做到了。经过研究,我找到了一种使用触发器的方法:

CREATE OR REPLACE FUNCTION check_number_of_row()
RETURNS TRIGGER AS
$body$
BEGIN
    -- replace 100 by the number of rows you want
    IF (SELECT count(*) FROM your_table) > 100
    THEN 
        RAISE EXCEPTION 'INSERT statement exceeding maximum number of rows for 
this table' 
    END IF;
END;
$body$
LANGUAGE plpgsql;

CREATE TRIGGER tr_check_number_of_row 
BEFORE INSERT ON your_table
FOR EACH ROW EXECUTE PROCEDURE check_number_of_row();

但这不是我所需要的。它将表的行数限制为STATIC的最大值,因此我将不得不遍历所有表,并且看起来很杂乱。而且我什至都没有想过动态设置此最大数量的方法。

我考虑过要进行每天/每周的cron工作,以检查所有数据库,计算总行数,并查看其是否在限制范围内,但是如果有更有效的方法,我会接受。

2 个答案:

答案 0 :(得分:2)

由于SELECT count(*)是一项非常昂贵的操作,因此我认为在每次数据更改时都运行它不是一个好主意。此外,行数不会告诉您表格的大小。

我的方法是像这样使用使用pg_total_relation_size()的触发器:

CREATE OR REPLACE FUNCTION size_trig() RETURNS trigger
   LANGUAGE plpgsql AS
$$BEGIN
   IF pg_total_relation_size(TG_RELID) > (TG_ARGV[0])::bigint THEN
      RETURN NULL;
   ELSE
      RETURN NEW;
   END IF;
END;$$;

CREATE TRIGGER size_trig BEFORE INSERT ON big
   FOR EACH ROW
   EXECUTE PROCEDURE size_trig(819200);

这会将包括索引和TOAST表在内的表的总大小限制为100个块,并且相对便宜。

您仍然必须为要检查的所有表定义触发器,但是无法修改PostgreSQL。

您看到可以为每个表动态设置限制。您还可以提出一种使用查找表进行大小限制的解决方案。

答案 1 :(得分:1)

  

直到我看到Heroku做到了,我才认为这是不可能的。

这并不完全准确。 Heroku的爱好层的数据库行限制没有硬性限制。换句话说,当您在hobby-dev或hobby-basic中超过10k或10M行时,没有什么会立即停止写入。 Heroku通过电子邮件提供了一个7天的窗口,使计数不超过配额,否则将阻止写访问。如果您只是想抬起头来进行相应调整,那么他们已经有了一个不错的系统。

但是,关于您的问题,考虑到Heroku Postgres(尤其是对于业余数据库而言)已被相当严格地锁定,我认为您不会拥有实现所要执行的操作所需的控制级别,而又不会使其变得更混乱您有什么问题。