我认为这是一个很常见的问题。
我有一个表用户(ID INT …)和一张表照片(id BIGINT,所有者INT)。所有者是用户(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,然后两者都插入,这将导致你超过限制。如果这不是您的问题,最好删除锁定,因为它可能成为许多插入/更新的瓶颈。