sql - 如何在 postgresql 中编写关于最大行数的约束?

标签 sql postgresql constraints

我认为这是一个很常见的问题。

我有一张表 user(id INT ...) 和一张表 photo(id BIGINT, owner INT)。 owner 是对 user(id) 的引用。

我想为表格照片添加一个约束条件,以防止超过 10 张照片被输入到每个用户的数据库中。

最好的写法是什么?

谢谢!

最佳答案

Quassnoi 是对的;触发器将是实现这一目标的最佳方式。

代码如下:

CREATE OR REPLACE FUNCTION enforce_photo_count() RETURNS trigger AS $$
DECLARE
    max_photo_count INTEGER := 10;
    photo_count INTEGER := 0;
    must_check BOOLEAN := false;
BEGIN
    IF TG_OP = 'INSERT' THEN
        must_check := true;
    END IF;

    IF TG_OP = 'UPDATE' THEN
        IF (NEW.owner != OLD.owner) THEN
            must_check := true;
        END IF;
    END IF;

    IF must_check THEN
        -- prevent concurrent inserts from multiple transactions
        LOCK TABLE photos IN EXCLUSIVE MODE;

        SELECT INTO photo_count COUNT(*) 
        FROM photos 
        WHERE owner = NEW.owner;

        IF photo_count >= max_photo_count THEN
            RAISE EXCEPTION 'Cannot insert more than % photos for each user.', max_photo_count;
        END IF;
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;


CREATE TRIGGER enforce_photo_count 
    BEFORE INSERT OR UPDATE ON photos
    FOR EACH ROW EXECUTE PROCEDURE enforce_photo_count();

我加入表锁定是为了避免两个并发交易为用户计算照片数量的情况,看到当前计数低于限制 1,然后都插入,这会导致您超过限制 1。如果这不是您关心的问题,最好删除锁定,因为它可能成为许多插入/更新的瓶颈。

关于sql - 如何在 postgresql 中编写关于最大行数的约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1743439/

相关文章:

postgresql - 连接本地主机 Postgres 数据库

java - choco 中的复杂变量

mysql - 错误 1452 : Cannot add or update a child row: a foreign key constraint fails

MySQL选择多个外键

sql - 表定义中的列别名?

sql - 查询执行速度 PostgreSQL 8.1 与 PostgreSQL 9.2

mysql - SQL根据表B数据组合(删除重复)表A?

swift - 以编程方式按钮自动布局?

ios - 在 iOS 中使用自动布局并排放置多个图标的最佳方式

mysql - 嵌套 SQL 查询在 MySql 中以不同形式运行时抛出错误