如何编写关于postgresql中最大行数的约束?
我认为这是一个相当普遍的问题 我有一个表userid INT。。。表photoid BIGINT,owner INT.owner是对userid的引用 我想给表photo添加一个约束,以防止每个用户有超过10张照片进入数据库 写这篇文章最好的方式是什么如何编写关于postgresql中最大行数的约束?,sql,postgresql,constraints,Sql,Postgresql,Constraints,我认为这是一个相当普遍的问题 我有一个表userid INT。。。表photoid BIGINT,owner INT.owner是对userid的引用 我想给表photo添加一个约束,以防止每个用户有超过10张照片进入数据库 写这篇文章最好的方式是什么 谢谢 不能在表声明中写入这样的约束 有一些变通办法: 创建一个触发器,用于检查每个用户的照片数量 创建一个照片顺序列,该列将保持照片的顺序,使用户id、照片顺序唯一,并添加介于1和10之间的CHECKphoto顺序 卡西诺是对的;触发是实现这一目
谢谢 不能在表声明中写入这样的约束 有一些变通办法: 创建一个触发器,用于检查每个用户的照片数量 创建一个照片顺序列,该列将保持照片的顺序,使用户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年实现短路的最佳方式吗?对于这个常见的问题,我找不到一个更为近期和令人满意的答案。那么,您不需要在照片顺序上强制执行唯一性吗?怎么做?