Data Model
Overview
The data model is the foundation of your Monospace workspace. It defines how your data is structured, how it connects, and how users interact with it. Everything in Monospace builds on top of the data model — permissions, APIs, content management, and spaces all reference it.
When you connect a data source, Monospace introspects the database and maps its schema into collections, fields, and relations. You choose which namespaces and collections to import. You can also create new collections directly from the Studio.
Collections
A collection represents a table or data structure within a data source — for example, customers, orders, or products. Collections are the primary unit you interact with across Monospace:
- Content — browse, create, and edit items
- Permissions — policies grant access at the collection level
- APIs — query collections across multiple data sources in a single call
Fields
Fields are the columns or attributes within a collection (e.g., email, price, created_at). Each field has a data type that defines what it stores:
| Category | Types |
|---|---|
| Text | String, UUID |
| Numeric | Integer (8-, 16-, and 32-bit), Long Integer, their unsigned variants, Float, Double, Decimal |
| Boolean | Boolean |
| Date & Time | Date, Time, Date & Time, Date & Time with Timezone |
| Structured | JSON |
| Binary | Binary |
Monospace detects fields and their types automatically during introspection. Fields can be customized with Interfaces that control how they are displayed and edited in the Studio.
Default Values
A primitive field can carry a default value, applied when an item is created without a value for that field. Defaults come from one of two places.
Managed by database — the connected database supplies the value, including an auto-increment sequence. Introspection preserves the existing default. Auto-Generate on an integer primary key configures an auto-increment default managed by the connector.
Managed by Monospace — the engine resolves the value as it writes:
| Source | Where you configure it | Resolves to |
|---|---|---|
| Static value | The field's Default Value setting | The value you enter |
| Random UUID | Auto-Generate on a UUID primary key | A new version 7 UUID |
| Current timestamp | The Created At or Updated At special field | The time of the write |
| Current user | The Created By or Updated By special field | The acting user's ID |
Auto-Generate and Special Fields are offered when you create a collection. Created At and Created By resolve on create only; Updated At and Updated By resolve on create and on every later change.
Auto-generated UUID keys use version 7, which is time-ordered — keys generated later sort after earlier ones.
Relations
Relations define how collections are connected through foreign keys. For example, an Orders collection can reference Customers through a customer_id field.
A direct relation stores a foreign key on one collection and points to fields on another. The referenced field set must have a primary key or unique index, ensuring each item resolves to at most one referenced item.
| Relation | Structure |
|---|---|
| To-one | An item stores a foreign key that points to one referenced item |
| To-many | The reverse of a to-one relation, returning every item with the matching foreign key |
| One-to-one | A to-one relation whose foreign key also has a unique index |
| Many-to-many | Two to-one relations connect both collections through a junction collection |
In a many-to-many relation, each junction foreign key can repeat independently. Use a composite primary key or unique index across both foreign keys to prevent duplicate links. The Studio creates this composite primary key when it creates a junction collection.
Relations work across data sources, enabling federated queries that connect data from different databases without replication. Cross-data-source relations are resolved at query time without foreign key enforcement. See Cross-Data-Source Referential Integrity.
This walkthrough relates a PostgreSQL CRM to a MySQL customer portal in the Studio, then filters across both in one request.
Relational Field Types
Three field types create a relation. The one you choose determines what the field points at.
| Field type | Points at | Options |
|---|---|---|
| Relation | A collection you choose | Every relation type above |
| File | Stored assets | Single File, Multiple Files |
| User | Workspace members | Single User, Multiple Users |
File and User target collections Monospace manages for you, so you pick the field type rather than choosing a target collection.
Single User also offers Exclusive, which allows each member to be referenced by only one item and makes the relation one-to-one. A dynamic filter can reach through a relation built that way.
Working with Related Items
When you pick a related item in the Studio — setting an article's author, for example — the picker lists items from the related collection and links the one you choose. A relation does not have to point at the related collection's primary key; when it references another field, the Studio matches on that field instead.
You can also filter a collection by a related item. Pick the specific related item you want to match, and the Studio builds the filter against the relation rather than asking you to know the underlying key.
Interfaces
While a field defines what data is stored, an interface defines how users interact with that data in the Studio. For example, a text field could use a simple input, a textarea, or a slug input. A number field could use a numeric input or a slider.
Monospace automatically assigns a default interface based on each field's data type. You can change the interface for any field in the Data Model settings.
Input Interfaces
Input interfaces control how fields appear in forms when creating or editing items.
| Interface | Field Types | Description |
|---|---|---|
| Text Input | Text, Identifier | Single-line text input |
| Textarea | Text | Multi-line text input |
| Number Input | Number, Identifier | Numeric input with min/max |
| Decimal Input | Number | Input for decimal numbers, with precision and scale |
| Slider | Number | Range slider |
| Select Input | Select | Dropdown menu |
| Radio Input | Select | Radio button group (single selection) |
| Tile Radio Input | Select | Visual tile-based selection (single selection) |
| Checkbox Input | Select | Checkbox group (multiple selection) |
| Toggle | Boolean | Toggle switch |
| Color Picker | Color | Color picker |
| Slug Input | Slug, Identifier | URL-friendly slug input |
| UUID Input | Identifier | Show or generate a UUID |
| Date Input | Date & Time | Date picker |
| Date & Time Input | Date & Time | Date and time picker |
| Time Input | Date & Time | Time picker |
| Code | JSON | Syntax-highlighted code editor |
Relational Interfaces
| Interface | Relation Type | Description |
|---|---|---|
| Relational Field (Many-to-One) | Many-to-One | Reference a single item from another collection |
| Relational Field (One-to-Many) | One-to-Many | Reference multiple items from another collection |
| Relational Field (Many-to-Many) | Many-to-Many | Reference multiple items through a junction collection |
| File Relation (Many-to-One) | Many-to-One | Reference a single file from the assets library |
| File Relation (Many-to-Many) | Many-to-Many | Reference multiple files through a junction collection |
| User Relation (Many-to-One) | Many-to-One | Reference a single workspace member |
| User Relation (Many-to-Many) | Many-to-Many | Reference multiple workspace members through a junction collection |
Default Interfaces
Each field data type has a default input and display interface:
| Data Type | Default Input | Default Display |
|---|---|---|
| Text | Text Input | Formatted Value |
| Number | Number Input (Decimal Input for decimals) | Formatted Value |
| Boolean | Toggle | Display Boolean |
| Color | Color Picker | Color Value |
| Relation | Relational Field (Many-to-One, One-to-Many, or Many-to-Many) | Related Value |