Skip to main content

CREATE TABLE

Create a new table in the database with column definitions, data types, and constraints.

Syntax

Column Definition

Column Constraints

Table Constraints

Description

CREATE TABLE defines a new table in the database. The table name must be unique within the database schema. Each table consists of one or more column definitions and optional table-level constraints.

Parameters

Column Definitions

Each column definition specifies a column name, an optional type, and zero or more column constraints. When no type is specified, the column accepts any storage class. When a type name is provided, it determines the column’s type affinity, which influences how inserted values are stored.

Column Constraints

PRIMARY KEY

Designates a column as the table’s primary key. A table can have at most one primary key.
When a column is declared as INTEGER PRIMARY KEY, it becomes an alias for the internal rowid, and inserted integer values are used as the row identifier directly. This is the most efficient primary key form.

AUTOINCREMENT

The AUTOINCREMENT keyword can only be used with INTEGER PRIMARY KEY. It prevents the reuse of rowid values from previously deleted rows by maintaining a counter in the sqlite_sequence system table.
Without AUTOINCREMENT, Turso may reuse rowid values after rows are deleted. With AUTOINCREMENT, automatically generated rowids are greater than any rowid that has ever existed in a committed row for the table, even if rows have been deleted.
AUTOINCREMENT adds minor overhead because it maintains a committed high-water mark. Rolled-back inserts do not have to permanently burn their generated rowids, but gaps are still possible when concurrent transactions commit later generated values.
AUTOINCREMENT under MVCC (journal_mode=experimental_mvcc): sqlite_sequence is updated lazily — only when the WAL is checkpointed. Between checkpoints it may lag the actual high-water mark or be empty for a freshly-created AUTOINCREMENT table. Do not rely on sqlite_sequence to recover the current value in MVCC mode. Instead, query the internal sequence backing table directly:
This row is updated immediately by every committed (and durably-burnt) nextval. After PRAGMA wal_checkpoint(TRUNCATE), sqlite_sequence is coalesced to a single row per AUTOINCREMENT table and is then safe to read with normal SQLite-compatible queries.Note also that MVCC autoincrement does not un-burn rolled-back rowids — a ROLLBACK after INSERT leaves a gap rather than recycling the rowid. SQLite WAL mode and Turso’s WAL mode both un-burn on rollback; only MVCC mode keeps them burnt.

NOT NULL

Prevents the column from containing NULL values. Any INSERT or UPDATE that would set the column to NULL raises a constraint error.

UNIQUE

Ensures that all values in the column are distinct. NULL values are considered distinct from each other (multiple NULL values are allowed in a UNIQUE column).

DEFAULT

Specifies a default value for the column when an INSERT statement does not provide one.
The default expression can be:

CHECK

Defines a boolean expression that must evaluate to true (or NULL) for every row in the table. The expression can reference any column in the same row.

REFERENCES (Foreign Key)

Establishes a foreign key relationship between a column and a column in another table. See Foreign Key Constraints for the full syntax.

COLLATE

Specifies the collation sequence used for text comparisons and sorting on the column. Turso also resolves locale-aware collations and custom collations registered on the connection. An unknown collation name now raises a no such collation sequence error rather than being silently ignored.

Table Constraints

Table constraints apply to one or more columns and are specified after all column definitions.

Composite PRIMARY KEY

Defines a primary key spanning multiple columns. Each combination of values across the key columns must be unique.

Composite UNIQUE

Ensures that each combination of values across the specified columns is unique.

Table-Level CHECK

A CHECK constraint at the table level can reference multiple columns.

Foreign Key Constraints

Foreign key constraints enforce referential integrity between tables. They ensure that values in the child table correspond to existing values in the parent table.
Foreign key enforcement is off by default. Enable it with PRAGMA foreign_keys = ON; before performing operations that should be checked.

Syntax

Foreign Key Actions

The ON DELETE and ON UPDATE clauses specify what happens to child rows when a referenced parent row is deleted or updated.

STRICT Tables

STRICT tables enforce type checking at the storage layer. Every value inserted into a STRICT column must match the declared column type or be losslessly convertible to that type.

Allowed Column Types

STRICT tables only allow these base column types: Every column in a STRICT table must have an explicit type declaration.
Turso Extension: STRICT tables also support custom types defined with CREATE TYPE and array types. Custom types extend the type system with user-defined encoding, decoding, validation, and operator overloading. Array columns are declared by appending [] to a base type.

Unsupported Features

The following CREATE TABLE features are not yet supported:

Experimental Features

The following are available behind experimental feature flags:

Examples

Basic Table with Constraints

Table with Foreign Keys and CHECK Constraints

STRICT Table

Composite Primary Key with Foreign Keys

IF NOT EXISTS

See Also