Primary Keys and Serial Columns in Drizzle
How SQL PRIMARY KEY, SERIAL, BIGSERIAL, and AUTO_INCREMENT columns map to Drizzle ORM's primaryKey chain and serial column builders across dialects.
Detailed Explanation
Primary Keys in Drizzle
Primary keys are the most fundamental constraint in any database table. Drizzle provides several ways to define them depending on the column type and whether the key is simple or composite.
Simple Primary Key with SERIAL
PostgreSQL:
CREATE TABLE users (
id SERIAL PRIMARY KEY
);
import { pgTable, serial } from "drizzle-orm/pg-core";
export const users = pgTable("users", {
id: serial("id").primaryKey(),
});
The serial() builder in Drizzle's pg-core implicitly makes the column NOT NULL and auto-incrementing, just like PostgreSQL's SERIAL type.
MySQL AUTO_INCREMENT
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY
);
import { mysqlTable, serial } from "drizzle-orm/mysql-core";
export const users = mysqlTable("users", {
id: serial("id").primaryKey(),
});
MySQL's serial() maps to BIGINT UNSIGNED NOT NULL AUTO_INCREMENT.
UUID Primary Key
CREATE TABLE documents (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY
);
import { pgTable, uuid } from "drizzle-orm/pg-core";
import { sql } from "drizzle-orm";
export const documents = pgTable("documents", {
id: uuid("id").default(sql`gen_random_uuid()`).primaryKey(),
});
BIGSERIAL for Large Tables
CREATE TABLE events (
id BIGSERIAL PRIMARY KEY
);
import { bigserial, pgTable } from "drizzle-orm/pg-core";
export const events = pgTable("events", {
id: bigserial("id", { mode: "number" }).primaryKey(),
});
Composite Primary Key
When a table has a multi-column primary key, individual columns do not get .primaryKey(). Instead, a primaryKey() constraint is added in the table's third argument:
import { integer, pgTable, primaryKey } from "drizzle-orm/pg-core";
export const postTags = pgTable("post_tags", {
postId: integer("post_id").notNull(),
tagId: integer("tag_id").notNull(),
}, (table) => [
primaryKey({ columns: [table.postId, table.tagId] }),
]);
SQLite Primary Key
In SQLite, INTEGER PRIMARY KEY creates an alias for the ROWID, which auto-increments by default. The AUTOINCREMENT keyword only prevents rowid reuse and is not needed for basic auto-incrementing behavior.
Use Case
You need to understand how different primary key strategies (serial, UUID, bigserial, composite) translate from SQL to Drizzle ORM across different database dialects.