PostgreSQLで自動インクリメント主キーを設定するにはどうすればよいですか?


259

PostgreSQLに22列のテーブルがあり、自動インクリメントの主キーを追加したいと思います。

idタイプBIGSERIALの列を作成しようとしましたが、pgadminがエラーで応答しました。

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

誰もがこの問題を修正する方法を知っていますか?テーブルを再作成せずに、PostgreSQLで自動インクリメントの主キーを作成するにはどうすればよいですか?

回答:


292

次のコマンドを試してください:

ALTER TABLE your_table ADD COLUMN key_column BIGSERIAL PRIMARY KEY;

テーブルを作成したのと同じDBユーザーで試してください。


75
(ここで重要なのは、SERIALまたはBIGSERIALデータ型を使用することです。これにより、シーケンスの背後にシーケンスが作成され、挿入時にインクリメント/使用されます)
rogerdpack

16
別のテーブルから参照する場合は、integerまたはbigintを使用します
Ward

2
@satishkilari:はい、構文はALTER TABLE mytable ADD PRIMARY KEY (column);です。Postgresqlは列にNULLが含まれていないことをチェックします。
AH

3
pgAdminで4両でこのエラーを取得bigserialし、serial同じエラーを与えている:ERROR: syntax error at or near "BIGSERIAL"
ADI

5
また、bigserialまたはserialを使用して構文エラーを取得します。これには最小限のpostgresqlバージョンがありますか?
dacDave 2016

251

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列が自動インクリメントされていることを確認します。

ProTip:

postgresqlは内部的にハッシュテーブル構造を使用して挿入、削除、更新、選択の速度を上げるため、常にテーブルで主キーを使用する必要があります。主キー列(一意で強制され、nullでない)が利用可能な場合、これを利用してハッシュ関数に一意のシードを提供できます。主キー列が使用できない場合、ハッシュ関数は他の列のセットをキーとして選択するため、非効率になります。


21
マイナーのnitpickは、SERIAL作成しないsequence舞台裏:postgresql.org/docs/9.2/static/...
カルボ

1
新しい列を追加せずにテーブルに主キー(既存の列)を作成することは可能ですか
satish kilari

外部キーは機能すると宣言されthing_id int references epictable(mytable_key)ますか?

36

カスタムシーケンスを使用して、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)

2つの行には、シーケンスで定義されているように、1から始まり1ずつ増加するキーがあります。

ボーナスエリートProTip:

プログラマーはタイピングが嫌いで、タイプアウトするのnextval('splog_adfarm_seq')は面倒です。DEFAULT代わりに、次のようにそのパラメータを入力できます。

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

上記が機能するためには、splog_adfarmテーブルでそのキー列のデフォルト値を定義する必要があります。どちらがきれいですか。


2
カスタムシーケンスの利点は何ですか?おそらく、セキュリティ?
レオ・レオポルド・ヘルツ준 영

1
@Masiカスタムシーケンスの1つの使用法は、マスターマスターレプリケーションを容易にすることです。これは、2つのデータセンター間のデータリンクが壊れている場合に役立ちます。異なるIDの両方のサーバーでレコードを作成できます。次に、生成されたIDを別々の場所に保持しながら、データベースを簡単に同期できます。
Vincent McNabb

16

pgadminでこれを行いたい場合は、はるかに簡単です。postgressqlのように、列に自動インクリメントを追加するには、まず自動インクリメントシーケンスを作成し、それを必要な列に追加する必要があります。私はこれが好きでした。

1)最初に、テーブルの主キーがあることを確認する必要があります。また、主キーのデータ型をbigintまたはsmallintのままにします。(bigintを使用しましたが、他の回答で言及されているように、serialというデータ型が見つかりませんでした)

2)次に、シーケンスを右クリックしてシーケンスを追加し、[ 新しいシーケンスを追加 ]をクリックします。テーブルにデータがない場合は、シーケンスをそのままにして、変更を加えないでください。保存してください。既存のデータがある場合は、以下に示すように、主キー列の最後または最も高い値を[定義]タブの[現在の値]に追加します。 ここに画像の説明を入力してください

3)最後に、nextval('your_sequence_name'::regclass)以下に示すように、主キーのデフォルト値に行を追加します。

ここに画像の説明を入力してください ここでシーケンス名が正しいことを確認してください。これですべてで、自動インクリメントが機能するはずです。


9

シーケンスで数値を使用したい場合は、次のようなもので新しいシーケンスを定義します

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);

テーブルごとに新しいシーケンスを作成する必要がありますか?
Bharat Chhabra

異なるテーブルで同じシーケンスを共有できますが、シーケンスは各テーブルのレコードごとに増加します。
アカルシ

1

次のスクリプトを試して、PostgreSQLの主キーを正常に自動インクリメントしました。

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キーワードは、それぞれの列のシーケンスを自動的に作成します。


シーケンスの場合と同じようにシリアルをリセットできますか?
thoroc

1
ええ、私はチェックしALTER SEQUENCE dummytable_id_seq RESTART WITH 1;てその動作を確認しました。
アサドシャキール

0

たぶん私はこの質問に答えるのが少し遅れますが、私は私の仕事でこの問題に取り組んでいます:)

列 'a_code' = c1、c2、c3、c4 ...を書き込みたい...

まず、名前ref_idとタイプの列を開きましたserial。それから私はこのコマンドで私の問題を解決しました:

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

新しい列を追加せずにテーブルに主キー(既存の列)を作成することは可能ですか
satish kilari
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.