¿Cómo configurar la clave primaria de incremento automático en PostgreSQL?

259

Tengo una tabla en PostgreSQL con 22 columnas, y quiero agregar una clave primaria de incremento automático.

Traté de crear una columna llamada idde tipo BIGSERIAL pero pgadmin respondió con un error:

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

¿Alguien sabe cómo solucionar este problema? ¿Cómo agrego un crear una clave primaria de incremento automático en PostgreSQL sin volver a crear la tabla?

mkn
fuente

Respuestas:

292

Prueba este comando:

ALTER TABLE your_table ADD COLUMN key_column BIGSERIAL PRIMARY KEY;

Pruébelo con el mismo usuario DB que creó la tabla.

AH
fuente
75
(la clave aquí es usar un tipo de datos SERIAL o BIGSERIAL, que crea una secuencia detrás de escena y la incrementa / usa en el momento de la inserción)
rogerdpack
16
y si desea hacer referencia a él desde otra tabla, use integer o bigint
Ward
2
@satishkilari: sí, la sintaxis es ALTER TABLE mytable ADD PRIMARY KEY (column);. Postgresql verificará que la columna no contenga NULL.
AH
3
Obteniendo este error en pgAdmin 4. Ambos bigserialy serialestán dando el mismo error:ERROR: syntax error at or near "BIGSERIAL"
adi
55
También obteniendo el error de sintaxis usando bigserial o serial. ¿Existe una versión mínima de postgresql para esto?
dacDave
251

Clave primaria de incremento automático en postgresql:

Paso 1, crea tu tabla:

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

Paso 2, inserte valores en su tabla de esta manera, observe que mytable_key no se especifica en la primera lista de parámetros, esto hace que la secuencia predeterminada se incremente automáticamente.

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

Paso 3, selecciona * de tu tabla:

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

Paso 4, interpreta la salida:

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

Observe que la columna mytable_key se ha incrementado automáticamente.

ProTip:

Siempre debe usar una clave principal en su tabla porque postgresql usa internamente estructuras de tabla hash para aumentar la velocidad de las inserciones, eliminaciones, actualizaciones y selecciones. Si hay disponible una columna de clave primaria (que es forzada única y no nula), se puede confiar en que proporcionará una semilla única para la función hash. Si no hay una columna de clave principal disponible, la función hash se vuelve ineficiente ya que selecciona algún otro conjunto de columnas como clave.

Eric Leschinski
fuente
21
Un pequeño detalle, SERIALcrea un sequencedetrás de escena: postgresql.org/docs/9.2/static/…
carbocation
1
¿es posible hacer una clave primaria (columna existente) en una tabla sin agregar ninguna columna nueva
satish kilari
será una clave foránea declarada con thing_id int references epictable(mytable_key)trabajo?
36

Cree una clave primaria de incremento automático en postgresql, utilizando una secuencia personalizada:

Paso 1, crea tu secuencia:

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

Paso 2, crea tu tabla

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

Paso 3, inserta en tu mesa

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

Paso 4, observa las filas

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)

Las dos filas tienen claves que comienzan en 1 y se incrementan en 1, según lo definido por la secuencia.

Bonificación Elite ProTip:

Los programadores odian escribir, y escribirlo nextval('splog_adfarm_seq')es molesto. Puede escribir DEFAULTpara ese parámetro en su lugar, así:

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

Para que lo anterior funcione, debe definir un valor predeterminado para esa columna clave en la tabla splog_adfarm. Lo cual es más bonito.

Eric Leschinski
fuente
2
¿Cuáles son los beneficios de las secuencias personalizadas? Probablemente, seguridad?
Léo Léopold Hertz 준영
1
@Masi Un uso de una secuencia personalizada podría ser facilitar la replicación maestro-maestro, lo que sería útil si se rompe el enlace de datos entre dos centros de datos, lo que permite crear registros en ambos servidores con diferentes ID, que luego facilita la sincronización de las bases de datos mientras se mantienen los identificadores generados en ubicaciones separadas.
Vincent McNabb
16

Si quieres hacer esto en pgadmin, es mucho más fácil. Parece que en postgressql, para agregar un incremento automático a una columna, primero debemos crear una secuencia de incremento automático y agregarla a la columna requerida. Me gustó esto.

1) En primer lugar, debe asegurarse de que haya una clave principal para su tabla. También mantenga el tipo de datos de la clave primaria en bigint o smallint. (Utilicé bigint, no pude encontrar un tipo de datos llamado serial como se menciona en otras respuestas en otro lugar)

2) Luego agregue una secuencia haciendo clic derecho en secuencia-> agregar nueva secuencia . Si no hay datos en la tabla, deje la secuencia como está, no realice ningún cambio. Solo guárdalo. Si hay datos existentes, agregue el último valor o el más alto en la columna de clave principal al valor Actual en la pestaña Definiciones como se muestra a continuación. ingrese la descripción de la imagen aquí

3) Finalmente, agregue la línea nextval('your_sequence_name'::regclass)al valor predeterminado en su clave principal como se muestra a continuación.

ingrese la descripción de la imagen aquí Asegúrese de que el nombre de la secuencia sea correcto aquí. Esto es todo y el incremento automático debería funcionar.

toing_toing
fuente
9

Si desea usar números en una secuencia, defina una nueva secuencia con algo como

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

y luego modifique la tabla para usar la secuencia para la identificación:

ALTER TABLE ONLY table ALTER COLUMN id SET DEFAULT nextval('your_sequence'::regclass);
acaruci
fuente
¿Tengo que crear una nueva secuencia para cada tabla?
Bharat Chhabra
Puede compartir la misma secuencia para diferentes tablas, pero la secuencia aumentará para cada registro en cada tabla.
acaruci
1

He intentado el siguiente script para aumentar automáticamente con éxito la clave primaria en 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)
);

EDITAR:

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

La palabra clave SERIAL crea automáticamente una secuencia para la columna respectiva.

Asad Shakeel
fuente
Sin embargo, ¿puedes restablecer un SERIAL como lo haces para una SECUENCIA?
thoroc
1
¡Sí !, lo he comprobado ALTER SEQUENCE dummytable_id_seq RESTART WITH 1;y está funcionando.
Asad Shakeel
0

Tal vez llego un poco tarde para responder esta pregunta, pero estoy trabajando en este tema en mi trabajo :)

Quería escribir la columna 'a_code' = c1, c2, c3, c4 ...

Primero abrí una columna con el nombre ref_idy el tipo serial. Entonces resolví mi problema con este comando:

update myschema.mytable set a_code=cast('c'||"ref_id" as text) 
usuario5838061
fuente
¿es posible hacer una clave primaria (columna existente) en una tabla sin agregar ninguna columna nueva
satish kilari