Làm cách nào để đặt khóa chính tăng tự động trong PostgreSQL?


259

Tôi có một bảng trong PostgreSQL với 22 cột và tôi muốn thêm khóa chính tăng tự động.

Tôi đã cố gắng tạo một cột được gọi là idloại BIGSERIAL nhưng pgadmin đã trả lời với một lỗi:

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

Có ai giải quyết được vấn đề này không? Làm cách nào để thêm khóa chính tạo tự động tăng trong PostgreSQL mà không cần tạo lại bảng?

Câu trả lời:


292

Hãy thử lệnh này:

ALTER TABLE your_table ADD COLUMN key_column BIGSERIAL PRIMARY KEY;

Hãy thử nó với cùng một người dùng DB như người bạn đã tạo bảng.


75
(chìa khóa ở đây là sử dụng kiểu dữ liệu SERIAL hoặc BIGSERIAL, tạo ra một chuỗi phía sau hậu trường và tăng / sử dụng nó tại thời điểm chèn)
rogerdpack

16
và nếu bạn muốn tham chiếu nó từ một bảng khác, hãy sử dụng số nguyên hoặc bigint
Ward

2
@satishkilari: vâng, cú pháp là ALTER TABLE mytable ADD PRIMARY KEY (column);. Postgresql sẽ kiểm tra xem cột không chứa NULL.
AH

3
Gặp lỗi này trong pgAdmin 4. Cả hai bigserialserialđều đưa ra cùng một lỗi:ERROR: syntax error at or near "BIGSERIAL"
adi

5
Cũng nhận được lỗi cú pháp bằng cách sử dụng bigserial hoặc serial. Có một bản án postgresql tối thiểu cho điều này?
dacDave

251

Tự động tăng khóa chính trong postgresql:

Bước 1, tạo bảng của bạn:

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

Bước 2, chèn các giá trị vào bảng của bạn như thế này, lưu ý rằng mytable_key không được chỉ định trong danh sách tham số đầu tiên, điều này làm cho chuỗi mặc định tự động tăng.

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

Bước 3, chọn * từ bảng của bạn:

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

Bước 4, giải thích đầu ra:

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

Quan sát rằng cột mytable_key đã được tăng tự động.

ProTip:

Bạn phải luôn luôn sử dụng khóa chính trên bảng vì postgresql sử dụng cấu trúc bảng băm để tăng tốc độ chèn, xóa, cập nhật và chọn. Nếu có một cột khóa chính (được buộc là duy nhất và không có giá trị), thì nó có thể được phụ thuộc vào để cung cấp một hạt giống duy nhất cho hàm băm. Nếu không có cột khóa chính khả dụng, hàm băm trở nên kém hiệu quả khi nó chọn một số nhóm cột khác làm khóa.


21
Một nitlog nhỏ, SERIALsẽ tạo ra một sequencehậu trường: postgresql.org/docs/9.2/static/ mẹo
carbocation 17/03/13

1
có thể tạo khóa chính (cột hiện tại) trong một bảng mà không cần thêm bất kỳ cột mới nào không
satish kilari

một khóa ngoại sẽ khai báo với thing_id int references epictable(mytable_key)công việc?

36

Tạo khóa chính tăng tự động trong postgresql, sử dụng chuỗi tùy chỉnh:

Bước 1, tạo chuỗi của bạn:

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

Bước 2, tạo bảng của bạn

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

Bước 3, chèn vào bảng của bạn

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

Bước 4, quan sát các hàng

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)

Hai hàng có các khóa bắt đầu từ 1 và được tăng thêm 1, như được xác định bởi chuỗi.

Tiền thưởng Elite ProTip:

Các lập trình viên ghét gõ, và gõ ra nextval('splog_adfarm_seq')là khó chịu. Bạn có thể gõ DEFAULTcho tham số đó thay vào đó, như thế này:

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

