Як встановити первинний ключ автоматичного збільшення в PostgreSQL?


259

У мене є таблиця в PostgreSQL з 22 стовпцями, і я хочу додати первинний ключ автоматичного збільшення.

Я спробував створити стовпчик з назвою idBIGSERIAL, але 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
а якщо ви хочете посилатися на нього з іншої таблиці, використовуйте ціле число або bigint
Уорд

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 verison?
dacDave

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 внутрішньо використовує структури хеш-таблиць для збільшення швидкості вставки, видалення, оновлення та вибору. Якщо доступний стовпець первинного ключа (який вимушений унікальним і ненульовим), це може залежати від надання унікального насіння для хеш-функції. Якщо стовпець первинного ключа недоступний, хеш-функція стає неефективною, оскільки вона вибирає якийсь інший набір стовпців як ключ.


21
Незначний гріз, 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)

Два ряди мають клавіші, які починаються з 1 і збільшуються на 1, як визначено послідовністю.

Bonus Elite ProTip:

Програмісти ненавидять вводити текст, а набирати текст - nextval('splog_adfarm_seq')це дратує. Ви можете DEFAULTзамість цього ввести цей параметр, наприклад:

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

Щоб вищезазначене працювало, потрібно визначити значення за замовчуванням для цього стовпця ключів у таблиці splog_adfarm. Що гарніше.


2
Які переваги користувацьких послідовностей? Можливо, безпека?
Лео Леопольд Герц 준영

1
@Masi Одне використання спеціальної послідовності могло б полегшити виконання реплікації master-master - що було б корисно, якщо зв’язок даних між двома центрами обробки даних буде розірвано - дозволяючи створювати записи на обох серверах з різними ідентифікаторами, які то спрощує синхронізацію резервних копій баз даних, зберігаючи ідентифікатори, згенеровані в окремих місцях.
Вінсент Макнабб

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
;

а потім змінити таблицю, щоб використовувати послідовність для ідентифікатора:

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

Чи потрібно створити нову послідовність для кожної таблиці?
Бхарат Чхабра

Ви можете поділити однакову послідовність для різних таблиць, але послідовність збільшиться для кожного запису в кожній таблиці.
acaruci

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 автоматично створює послідовність для відповідного стовпця.


Чи можете ви скинути СЕРІАЛ, як ви робите для ПОСЛІДНОСТІ?
торок

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.