DEFINE FIELD
DEFINE FIELD
Level 4 — Schema Definition & Constraints The DDL (Data Definition Language) statement in SurrealDB used to configure schemas and types for specific record fields on a table, supporting nested dot-notation paths and field-level permissions.
1. Prerequisites
DEFINE TABLE— The parent schema context.- Data Types (Overview) — The type definitions.
2. Term Category
Schema & Modeling (table field definition statement): - Database Command / Tool
3. Explanation
(1) Design Motivation — "Why did we design this?"
In SQL databases (PostgreSQL), columns are defined inside the CREATE TABLE statement.
- This works for simple tables.
- However, if you want to add columns, write separate validation constraints, or set different permissions per column, managing the schema becomes difficult.
In MongoDB, document validation requires writing complex JSON schemas.
We designed the DEFINE FIELD statement in SurrealQL to provide a modular, granular schema builder.
Instead of writing a single, massive table definition query, you declare fields one-by-one.
This keeps schema updates clean.
It supports dot-notation nested paths, maps strict data types (like TYPE array<string>), and allows you to write access permissions for individual fields, providing field-level security out of the box.
(2) Field-Level Security
You can restrict access to specific fields using the PERMISSIONS clause on the field declaration:
DEFINE FIELD social_security ON user TYPE string PERMISSIONS FOR select WHERE id = $auth.id;
- Result: Other users can query the
usertable and see names, but only the owner can retrieve their own social security field!
(3) Reality Metaphor (Filing Dividers)
Imagine organizing folders inside a cabinet drawer (table):
DEFINE FIELD: Installing a Physical Divider Partition inside the drawer.- You label the slot
ageON user. - You write a rule on the divider slot:
TYPE int. - Only whole numbers are allowed inside this slot.
- If you try to drop a pair of keys (an object) or a letter (a string) into the slot, the divider's guide blocks it.
- You label the slot
(4) Code Examples
Defining Fields in SurrealQL
Let's build a complete member details schema:
DEFINE TABLE member SCHEMAFULL;
-- 1. Define standard primitive fields
DEFINE FIELD username ON member TYPE string;
DEFINE FIELD points ON member TYPE int;
-- 2. Define nested properties inside a settings object (dot notation!)
DEFINE FIELD settings ON member TYPE object;
DEFINE FIELD settings.theme ON member TYPE string;
DEFINE FIELD settings.marketing ON member TYPE bool;
-- 3. Define a field with field-level permissions (SSN field)
-- Only the owner can view this field!
DEFINE FIELD ssn ON member TYPE string
PERMISSIONS FOR select WHERE id = $auth.id;
4. Common Mistakes & Pitfalls
Mistake 1: Omitting the 'ON' or 'ON TABLE' keywords in the field definition statement, triggering compiler syntax errors
The mistake: Writing the query DEFINE FIELD username TYPE string; to configure a user profile.
Why it's wrong: In SurrealQL, fields do not float globally.
They must be anchored to a specific table.
Omitting the ON table link causes the query compiler to throw syntax parsing errors.
Fix: Always specify the target table using the ON <table> or ON TABLE <table> clauses:
-- BAD
DEFINE FIELD username TYPE string;
-- GOOD
DEFINE FIELD username ON user TYPE string;
Mistake 2: Omitting Table Name in DEFINE FIELD Statements
The mistake: Writing DEFINE FIELD email TYPE string; (SyntaxError).
Why it's wrong: DEFINE FIELD requires specifying the target table name via ON TABLE table_name.
Incorrect:
DEFINE FIELD email TYPE string; // ❌ Parse error: missing ON TABLE
Fix:
DEFINE FIELD email ON TABLE user TYPE string; // Specifies target table 'user'
Mistake 3: Confusing TYPE option<string> with TYPE string in Required Fields
The mistake: Defining a mandatory field as TYPE option<string>.
Why it's wrong: option<T> allows the field to be NONE (optional). If the field is strictly required, use TYPE string.
Incorrect:
DEFINE FIELD required_name ON TABLE user TYPE option<string>; // Allows NONE!
Fix:
DEFINE FIELD required_name ON TABLE user TYPE string; // Strictly required non-none field
5. Practice Exercises
Exercise 1: Defining Typed Fields with Default Values
Scenario:
You are defining schema rules for a user table requiring a typed email string and a default role string.
Requirements:
- Define table
userasSCHEMAFULL. - Define field
emailasstring. - Define field
roleasstringwithDEFAULT "customer".
Answer
Implementation
DEFINE TABLE user SCHEMAFULL;
DEFINE FIELD email ON TABLE user TYPE string;
DEFINE FIELD role ON TABLE user TYPE string DEFAULT "customer";
CREATE user:u1 SET email = "u1@example.com";
Technical Explanation
DEFINE FIELDestablishes schema rules for individual table properties.TYPE <type>enforces strict data type validation at write time inSCHEMAFULLmode.DEFAULT <val>automatically populates field values if omitted during record creation.
Exercise 2: Defining Readonly Timestamp Fields
Scenario:
Define an immutable created_at timestamp field on table post that cannot be altered after record creation.
Requirements:
- Define field
created_aton tablepostasdatetime. - Apply
DEFAULT time::now()andREADONLYattributes.
Answer
Implementation
DEFINE TABLE post SCHEMAFULL;
DEFINE FIELD created_at ON TABLE post TYPE datetime
DEFAULT time::now()
READONLY;
Technical Explanation
READONLYprevents field modifications on subsequentUPDATEorMERGEqueries.- Guarantees audit timestamp immutability at the storage engine level.
- Rejects update operations attempting to alter readonly field values.
Exercise 3: Idempotent Field Overwrites with OVERWRITE
Scenario:
Update an existing field definition age on table user to change its type to int using DEFINE FIELD OVERWRITE.
Requirements:
- Write the
DEFINE FIELD OVERWRITEstatement for fieldage.
Answer
Implementation
DEFINE FIELD OVERWRITE age ON TABLE user TYPE int ASSERT $value >= 0;
Technical Explanation
OVERWRITEupdates existing field definitions idempotently without requiring priorREMOVE FIELDcalls.- Modifies data type constraints and assertion expressions cleanly.
- Simplifies continuous deployment schema migration scripts.
6. Related Terms
-
Clause — Field assertion clause.
-
DEFINE TABLE— The parent schema context. -
option<T>(Optional Fields) — Optional fields wrapper. -
Assertions (
ASSERT) — Custom field validation. -
SCHEMAFULLvsSCHEMALESS— Related concept:SCHEMAFULLvsSCHEMALESS. -
VALUE/DEFAULT/READONLYClause — Related concept:VALUE/DEFAULT/READONLYClause. -
SCHEMAFULLValidation Assertion Patterns — Related concept:SCHEMAFULLValidation Assertion Patterns. -
OVERWRITEKeyword — Related concept:OVERWRITEKeyword.
7. Key Takeaways
DEFINE FIELDdeclares validation rules and types for record properties.- Relational equivalent to defining table columns; NoSQL equivalent to schema validation.
- Fields are defined individually and anchored using the
ONkeyword. - Supports dot-notation paths to validate nested object properties.
- Field-level permissions (
PERMISSIONS) provide granular access controls. - Schema-full tables reject writes to fields that are not explicitly defined.
- Field types support parameter arguments (like
array<string>).