如何使用PostgreSQL限制特定表中的行数?

时间:2013-07-08 01:53:24

标签: database postgresql limit

我们正试图以最简单的方式限制SIP服务器上的注册数量。更具体地说,我们决定限制users表中的条目数。服务器正在运行PostgreSQL作为DBMS。

是否可以限制特定表格中的条目数量?例如,我们希望将行数限制为100,除非删除一些旧条目,否则我们不希望该表上有任何条目。

请告知。

3 个答案:

答案 0 :(得分:3)

这是可能的,但这是解决这个问题的一种非常糟糕的方式。您必须创建一个触发器,在表上获取EXCLUSIVE锁,然后在允许提交之前检查表上的count(),或者,如果插入会添加太多行,则执行RAISE EXCEPTION 1}}中止事务。

实际上有两个触发器;执行BEFORE INSERT OR DELETELOCK TABLE ... IN EXCLUSIVE MODE触发器的AFTER INSERT触发器,用于检查表的COUNT并决定是否引发异常。简单的BEFORE触发器是不够的,因为它无法判断INSERT是否可能添加多行,因此多值插入或INSERT ... SELECT可能会导致超出限制

其他想要更新表的会话必须等到执行INSERT的事务完成。如果应用程序不是为此设计的,则很容易导致死锁。

当应用程序INSERT进入会话表时,应用程序可能不会出现错误,因此它可能无法正常处理。它不太可能给用户一个整洁的“太多注册”错误。

我没有为此编写一个示例触发器,因为我认为这是一个绝对可怕的想法。如果要设置SIP服务器中可注册用户数的限制,请相应地配置SIP服务器。如果没有这样的配置选项,请修改它以添加一个或使用 具有的一个不同的SIP服务器。

答案 1 :(得分:1)

有点晚了,但我们遇到了同样的问题,所以我想分享我的解决方案。 我假设 user 表有一些父键或一些关系。 您可以通过锁定父记录并检查满足您条件的用户总数来在事务中完成此操作。如果它小于 limit,那么您可以插入新用户。如果您尝试在另一笔交易中这样做,您将被锁定,直到第一个完成,或者您可以使用 SKIP LOCKED 获得空结果并完成交易。

代码:

BEGIN;
SELECT * FROM user_parent WHERE /* condition */ FOR UPDATE;
SELECT count(1) FROM "user" WHERE /* condition */;
// check count in your code
// if count <= limit; then continue; else ROLLBACK
// INSERT your users
COMMIT;

答案 2 :(得分:-1)

像往常一样,谷歌把我带到这里:

CONSTRAINT nomore_than_x_rows
CHECK( table_id < 101 ); 

鉴于id是serial

类型