Để làm việc ở trên, bạn phải xác định một giá trị mặc định cho cột khóa đó trên bảng splog_adfarm. Cái nào đẹp hơn.


2
Những lợi ích của trình tự tùy chỉnh là gì? Có lẽ, an ninh?
Léo Léopold Hertz

1
@Masi Một cách sử dụng trình tự tùy chỉnh có thể giúp cho việc sao chép chính chủ dễ dàng hơn - sẽ hữu ích nếu liên kết dữ liệu giữa hai trung tâm dữ liệu bị hỏng - cho phép tạo bản ghi trên cả hai máy chủ có ID khác nhau, điều này được tạo sau đó giúp dễ dàng đồng bộ hóa cơ sở dữ liệu sao lưu trong khi vẫn giữ các id được tạo ở các vị trí riêng biệt.
Vincent McNabb

16

Nếu bạn muốn làm điều này trong pgadmin, nó dễ dàng hơn nhiều. Có vẻ như trong postTHERql, để thêm một mức tăng tự động vào một cột, trước tiên chúng ta cần tạo một chuỗi tăng tự động và thêm nó vào cột cần thiết. Tôi đã làm như thế này.

1) Trước tiên, bạn cần đảm bảo có một khóa chính cho bảng của bạn. Cũng giữ kiểu dữ liệu của khóa chính trong bigint hoặc smallint. (Tôi đã sử dụng bigint, không thể tìm thấy một kiểu dữ liệu được gọi là nối tiếp như được đề cập trong các câu trả lời khác ở nơi khác)

2) Sau đó thêm một chuỗi bằng cách nhấp chuột phải vào chuỗi-> thêm chuỗi mới . Nếu không có dữ liệu trong bảng, hãy để nguyên chuỗi, đừng thực hiện bất kỳ thay đổi nào. Chỉ cần lưu nó. Nếu có dữ liệu hiện có, hãy thêm giá trị cuối cùng hoặc cao nhất vào cột khóa chính vào giá trị Hiện tại trong tab Định nghĩa như được hiển thị bên dưới. nhập mô tả hình ảnh ở đây

3) Cuối cùng, thêm dòng nextval('your_sequence_name'::regclass)vào giá trị Mặc định trong khóa chính của bạn như hiển thị bên dưới.

nhập mô tả hình ảnh ở đây Hãy chắc chắn rằng tên trình tự là chính xác ở đây. Đây là tất cả và tự động tăng nên hoạt động.


9

Nếu bạn muốn sử dụng các số trong một chuỗi, hãy xác định một chuỗi mới với một cái gì đó như

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

và sau đó thay đổi bảng để sử dụng chuỗi cho id:

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

Tôi có phải tạo một chuỗi mới cho mỗi bảng không?
Bharat Chhabra

Bạn có thể chia sẻ cùng một chuỗi cho các bảng khác nhau, nhưng chuỗi sẽ tăng cho mỗi bản ghi trong mỗi bảng.
acaruci

1

Tôi đã thử đoạn script sau để tự động tăng thành công khóa chính trong 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)
);

BIÊN TẬP:

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

Từ khóa SERIAL tự động tạo một chuỗi cho cột tương ứng.


Bạn có thể thiết lập lại một SERIAL giống như bạn làm cho một SEQUENCE không?
ngực

1
Vâng!, Tôi đã kiểm tra ALTER SEQUENCE dummytable_id_seq RESTART WITH 1;và nó hoạt động.
Asad Shakeel

0

Có lẽ tôi hơi muộn để trả lời câu hỏi này, nhưng tôi đang làm việc về chủ đề này trong công việc của mình :)

Tôi muốn viết cột 'a_code' = c1, c2, c3, c4 ...

Đầu tiên tôi mở một cột với tên ref_idvà loại serial. Sau đó, tôi đã giải quyết vấn đề của mình bằng lệnh này:

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

có thể tạo khóa chính (cột hiện tại) trong một bảng mà không cần thêm bất kỳ cột mới nào không
satish kilari
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.