Skip to main content

Column Types and Constraints

Columns define the structure of your tables. Each column has a type and can have constraints that enforce data integrity.

Column Types

SpacetimeDB supports a variety of column types optimized for performance.

Primitive Types

TypeDescription
boolBoolean value
StringUTF-8 string
f32, f64Floating point numbers
i8 through i128Signed integers
u8 through u128Unsigned integers

Special Types

Structured Types

TypeDescription
enum with #[derive(SpacetimeType)]Sum type/tagged union
Option<T>Optional value
Vec<T>Vector of elements

Special Types

TypeDescription
IdentityUnique identity for authentication
ConnectionIdClient connection identifier
TimestampAbsolute point in time (microseconds since Unix epoch)
DurationRelative duration
ScheduleAtWhen a scheduled reducer should execute (either Time(Timestamp) or Interval(Duration))

Column Constraints

Unique Columns

Mark columns as unique to ensure only one row can exist with a given value.

#[spacetimedb::table(name = user, public)]
pub struct User {
    #[primary_key]
    id: u32,
    #[unique]
    email: String,
    #[unique]
    username: String,
}

Primary Key

A table can have one primary key column. The primary key represents the identity of the row. Changes that don't affect the primary key are updates; changes to the primary key are treated as delete + insert.

Only one column can be marked as a primary key, but multiple columns can be marked unique.

Auto-Increment Columns

Use auto-increment for automatically increasing integer identifiers. Inserting a row with a zero value causes the database to assign a new unique value.

#[spacetimedb::table(name = post, public)]
pub struct Post {
    #[primary_key]
    #[auto_inc]
    id: u64,
    title: String,
}

#[spacetimedb::reducer]
fn add_post(ctx: &ReducerContext, title: String) -> Result<(), String> {
    let inserted = ctx.db.post().insert(Post { id: 0, title })?;
    // inserted.id now contains the assigned auto-incremented value
    Ok(())
}