我认为这是一个很常见的问题。
我有一张表 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/