【问题标题】:How to set auto increment primary key in PostgreSQL?如何在 PostgreSQL 中设置自增主键?
【发布时间】:2011-12-04 20:06:31
【问题描述】:

我在 PostgreSQL 中有一个包含许多列的表,我想添加一个自增主键。

我尝试创建一个名为 id 类型为 BIGSERIAL 的列,但 pgadmin 响应错误:

ERROR: sequence must have same owner as table it is linked to.

有人知道如何解决这个问题吗?如何在不重新创建表的情况下在 PostgreSQL 中添加或创建自增主键?

【问题讨论】:

标签: sql postgresql auto-increment


【解决方案1】:

在 PgAdmin 上执行此操作的步骤:

  • 创建序列 sequnence_title START 1; // 如果 table 存在 last id
  • 将这个序列添加到主键,表-属性-列-column_id(主键)编辑-约束-添加nextval('sequnence_title'::regclass)到 字段默认值。

【讨论】:

    【解决方案2】:

    我已尝试使用以下脚本成功地自动增加 P​​ostgreSQL 中的主键。

    CREATE SEQUENCE dummy_id_seq
        START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;
    
    CREATE table dummyTable (
        id bigint DEFAULT nextval('dummy_id_seq'::regclass) NOT NULL,
        name character varying(50)
    );
    

    编辑:

    CREATE table dummyTable (
        id SERIAL NOT NULL,
        name character varying(50)
    )
    

    SERIAL 关键字自动为各个列创建一个序列。

    【讨论】:

    • 你能像对序列一样重置序列吗?
    • 是的!我已经检查了ALTER SEQUENCE dummytable_id_seq RESTART WITH 1; 及其工作。
    【解决方案3】:

    如果你想在一个序列中使用数字,定义一个新的序列,比如

    CREATE SEQUENCE public.your_sequence
        INCREMENT 1
        START 1
        MINVALUE 1
    ;
    

    然后更改表以使用 id 的序列:

    ALTER TABLE ONLY table ALTER COLUMN id SET DEFAULT nextval('your_sequence'::regclass);
    

    【讨论】:

    • 我必须为每个表创建一个新序列吗?
    • 不同表可以共享同一个序列,但是每个表中每条记录的序列都会增加。
    【解决方案4】:

    在 postgresql 中创建一个自动递增的主键,使用自定义序列:

    第 1 步,创建序列:

    create sequence splog_adfarm_seq
        start 1
        increment 1
        NO MAXVALUE
        CACHE 1;
    ALTER TABLE fact_stock_data_detail_seq
    OWNER TO pgadmin;
    

    第 2 步,创建表格

    CREATE TABLE splog_adfarm
    (
        splog_key    INT unique not null,
        splog_value  VARCHAR(100) not null
    );
    

    第 3 步,插入表格

    insert into splog_adfarm values (
        nextval('splog_adfarm_seq'), 
        'Is your family tree a directed acyclic graph?'
    );
    
    insert into splog_adfarm values (
        nextval('splog_adfarm_seq'), 
        'Will the smart cookies catch the crumb?  Find out now!'
    );
    

    第 4 步,观察行

    el@defiant ~ $ psql -U pgadmin -d kurz_prod -c "select * from splog_adfarm"
    
    splog_key |                            splog_value                             
    ----------+--------------------------------------------------------------------
            1 | Is your family tree a directed acyclic graph?
            2 | Will the smart cookies catch the crumb?  Find out now!
    (3 rows)
    

    这两行的键从 1 开始并按序列定义递增 1。

    Bonus Elite ProTip:

    程序员讨厌打字,而且输入nextval('splog_adfarm_seq') 很烦人。您可以为该参数键入 DEFAULT,如下所示:

    insert into splog_adfarm values (
        DEFAULT, 
        'Sufficient intelligence to outwit a thimble.'
    );
    

    要使上述方法起作用,您必须在 splog_adfarm 表上为该键列定义一个默认值。哪个更漂亮。

    【讨论】:

    • 自定义序列有什么好处?可能是安全?
    • @Masi 自定义序列的一种用途可能是使主-主复制更容易 - 如果两个数据中心之间的数据链接中断,这将很有用 - 允许创建记录在具有不同 ID 的两台服务器上,这样可以轻松同步数据库备份,同时将生成的 ID 保留在不同的位置。
    【解决方案5】:

    也许我回答这个问题有点晚了,但我在工作中正在研究这个主题:)

    我想写列 'a_code' = c1,c2,c3,c4...

    首先我打开了一个名为ref_id 和类型serial 的列。 然后我用这个命令解决了我的问题:

    update myschema.mytable set a_code=cast('c'||"ref_id" as text) 
    

    【讨论】:

    • 是否可以在不添加任何新列的情况下在表中创建主键(现有列)
    【解决方案6】:

    如果您想在 pgadmin 中执行此操作,则要容易得多。在 postgressql 中,要为列添加自动增量,我们首先需要创建一个自动增量序列并将其添加到所需的列中。我确实喜欢这个。

    1) 首先你需要确保你的表有一个主键。还要将主键的数据类型保留在 bigint 或 smallint 中。 (我使用了 bigint,找不到其他地方的其他答案中提到的名为 serial 的数据类型)

    2)然后通过右键单击序列添加一个序列-> 添加新序列。 如果表中没有数据,则保持原样,不要进行任何更改。保存它。 如果存在现有数据,请将主键列中的最后一个或最高值添加到定义选项卡中的当前值,如下所示。

    3)最后,将nextval('your_sequence_name'::regclass) 行添加到主键中的默认值,如下所示。

    确保此处的序列名称正确。这就是全部,自动增量应该可以工作。

    【讨论】:

      【解决方案7】:

      postgresql 中主键自动递增:

      第 1 步,创建表格:

      CREATE TABLE epictable
      (
          mytable_key    serial primary key,
          moobars        VARCHAR(40) not null,
          foobars        DATE
      );
      

      第2步,像这样向表中插入值,注意第一个参数列表中没有指定mytable_key,这会导致默认序列自动递增。

      insert into epictable(moobars,foobars) values('delicious moobars','2012-05-01')
      insert into epictable(moobars,foobars) values('worldwide interblag','2012-05-02')
      

      第 3 步,从表格中选择 *:

      el@voyager$ psql -U pgadmin -d kurz_prod -c "select * from epictable"
      

      第 4 步,解释输出:

      mytable_key  |        moobars        |  foobars   
      -------------+-----------------------+------------
                 1 | delicious moobars     | 2012-05-01
                 2 | world wide interblags | 2012-05-02
      (2 rows)
      

      观察 mytable_key 列已自动递增。

      专业提示:

      您应该始终在表上使用主键,因为 postgresql 内部使用哈希表结构来提高插入、删除、更新和选择的速度。如果主键列(强制唯一且非空)可用,则可以依赖它为散列函数提供唯一种子。如果没有可用的主键列,则哈希函数会变得低效,因为它会选择其他一些列集作为键。

      【讨论】:

      • 一个小小的挑剔,SERIAL 确实在幕后创建了一个sequencepostgresql.org/docs/9.2/static/…
      • 是否可以在不添加任何新列的情况下在表中创建主键(现有列)
      • 使用thing_id int references epictable(mytable_key) 声明的外键是否有效?
      【解决方案8】:

      试试这个命令:

      ALTER TABLE your_table ADD COLUMN key_column BIGSERIAL PRIMARY KEY;
      

      尝试使用与您创建表的数据库用户相同的数据库用户。

      【讨论】:

      • (这里的关键是使用 SERIAL 或 BIGSERIAL 数据类型,它在后台创建序列并在插入时递增/使用它)
      • 如果要从另一个表中引用它,请使用整数或 bigint
      • @satishkilari:是的,语法是 ALTER TABLE mytable ADD PRIMARY KEY (column); 。 Postgresql 将检查该列是否包含 NULL。
      • 在 pgAdmin 4 中出现此错误。bigserialserial 都给出相同的错误:ERROR: syntax error at or near "BIGSERIAL"
      • 使用 bigserial 或 serial 时也会出现语法错误。是否有最低的 postgresql 版本?
      猜你喜欢
      • 1970-01-01
      • 2012-08-28
      • 1970-01-01
      • 2017-03-03
      • 1970-01-01
      • 2017-08-13
      • 2011-12-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多