【问题标题】:PostgreSQL column type conversion from bigint to bigserialPostgreSQL 列类型从 bigint 到 bigserial 的转换
【发布时间】:2015-11-05 01:54:48
【问题描述】:

当我尝试通过 alter 命令更改表中列的数据类型时...

alter table temp alter column id type bigserial;

我明白了

ERROR:  type "bigserial" does not exist

如何将数据类型从 bigint 更改为 bigserial?

【问题讨论】:

    标签: sql database postgresql persistence


    【解决方案1】:

    听起来很多专业人士都在这个主题上......如果原始表确实有数据,那么这个困境的真正答案是首先正确设计数据库。但是,在这种情况下,更改列规则(类型)将需要对该列进行完整性验证以用于新范式。而且,不要忘记,在任何地方操作(添加/更新)该列的地方都需要调查。

    如果是新表,那么简单:删除列并重新添加新列(为您处理顺序)。再次,设计,设计,设计。

    我想我们都犯了这个错误。

    【讨论】:

      【解决方案2】:

      documentation 中所述,SERIAL 不是数据类型,而是其他命令集合的快捷方式。

      所以虽然你不能简单地通过改变类型来改变它,但你可以通过自己运行这些其他命令来达到相同的效果:

      CREATE SEQUENCE temp_id_seq;
      ALTER TABLE temp ALTER COLUMN id SET NOT NULL;
      ALTER TABLE temp ALTER COLUMN id SET DEFAULT nextval('temp_id_seq');
      ALTER SEQUENCE temp_id_seq OWNED BY temp.id;
      

      更改所有者将确保在删除表/列时删除序列。它还会在pg_get_serial_sequence() 函数中为您提供预期的行为。

      坚持tablename_columnname_seq 命名约定对于说服一些工具(如pgAdmin)将此列类型报告为BIGSERIAL 是必要的。请注意,psql 和 pg_dump 将始终显示底层定义,即使该列最初声明为 SERIAL 类型。

      从 Postgres 10 开始,您还可以选择使用 SQL 标准 identity column,它可以无形地处理所有这些,并且您可以轻松地将其添加到现有表中:

      ALTER TABLE temp ALTER COLUMN id
        ADD GENERATED BY DEFAULT AS IDENTITY
      

      【讨论】:

      • 我觉得这并没有真正回答有关如何在现有列上获取 bigserial 的问题。你是说在 bigint 上设置一个序列会导致它成为 bigserial?
      • @Amalgovinus:基本上,是的。 Postgres 实际上并不跟踪列是否被创建为SERIAL 类型。如果您查看带有BIGSERIAL 的表的pg_dump 输出,您只会看到BIGINT 和一个序列(并且自己创建BIGINT 和序列与使用@987654336 完全相同@关键字)。请注意,从 Postgres 10 开始,您可以选择将其转换为 identity column
      【解决方案3】:

      这是一个简单的解决方法:

      ALTER TABLE table_name drop column column_name, add column column_name bigserial;
      

      【讨论】:

      • 如你所说,这是一个hack。他会丢失存储在 stat 列中的所有数据。糟糕的解决方案!
      • @Alexander,你说的不太对。无论旧值是什么,当有人决定列类型为 *serial 时,他必须创建并使用序列。如果这不正确,那么黑客是深不可测的。可以添加一个额外的列,复制旧值,应用我的技巧,用旧值更新值,最后通过 ALTER SEQUENCE 设置适当的 nextval()。希望这会有所帮助。
      【解决方案4】:

      ALTERBIGINTEGERBIGSERIAL 的列以使其自动递增不起作用。 BIGSERIAL is not a true type, it is a trick that automates PK and SEQUENCE creation.

      您可以自己创建一个序列,然后将其指定为列的默认值:

      CREATE SEQUENCE "YOURSCHEMA"."SEQNAME";
      
      ALTER TABLE "YOURSCHEMA"."TABLENAME"
         ALTER COLUMN "COLUMNNAME" SET DEFAULT nextval('"YOURSCHEMA"."SEQNAME"'::regclass);
      ALTER TABLE "YOURSCHEMA"."TABLENAME" ADD CONSTRAINT pk PRIMARY KEY ("COLUMNNAME");
      

      【讨论】:

      • 请注意,这将不会使用现有值填充列。因此,如果存在NULL 或非唯一的现有行,则添加PRIMARY KEY 约束将失败。 (您假设用户还没有主键。SERIAL 不只是用于 PK,SERIAL 并不意味着 SERIAL PRIMARY KEY)。此外,如果表有现有行,您需要setval 序列以确保它从第一个空闲标识符开始,LOCKing 表首先防止并发INSERTs。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-03
      • 2020-06-10
      • 2016-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-04
      相关资源
      最近更新 更多