如何在PostgreSQL中安全地转发主键序列?

如何在PostgreSQL中安全地转发主键序列?,postgresql,sequence,Postgresql,Sequence,使用PostgreSQL(8.x),我需要自动跳过序列号块,例如,在发出49999之后,我希望下一个id是70000而不是50000 这样做的正确/最安全的方法是什么 注意:我最初发布了一个非常类似的问题,但我觉得这必须在数据库级别完成(并发问题).您可以使用触发器,在insert语句之后检查序列的实际值,并将其更改为所需的值 我认为这段代码应该可以完成这项工作 CREATE OR REPLACE FUNCTION change_sequence() RETURNS TRIGGER AS $ch

使用PostgreSQL(8.x),我需要自动跳过序列号块,例如,在发出49999之后,我希望下一个id是70000而不是50000

这样做的正确/最安全的方法是什么


注意:我最初发布了一个非常类似的问题,但我觉得这必须在数据库级别完成(并发问题).

您可以使用触发器,在insert语句之后检查序列的实际值,并将其更改为所需的值

我认为这段代码应该可以完成这项工作

CREATE OR REPLACE FUNCTION change_sequence() RETURNS TRIGGER AS $change_sequence$
DECLARE
  current_value INTEGER;

BEGIN
  current_value := currval('your_sequence');
  IF current_value = 49999 THEN
    setval ('you_sequence', 70000, false);
  END IF;
  RETURN NULL;
END;
$change_sequence$ LANGUAGE plpgsql;

-- DROP TRIGGER check_pkey ON your_table;
CREATE TRIGGER check_pkey
AFTER INSERT ON your_table
EXECUTE PROCEDURE change_sequence();

我相信我找到了一个方法:

  • 不要对主键使用串行,请使用默认的my_next_id()
  • 遵循与“单级无间隙序列”相同的逻辑-my_next_id()执行更新,然后执行选择
  • 不要只增加1,而是检查边界是否已越过,如果是,则进一步增加

伙计,根据上面提到的问题,你真的是在找麻烦……谢谢你的回答。这将更改主键而不是顺序。我可以接受这样一个事实,这将被触发20000次,但我认为更大的问题是,我正在使用的框架(Django)将使用序列的currval()作为在同一会话中创建的对象的外键。我编辑了这个片段。我认为可以通过将false参数传递给setval来处理currval问题,如果它不起作用,您可以调用setval('your_seq',69999),然后调用nexval感谢您的再次访问!嗯,我以为“插入后”触发器只有在成功插入后才会触发,对吗?插入尝试不成功仍将拉取nextval(),这意味着不成功的插入可能会在未调用此触发器的情况下拉取49999,然后是成功的插入,如果49999的相等性检查不起作用,因为它拉了50000…?我的第一个想法是在序列更新而不是插入时触发,但我开始不信任序列-它们似乎有点太慷慨了:-)