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

如何编写关于postgresql中最大行数的约束?,sql,postgresql,constraints,Sql,Postgresql,Constraints,我认为这是一个相当普遍的问题 我有一个表userid INT。。。表photoid BIGINT,owner INT.owner是对userid的引用 我想给表photo添加一个约束,以防止每个用户有超过10张照片进入数据库 写这篇文章最好的方式是什么 谢谢 不能在表声明中写入这样的约束 有一些变通办法: 创建一个触发器,用于检查每个用户的照片数量 创建一个照片顺序列,该列将保持照片的顺序,使用户id、照片顺序唯一,并添加介于1和10之间的CHECKphoto顺序 卡西诺是对的;触发是实现这一目

我认为这是一个相当普遍的问题

我有一个表userid INT。。。表photoid BIGINT,owner INT.owner是对userid的引用

我想给表photo添加一个约束,以防止每个用户有超过10张照片进入数据库

写这篇文章最好的方式是什么


谢谢

不能在表声明中写入这样的约束

有一些变通办法:

创建一个触发器,用于检查每个用户的照片数量 创建一个照片顺序列,该列将保持照片的顺序,使用户id、照片顺序唯一,并添加介于1和10之间的CHECKphoto顺序
卡西诺是对的;触发是实现这一目标的最佳方式

代码如下:

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。如果您不担心这一点,最好删除锁定,因为它可能会成为许多插入/更新的瓶颈。

另一种方法是将列photo_count添加到users表中,使用触发器更新它以使其反映现实,并添加检查以强制执行最大数量的照片

这样做的另一个好处是,在任何给定的时刻,我们都可以知道用户拥有多少照片


另一方面,Quassnoi建议的方法也很酷,因为它使您能够在用户需要时重新排序照片。

更好的选择是在插入时检查行数:

insert into photos(id,owner) 
select 1,2 from dual
where (select count(*) from photos where id=1) < 10

还有一件事:不幸的是,触发器开头的所有IF语句都不能合并到单个IF TG_OP='INSERT'或TG_OP='UPDATE'和NEW.owner!=老主人那么。。。因为PLPGSQL不支持短路。对于最新版本的potsgres 11,这仍然是2019年实现短路的最佳方式吗?对于这个常见的问题,我找不到一个更为近期和令人满意的答案。那么,您不需要在照片顺序上强制执行唯一性吗?怎么做?