Postgresql 如何获得一列连续递增的数字,而不丢失任何数字?

Postgresql 如何获得一列连续递增的数字,而不丢失任何数字?,postgresql,triggers,tabbing,Postgresql,Triggers,Tabbing,可能的重复项: 我只是想问,在PostgreSQL中是否存在这样的可能性,如果我有5行,在一列中有数字1,2,3,4,5,如果我删除这些列,比如说tird行,PostgreSQL会重新枚举该列,这样我就可以有1,2,3,4,而不是1,2,4,5?根据先前的答案改编。当应用程序需要变量的制表顺序(读取:EAV模型中的记录)时,这种情况经常发生,也可能是备用键的一部分 优先级字段需要保持连续。[这是制表顺序] 插入时:优先级>=新记录的所有记录的优先级应增加 类似地:删除->递减 如果更新更

可能的重复项:



我只是想问,在PostgreSQL中是否存在这样的可能性,如果我有5行,在一列中有数字
1,2,3,4,5
,如果我删除这些列,比如说tird行,PostgreSQL会重新枚举该列,这样我就可以有
1,2,3,4
,而不是
1,2,4,5

根据先前的答案改编。当应用程序需要变量的制表顺序(读取:EAV模型中的记录)时,这种情况经常发生,也可能是备用键的一部分

  • 优先级
    字段需要保持连续。[这是制表顺序]
  • 插入时:优先级>=新记录的所有记录的优先级应增加
  • 类似地:删除->递减
  • 如果更新更改了记录的优先级,则新旧优先级值之间的记录的优先级应上移或下移
  • 要避免递归触发器调用,请执行以下操作:
    • 基于触发器的更新会翻转所接触的任何记录的
      flipflag
    • 他们测试
      old.flipflag=new.flipflag
      ,以检测真正的更新。(非由触发器引起的)


根据以前的答案改编。。。那么这也是一个副本?不,我添加了删除和插入的代码。旧版本只有更新-->>上下冒泡。你通过交替位进行无休止的循环预防让我想起了我使用延迟触发器的地方。但我现在没有时间深入研究。如果它除了“我改编自一个未命名的来源”之外还有其他解释的话,这可能是一个非常好的答案。在
flipflag
列旁边放一个眨眼的笑脸是很好的,但我完全不知道它为什么在那里。它是用来区分真正的更新和由触发器引起的更新,从而避免无限递归(此后出现了避免无限递归的其他机制),另一个答案是我自己的IIRC。
        -- Make some data
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

CREATE TABLE fruits
        ( id INTEGER NOT NULL PRIMARY KEY
        , priority INTEGER NOT NULL
        , flipflag boolean NOT NULL default false
        , zname varchar NOT NULL
        , CONSTRAINT unique_priority UNIQUE (priority) DEFERRABLE INITIALLY DEFERRED
        );
INSERT INTO fruits(id,zname,priority) VALUES
 (1  , 'Pear' ,4)
,(2  , 'Apple' ,2)
,(3  , 'Orange' ,1)
,(4  , 'Banana' ,3)
,(5  , 'Peach' ,5)
        ;

        -- Trigger functions for Insert/update/delete
CREATE function shift_priority()
RETURNS TRIGGER AS $body$

BEGIN
        UPDATE fruits fr
        SET priority = priority +1
        , flipflag = NOT flipflag       -- alternating bit protocol ;-)
        WHERE NEW.priority < OLD.priority
        AND OLD.flipflag = NEW.flipflag -- redundant condition
        AND fr.priority >= NEW.priority
        AND fr.priority < OLD.priority
        AND fr.id <> NEW.id             -- exlude the initiating row
                ;
        UPDATE fruits fr
        SET priority = priority -1
        , flipflag = NOT flipflag
        WHERE NEW.priority > OLD.priority
        AND OLD.flipflag = NEW.flipflag
        AND fr.priority <= NEW.priority
        AND fr.priority > OLD.priority
        AND fr.id <> NEW.id
        ;
        RETURN NEW;
END;

$body$
language plpgsql;

CREATE function shift_down_priority()
RETURNS TRIGGER AS $body$

BEGIN

        UPDATE fruits fr
        SET priority = priority -1
        , flipflag = NOT flipflag       -- alternating bit protocol ;-)
        WHERE fr.priority > OLD.priority
                ;
        RETURN NEW;
END;

$body$
language plpgsql;

CREATE function shift_up_priority()
RETURNS TRIGGER AS $body$

BEGIN
        UPDATE fruits fr
        SET priority = priority +1
        , flipflag = NOT flipflag       -- alternating bit protocol ;-)
        WHERE fr.priority >= NEW.priority
                ;
        RETURN NEW;
END;

$body$
language plpgsql;

        -- Triggers for Insert/Update/Delete
CREATE TRIGGER shift_priority_u
        AFTER UPDATE OF priority ON fruits
        FOR EACH ROW
        WHEN (OLD.flipflag = NEW.flipflag AND OLD.priority <> NEW.priority)
        EXECUTE PROCEDURE shift_priority()
        ;
CREATE TRIGGER shift_priority_d
        AFTER DELETE ON fruits
        FOR EACH ROW
        EXECUTE PROCEDURE shift_down_priority()
        ;
CREATE TRIGGER shift_priority_i
        BEFORE INSERT ON fruits
        FOR EACH ROW
        EXECUTE PROCEDURE shift_up_priority()
        ;

        -- Do some I/U/D operations
\echo Pears are Okay
UPDATE fruits
SET priority = 1
WHERE id=1; -- 1,4

SELECT * FROM fruits ORDER BY priority;

\echo dont want bananas
DELETE FROM fruits WHERE id = 4;
SELECT * FROM fruits ORDER BY priority;

\echo  We want Kiwis
INSERT INTO fruits(id,zname,priority) VALUES (4  , 'Kiwi' ,3) ;
SELECT * FROM fruits ORDER BY priority;
Pears are Okay
UPDATE 1
 id | priority | flipflag | zname  
----+----------+----------+--------
  1 |        1 | f        | Pear
  3 |        2 | t        | Orange
  2 |        3 | t        | Apple
  4 |        4 | t        | Banana
  5 |        5 | f        | Peach
(5 rows)

dont want bananas
DELETE 1
 id | priority | flipflag | zname  
----+----------+----------+--------
  1 |        1 | f        | Pear
  3 |        2 | t        | Orange
  2 |        3 | t        | Apple
  5 |        4 | t        | Peach
(4 rows)

We want Kiwis
INSERT 0 1
 id | priority | flipflag | zname  
----+----------+----------+--------
  1 |        1 | f        | Pear
  3 |        2 | t        | Orange
  4 |        3 | f        | Kiwi
  2 |        4 | f        | Apple
  5 |        5 | f        | Peach
(5 rows)