PostgreSQL dispose des types de données smallserial, serial et bigserial ; ce ne sont pas de véritables types, mais simplement une commodité de notation pour créer des colonnes d'identifiants uniques. Ils sont similaires à la propriété AUTO_INCREMENT supportée par certaines autres bases de données.

Si vous souhaitez qu'une colonne serial ait une contrainte unique ou soit une clé primaire, elle doit être spécifiée comme tout autre type de données.

Le nom de type smallserial crée une colonne smallint, serial crée une colonne de type integer et bigserial crée une colonne bigint.

Syntaxe
CREATE TABLE tablename ( <nom de colonne> SERIAL );
Exemple

Considérons une table d'information nommé SYS_INFOS :

psql#> CREATE TABLE sys_infos (
   id_info SERIAL PRIMARY KEY,
   when_info timestamp without time zone NOT NULL,
   detail_info TEXT
) ;

Puis nous ajoutons des enregistrements sans spécifier la valeur de la colonne id_info :

psql#> insert into sys_infos (when_info, detail_info) values (now(), 'message systeme 1');
psql#> insert into sys_infos (when_info, detail_info) values (now(), 'message systeme 2');
psql#> insert into sys_infos (when_info, detail_info) values (now(), 'message systeme 3');

Nous obtenons :

psql#> select * from sys_infos;
 id_info |         when_info          |    detail_info
---------+----------------------------+-------------------
       1 | 2022-07-19 18:52:36.78417  | message systeme 1
       2 | 2022-07-19 18:52:45.194683 | message systeme 2
       3 | 2022-07-19 18:52:47.380043 | message systeme 3
(3 rows)

Si la table est vidée avec un TRUNCATE, l'index suivant est conservé :

psql#> truncate table sys_infos;
TRUNCATE TABLE
psql#> insert into sys_infos (when_info, detail_info) values (now(), 'message systeme x');
INSERT 0 1
psql#> select * from sys_infos;
 id_info |         when_info          |    detail_info
---------+----------------------------+-------------------
       4 | 2022-07-19 18:54:13.273644 | message systeme x
(1 row)

Attention, si la valeur de l'index est précisé avec une valeur supérieure à l'index courant, la ligne est insérée normalement, mais lors de nouvelles insertions sans préciser la valeur de l'index, on obtient une violation de contrainte.

psql#> insert into sys_infos values (6, now(), 'message six');
psql#> select * from sys_infos;
 id_info |         when_info          |    detail_info
---------+----------------------------+-------------------
       4 | 2022-07-19 18:54:13.273644 | message systeme x
       6 | 2022-07-19 18:55:17.125493 | message six

psql#> insert into sys_infos (when_info, detail_info) values (now(), 'message systeme suivant');
psql#> select * from sys_infos;
 id_info |         when_info          |    detail_info
---------+----------------------------+-------------------
       4 | 2022-07-19 18:54:13.273644 | message systeme x
       5 | 2022-07-19 18:56:53.439211 | message suivant
       6 | 2022-07-19 18:55:17.125493 | message six

psql#> insert into sys_infos (when_info, detail_info) values (now(), 'message systeme suivant');
ERROR:  duplicate key value violates unique constraint "sys_infos_pkey"
DETAIL:  Key (id_info)=(6) already exists.