Auto increment depending on value of column in PostgreSQL
接下来的问题是,我是否可以根据特定列(此处为business_uuid)的值自动递增(verification_number),以便使该verify_number根据该business_uuid自身的verification_number的最高数目递增一(1)?
数据库如下所示:
表:验证
1 2 3 | verification_id = INTEGER, SEQUENCE (PRIMARY KEY) business_uuid = text verification_number = INTEGER |
verification_id是此表中的主键,我希望verification_number遵循它自己的自动增量,这取决于仅针对business_uuid过滤的最大值。
business_uuid是每个企业的唯一标识符。
有可能吗?
我认为这是一个不好的设计,但是如果您真的想要这样做,可以按以下步骤实现:
创建唯一约束:
1 2 3 | ALTER TABLE verification ADD CONSTRAINT verification_uuid_nr_unique UNIQUE (business_uuid, verification_number); |
由此创建的索引还将使以下触发功能更快。
创建一个
1 2 3 4 5 6 7 8 9 10 11 12 | CREATE OR REPLACE FUNCTION veritrig() RETURNS TRIGGER LANGUAGE plpgsql AS $$BEGIN SELECT COALESCE(MAX(verification_number)+1, 1) INTO NEW.verification_number FROM verification WHERE business_uuid = NEW.business_uuid; RETURN NEW; END;$$; CREATE TRIGGER veritrig BEFORE INSERT OR UPDATE ON verification FOR EACH ROW EXECUTE PROCEDURE veritrig(); |
插入这样的新值:
1 | INSERT INTO verification (business_uuid) VALUES ('42'); |
然后将根据需要设置
但是并发性问题。
如果多个会话尝试同时插入或更新表,则会出现如下错误:
1 2 | ERROR: duplicate KEY VALUE violates UNIQUE CONSTRAINT"verification_uuid_nr_unique" DETAIL: KEY (business_uuid, verification_number)=(43, 1) already EXISTS. |
这是因为在并发修改中的
没有任何方法可以避免锁定表。但是,如果收到这样的错误,则可以简单地重试该事务,并且很有可能在下次运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | CREATE OR REPLACE FUNCTION public.creaid( IN key_field text, IN table_mane text, OUT id INTEGER) RETURNS INTEGER AS $BODY$ DECLARE maxid INT; BEGIN EXECUTE 'SELECT max('||key_field||') FROM '||TABLE_NAME INTO maxid; IF maxid IS NULL THEN id = 1; ELSE id = maxid + 1; END IF; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; |
然后,您可以将该函数作为数据库每个表的每个键值的默认值进行调用,如下所示:
1 | DEFAULT creaid('key_field'::text, 'table_name'::text) |
尚不清楚是否要将
1 2 3 4 5 6 | SELECT verification_id, business_uuid, ROW_NUMBER() OVER( partition BY business_uuid ORDER BY verification_id ) AS verification_number FROM verification |
上述方法的问题是,如果删除行,
窗口功能