如何在postgresql中写一个关于最大行数的约束?

jej*_*eje 20 sql postgresql constraints

我认为这是一个非常普遍的问题.

我有桌子user(id INT ...)和桌子photo(id BIGINT, owner INT).所有者是参考user(id).

我想在桌面照片中添加一个约束,这样就可以防止10张照片进入每个用户的数据库.

写这个的最好方法是什么?

谢谢!

Ale*_*tec 26

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();
Run Code Online (Sandbox Code Playgroud)

我包括表,以避免出现两个并发tansactions只能算作照片用户锁定,看到当前计为1以下的限制,那么这两个插入,这将导致你超过极限去1.如果您不关心这一点,最好删除锁定,因为它可能成为许多插入/更新的瓶颈.


Qua*_*noi 10

您不能在表声明中编写这样的约束.

有一些解决方法:

  • 创建一个触发器,用于检查每个用户的照片数量
  • 创建一个photo_order保持照片,制作(user_id, photo_order) UNIQUE和添加顺序的列CHECK(photo_order BETWEEN 1 AND 10)

  • 然后,您是否不必在照片顺序上强制唯一性?怎么做? (2认同)