SQL identity columns
Autoincrementing columns, identity columns, serial columns, whatever you call it, this is clearly a popular feature in SQL databases, but with a bunch of different syntaxes. At least historically.
In SQL:2003, a syntax for this was standardized, which has been adopted slowly across more implementations:
CREATE TABLE t1 (
a int GENERATED ALWAYS AS IDENTITY,
...
);
with some variations and additional options not shown here.
This has by now been adopted by a number of implementations:
Implementation | Syntax | Notes |
---|---|---|
Apache Derby | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY |
docs |
Databricks | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY |
docs |
Db2 | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY |
docs |
H2 | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY |
docs |
Ingres | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY |
docs |
Oracle | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY |
docs; since Oracle 12 |
PostgreSQL | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY |
docs; since PostgreSQL 10 |
(Some of the implementations that support the SQL standard syntax also support their own legacy syntax.)
But while the landscape is better than 20 years ago (it’s also bigger), not all implementations are caught up:
Implementation | Syntax | Notes |
---|---|---|
MariaDB | AUTO_INCREMENT |
docs |
Microsoft SQL Server | IDENTITY |
docs |
MySQL | AUTO_INCREMENT |
docs |
Snowflake | IDENTITY or AUTOINCREMENT |
docs |
SQLite | AUTOINCREMENT |
docs; not recommended |
Ok, so there are two and a half nonstandard variants here.
Note that the standardization in SQL does not only cover the syntax but also questions like, what happens if you insert into an autoincrementing column manually, what happens when you copy a table containing such a column, how do these columns interact with triggers, which data types are supported, and so on. Hopefully, those who have adopted the standard syntax have also looked into those issues. Reading through the documentation of the nonstandard ones, there is quite a bit of variation there.
Finally, paging Markus Winand to add a page about this on https://modern-sql.com/. There is already a good page about generated columns, which are adjacent to this.