Как установить автоинкрементный первичный ключ в PostgreSQL?

259

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

Я попытался создать столбец с именем idтипа BIGSERIAL, но pgadmin ответил с ошибкой:

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

Кто-нибудь знает, как решить эту проблему? Как добавить автоинкрементный первичный ключ в PostgreSQL без повторного создания таблицы?

MKN
источник

Ответы:

292

Попробуйте эту команду:

ALTER TABLE your_table ADD COLUMN key_column BIGSERIAL PRIMARY KEY;

Попробуйте это с тем же пользователем базы данных, что и созданный вами стол.

AH
источник
75
(здесь ключом является использование типа данных SERIAL или BIGSERIAL, который создает закулисную последовательность и увеличивает / использует ее во время вставки)
rogerdpack
16
и если вы хотите сослаться на него из другой таблицы, используйте целое число или 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"
Ади
5
Также получаю синтаксическую ошибку, используя bigserial или serial. Существует ли минимальная версия postgresql для этого?
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закулисную ситуацию
carbocation
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, как определено в последовательности.

Бонус 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)к значению Default в вашем первичном ключе, как показано ниже.

введите описание изображения здесь Убедитесь, что имя последовательности здесь правильно. Это все, и автоматическое увеличение должно работать.

toing_toing
источник
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
источник
Нужно ли создавать новую последовательность для каждой таблицы?
Бхарат Чхабра
Вы можете использовать одну и ту же последовательность для разных таблиц, но эта последовательность будет увеличиваться для каждой записи в каждой таблице.
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 автоматически создает последовательность для соответствующего столбца.

Асад Шакил
источник
Можете ли вы сбросить SERIAL, как вы делаете для SEQUENCE?
Торок
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) 
user5838061
источник
Можно ли сделать первичный ключ (существующий столбец) в таблице без добавления какого-либо нового столбца
Satish kilari