如何在 Postgres 中为 Table 中的行数限制建模

How can I model a limit of number of Rows in a Table in Postgres

我目前正在学习如何在全栈 Web 开发环境中使用数据库。我想模拟一个场景,学生可以参加具有一定容量的各种活动。我已经看过这个帖子了:

How to write a constraint concerning a max number of rows in postgresql?

但不能完全应用于我的场景,因为应该可以有不同的容量,例如,当房间更新时,容量也可以改变(容量参考房间的容量列 table)

有没有一种优雅的建模方法?

我目前的解决方案是有一个容量列和一个注册量列,每个 insert/delete 获得 in-/decremented。 这种粗略的检查也会发生在客户端 atm 上,我知道出于多种原因这是一种不好的做法,我对此绝对不满意,这就是我创建此 post.

的原因

我认为至少可以使用 Postgres 函数对服务器端进行建模,但由于我还不熟悉这些函数,所以我想先问一下,是否有一种通常更好的建模方法。我正在为我的项目使用 Supabase 实例。

先谢谢大家了!

有很多方法可以做到这一点,但如果你只是想让 PostgreSQL 确保你永远不会超额预订一个事件,你可以为 INSERTUPDATE 编写一个 TRIGGER你的 registration table.

我在我的 Supabase 实例上测试了这个,因为没有什么比从 Whosebug 得到一个不起作用的专家答案更烦人的了!

CREATE TABLE person (id INTEGER UNIQUE PRIMARY KEY, firstname TEXT, lastname TEXT);
CREATE TABLE event (id INTEGER UNIQUE PRIMARY KEY, event_name TEXT, capacity INTEGER);
CREATE TABLE registration (id INTEGER UNIQUE PRIMARY KEY, event_id INTEGER , person_id INTEGER);

INSERT INTO person (id, firstname, lastname) VALUES (1, 'Bob','Barker'),(2, 'Jamie','Oliver'),(3, 'Gary ','Busey');

INSERT INTO event (id, event_name, capacity) VALUES (1, 'Fireman''s Ball', 2);

CREATE OR REPLACE FUNCTION check_registration_capacity()
  RETURNS TRIGGER AS $$
BEGIN
  IF (SELECT count(*) FROM registration as r1 WHERE r1.event_id = NEW.event_id) > 
     ((SELECT capacity FROM event WHERE event.id = NEW.event_id) - 1)
  THEN
    RAISE EXCEPTION 'Event is full';
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER verify_registration_capacity 
BEFORE INSERT OR UPDATE ON registration 
FOR EACH ROW EXECUTE PROCEDURE check_registration_capacity();

-- register Bob for the Fireman's Ball
INSERT INTO registration (id, event_id, person_id) VALUES (1, 1, 1); 
-- register Jamie for the Fireman's Ball
INSERT INTO registration (id, event_id, person_id) VALUES (2, 1, 2);
-- sorry, Gary, the next line throws an 'Event is full' error
INSERT INTO registration (id, event_id, person_id) VALUES (3, 1, 3);