简要提示:在大多数情况下,自增列(auto-increment columns)通常用作主键(Primary Key)。但根据 SQL 标准,这两者的结合不是强制性的


SQL 标准

SQL 标准规定了两种生成自增值的方法:

  1. 标识列(Identity Columns):作为精确数值类型的扩展,语法如下:

    GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY
    
  2. 序列(Sequence)+ 触发器(Trigger):标准化的方法之一,通过触发器使用序列生成值。

示例:

CREATE TABLE t1 (col1 DECIMAL GENERATED ALWAYS AS IDENTITY);

DB2

支持使用标识列或序列加触发器(两种方式都常用):

CREATE TABLE t1 (col1 INT GENERATED ALWAYS AS IDENTITY);

或者:

CREATE TABLE t1 (col1 INT);
CREATE SEQUENCE sequence_name;
CREATE TRIGGER insert_trigger
       NO CASCADE BEFORE INSERT ON t1
       REFERENCING NEW AS n
       FOR EACH ROW
  SET n.col1 = NEXTVAL FOR sequence_name;

Firebird

推荐使用序列 + 触发器方式。从版本 3.0 起开始支持 Identity 语法。

SET TERM  ^;
CREATE TABLE t1(col1 INTEGER NOT NULL PRIMARY KEY)^
CREATE SEQUENCE sequence_name^
ALTER SEQUENCE sequence_name RESTART WITH 0^

CREATE TRIGGER trigger_name FOR t1
BEFORE INSERT
AS
BEGIN
  NEW.col1 = NEXT VALUE FOR sequence_name;
END^

Linter

支持 AUTOINC 列(可带范围)或序列与触发器结合的方式。

CREATE TABLE t1 (col1 SMALLINT AUTOINC);
CREATE TABLE t2 (col1 INTEGER AUTOINC);
CREATE TABLE t3 (col1 BIGINT AUTOINC);

MonetDB

支持多种方式:

CREATE SEQUENCE sequence_name AS INT START WITH 1 INCREMENT BY 1;

CREATE TABLE t1 (
  col1 BIGINT PRIMARY KEY DEFAULT NEXT VALUE FOR sequence_name,
  col2 BIGINT AUTO_INCREMENT, 
  col3 BIGINT GENERATED ALWAYS AS IDENTITY (
           START WITH 100 INCREMENT BY 2
           NO MINVALUE MAXVALUE 1000
           CACHE 2 CYCLE)
);

也支持 SERIALBIGSERIAL(自动创建序列):

CREATE TABLE ts (
  col1 SERIAL,
  ...
);

CREATE TABLE tbs (
  col1 BIGSERIAL,
  ...
);

MSSQL(Microsoft SQL Server)

使用 IDENTITY(start, increment) 语法:

CREATE TABLE t1 (col1 INT IDENTITY(1,1));

MySQL

使用 AUTO_INCREMENT 关键字,必须配合 PRIMARY KEYUNIQUE

CREATE TABLE t1 (col1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT);

OpenLink Virtuoso

支持 IDENTITY 语法:

CREATE TABLE t1 (col1 INTEGER IDENTITY);
-- 或:
CREATE TABLE t1 (col1 INTEGER IDENTITY (start with 1));

Oracle

传统方式是使用序列和触发器:

CREATE TABLE t1 (col1 NUMBER PRIMARY KEY);
CREATE SEQUENCE sequence_name START WITH 1 INCREMENT BY 1;

CREATE OR REPLACE TRIGGER trigger_name BEFORE INSERT ON t1 FOR EACH ROW
DECLARE
  max_id NUMBER;
  cur_seq NUMBER;
BEGIN
IF :NEW.col1 IS NULL THEN
  :NEW.col1 := sequence_name.NEXTVAL;
ELSE
  SELECT GREATEST(COALESCE(MAX(col1), 0), :NEW.col1) INTO max_id FROM t1;
  WHILE cur_seq < max_id LOOP
    SELECT sequence_name.NEXTVAL INTO cur_seq FROM DUAL;
  END LOOP;
END IF;
END;

Oracle 12.1 起支持 IDENTITY

CREATE TABLE t1 (col1 NUMBER GENERATED BY DEFAULT AS IDENTITY);

PostgreSQL

传统方式使用 serial 类型(自动创建序列并设默认值):

CREATE TABLE t1 (col1 serial PRIMARY KEY);

PostgreSQL 10 起支持标准语法:

CREATE TABLE t1 (col1 integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY);

SQLite

两种方式均可实现自增主键:

CREATE TABLE t1 (col1 INTEGER PRIMARY KEY);  -- 自动自增
CREATE TABLE t1 (col1 INTEGER PRIMARY KEY AUTOINCREMENT);  -- 避免重用删除的值

最后修改: 2025年04月11日 星期五 10:39