【问题标题】:Changing primary key int type to serial将主键 int 类型更改为串行
【发布时间】:2014-06-28 00:13:06
【问题描述】:

有没有办法在不删除表的情况下将现有的主键类型从 int 更改为 serial?我的表中已经有很多数据,我不想删除它。

【问题讨论】:

    标签: postgresql primary-key auto-increment


    【解决方案1】:

    将 int 转换为串行 more or less only means adding a sequence default to the value,从而使其成为串行;

    • 为序列选择一个起始值,大于表中任何现有值
      SELECT MAX(id)+1 FROM mytable

    • 为序列创建一个序列(tablename_columnname_seq 是个好名字)
      CREATE SEQUENCE test_id_seq MINVALUE 3(假设你想从 3 开始)

    • 更改列的默认值以使用序列
      ALTER TABLE test ALTER id SET DEFAULT nextval('test_id_seq')

    • 更改表/列所拥有的序列;
      ALTER SEQUENCE test_id_seq OWNED BY test.id

    A very simple SQLfiddle demo.

    和往常一样,养成运行完整备份的习惯运行来自 Internet 上随机人员的更改 SQL 查询 ;-)

    【讨论】:

    • 但是我们如何在不同的表中使用这个递增的值作为外键。它在它所链接的其他表中给出空值。
    • 谁能解释为什么权限所有权ALTER SEQUENCE test_id_seq OWNED BY test.id 查询很重要?我的架构不匹配,所以无法运行。
    • @ConnorWilloughby 来自the documentation(对于 PostgreSQL 版本 12)描述了对表列使用 SERIAL 类型的实际效果,'序列被标记为“由”列拥有,因此它将如果列或表被删除,则被删除。也就是说,列或表的 DROP 现在将级联,也摆脱了序列。方便!
    【解决方案2】:
    -- temp schema for testing
    -- ----------------------------
    DROP SCHEMA tmp CASCADE;
    CREATE SCHEMA tmp ;
    SET search_path=tmp;
    
    CREATE TABLE bagger
            ( id  INTEGER NOT NULL PRIMARY KEY
            , tralala varchar
            );
    
    INSERT INTO bagger(id,tralala)
    SELECT gs, 'zzz_' || gs::text
    FROM generate_series(1,100) gs
            ;
    
    DELETE FROM bagger WHERE random() <0.9;
    -- SELECT * FROM bagger;
    
            -- CREATE A sequence and tie it to bagger.id
            -- -------------------------------------------
    CREATE SEQUENCE bagger_id_seq;
    ALTER TABLE bagger
            ALTER COLUMN id SET NOT NULL
            , ALTER COLUMN id SET DEFAULT nextval('player_id_seq')
            ;
    ALTER SEQUENCE bagger_id_seq
            OWNED BY bagger.id
            ;
    SELECT setval('bagger_id_seq', MAX(ba.id))
    FROM bagger ba
            ;
    
         -- Check the result
         -- ------------------
    SELECT * FROM bagger;
    
    \d bagger
    \d bagger_id_seq
    

    【讨论】:

    • 这是做什么的?你能解释一下它为什么有效或其他可能的解决方案吗?
    • 好吧:它创建了一个表(OP 没有这样做),用随机值填充它(OP 没有这样做),添加一个序列 loldstyle(其中OP 的意图)并使其成为主键(OP 的意图)
    猜你喜欢
    • 1970-01-01
    • 2017-04-05
    • 2012-02-09
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 2018-04-14
    • 1970-01-01
    相关资源
    最近更新 更多