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
- Rust
- C#
- TypeScript
| Type | Description |
|---|---|
bool | Boolean value |
String | UTF-8 string |
f32, f64 | Floating point numbers |
i8 through i128 | Signed integers |
u8 through u128 | Unsigned integers |
| Type | Description |
|---|---|
bool | Boolean value |
string | UTF-8 string |
float, double | Floating point numbers |
sbyte, short, int, long | Signed integers (8-bit to 64-bit) |
byte, ushort, uint, ulong | Unsigned integers (8-bit to 64-bit) |
SpacetimeDB.I128, SpacetimeDB.I256 | Signed 128-bit and 256-bit integers |
SpacetimeDB.U128, SpacetimeDB.U256 | Unsigned 128-bit and 256-bit integers |
| Type | Returns | TypeScript Type | Description |
|---|---|---|---|
t.bool() | BoolBuilder | boolean | Boolean value |
t.string() | StringBuilder | string | UTF-8 string |
t.f32() | F32Builder | number | 32-bit floating point |
t.f64() | F64Builder | number | 64-bit floating point |
t.i8() | I8Builder | number | Signed 8-bit integer |
t.u8() | U8Builder | number | Unsigned 8-bit integer |
t.i16() | I16Builder | number | Signed 16-bit integer |
t.u16() | U16Builder | number | Unsigned 16-bit integer |
t.i32() | I32Builder | number | Signed 32-bit integer |
t.u32() | U32Builder | number | Unsigned 32-bit integer |
t.i64() | I64Builder | bigint | Signed 64-bit integer |
t.u64() | U64Builder | bigint | Unsigned 64-bit integer |
t.i128() | I128Builder | bigint | Signed 128-bit integer |
t.u128() | U128Builder | bigint | Unsigned 128-bit integer |
t.i256() | I256Builder | bigint | Signed 256-bit integer |
t.u256() | U256Builder | bigint | Unsigned 256-bit integer |
Special Types
- Rust
- C#
- TypeScript
Structured Types
| Type | Description |
|---|---|
enum with #[derive(SpacetimeType)] | Sum type/tagged union |
Option<T> | Optional value |
Vec<T> | Vector of elements |
Special Types
| Type | Description |
|---|---|
Identity | Unique identity for authentication |
ConnectionId | Client connection identifier |
Timestamp | Absolute point in time (microseconds since Unix epoch) |
Duration | Relative duration |
ScheduleAt | When a scheduled reducer should execute (either Time(Timestamp) or Interval(Duration)) |
Structured Types
| Type | Description |
|---|---|
TaggedEnum<Variants> | Tagged union/enum type for sum types |
T? | Nullable/optional value |
List<T> | List of elements |
Special Types
| Type | Description |
|---|---|
Identity | Unique identity for authentication |
ConnectionId | Client connection identifier |
Timestamp | Absolute point in time (microseconds since Unix epoch) |
TimeDuration | Relative duration in microseconds |
ScheduleAt | When a scheduled reducer should execute (either at a specific time or at repeating intervals) |
Structured Types
| Type | Returns | TypeScript Type | Description |
|---|---|---|---|
t.object(name, obj) | ProductBuilder<Obj> | { [K in keyof Obj]: T<Obj[K]> } | Product/object type for nested or structured data |
t.row(obj) | RowBuilder<Obj> | { [K in keyof Obj]: T<Obj[K]> } | Row type for table schemas (allows column metadata) |
t.enum(name, variants) | SumBuilder<Obj> or SimpleSumBuilder | { tag: 'variant' } | { tag: 'variant', value: T } | Sum/enum type (tagged union or simple enum) |
t.array(element) | ArrayBuilder<Element> | T<Element>[] | Array of the given element type |
t.unit() | UnitBuilder | {} or undefined | Zero-field product type (unit) |
t.option(value) | OptionBuilder<Value> | Value | undefined | Optional value type |
Special Types
| Type | Returns | TypeScript Type | Description |
|---|---|---|---|
t.identity() | IdentityBuilder | Identity | Unique identity for authentication |
t.connectionId() | ConnectionIdBuilder | ConnectionId | Client connection identifier |
t.timestamp() | TimestampBuilder | Timestamp | Absolute point in time (microseconds since Unix epoch) |
t.timeDuration() | TimeDurationBuilder | TimeDuration | Relative duration in microseconds |
t.scheduleAt() | ColumnBuilder<ScheduleAt, …> | ScheduleAt | Special column type for scheduling reducer execution |
Column Constraints
Unique Columns
Mark columns as unique to ensure only one row can exist with a given value.
- Rust
- C#
- TypeScript
#[spacetimedb::table(name = user, public)]
pub struct User {
#[primary_key]
id: u32,
#[unique]
email: String,
#[unique]
username: String,
}[SpacetimeDB.Table(Name = "user", Public = true)]
public partial struct User
{
[SpacetimeDB.PrimaryKey]
public uint Id;
[SpacetimeDB.Unique]
public string Email;
[SpacetimeDB.Unique]
public string Username;
}const user = table(
{ name: 'user', public: true },
{
id: t.u32().primaryKey(),
email: t.string().unique(),
username: t.string().unique(),
}
);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.
- Rust
- C#
- TypeScript
#[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(())
}[SpacetimeDB.Table(Name = "post", Public = true)]
public partial struct Post
{
[SpacetimeDB.PrimaryKey]
[SpacetimeDB.AutoInc]
public ulong Id;
public string Title;
}
[SpacetimeDB.Reducer]
public static void AddPost(ReducerContext ctx, string title)
{
var inserted = ctx.Db.post.Insert(new Post { Id = 0, Title = title });
// inserted.Id now contains the assigned auto-incremented value
}const post = table(
{ name: 'post', public: true },
{
id: t.u64().primaryKey().autoInc(),
title: t.string(),
}
);
const spacetimedb = schema(post);
spacetimedb.reducer('add_post', { title: t.string() }, (ctx, { title }) => {
const inserted = ctx.db.post.insert({ id: 0, title });
// inserted.id now contains the assigned auto-incremented value
});