The DEFINE statement can be used to specify instructions to the schema such as authentication access and behaviour, global parameters, table configurations, table events, analyzers, and indexes.
Before SurrealDB version 3.0.0, the FULLTEXT ANALYZER clause used the syntax SEARCH ANALYZER.
DEFINE [
NAMESPACE [ OVERWRITE | IF NOT EXISTS ] @name
| DATABASE [ OVERWRITE | IF NOT EXISTS ] @name
| USER [ OVERWRITE | IF NOT EXISTS ] @name ON [ ROOT | NAMESPACE | DATABASE ] [ PASSWORD @pass | PASSHASH @hash ] ROLES @roles
| TABLE [ OVERWRITE | IF NOT EXISTS ] @name
[ DROP ]
[ SCHEMAFULL | SCHEMALESS ]
[ AS SELECT @projections
FROM @tables
[ WHERE @condition ]
[ GROUP [ BY ] @groups ]
]
[ PERMISSIONS [ NONE | FULL
| FOR select @expression
| FOR create @expression
| FOR update @expression
| FOR delete @expression
] ]
| EVENT [ OVERWRITE | IF NOT EXISTS ] @name ON [ TABLE ] @table WHEN @expression THEN @expression
| FIELD [ OVERWRITE | IF NOT EXISTS ] @name ON [ TABLE ] @table
[ TYPE @type ]
[ VALUE @expression ]
[ ASSERT @expression ]
[ PERMISSIONS [ NONE | FULL
| FOR select @expression
| FOR create @expression
| FOR update @expression
| FOR delete @expression
] ]
| PARAM [ OVERWRITE | IF NOT EXISTS ] $name VALUE @value
| FUNCTION [ OVERWRITE | IF NOT EXISTS ] fn::@name ( [ ( @argument:@type ... ) ] ) { [@query] [RETURNS @returned] }
| ANALYZER [ OVERWRITE | IF NOT EXISTS ] @name
[ TOKENIZERS @tokenizers ]
[ FILTERS @filters ]
| INDEX [ OVERWRITE | IF NOT EXISTS ] @name ON [ TABLE ] @table [ FIELDS | COLUMNS ] @fields
[ UNIQUE | FULLTEXT ANALYZER @analyzer [ BM25 [(@k1, @b)] ] [ HIGHLIGHTS ] ]
| SEQUENCE [ OVERWRITE | IF NOT EXISTS ] @name
[ BATCH @batch ]
[ START @start ]
| ACCESS [ OVERWRITE | IF NOT EXISTS ] @name ON [ NAMESPACE | DATABASE ]
TYPE [
JWT [ ALGORITHM @algorithm KEY @key | URL @url ]
| RECORD
[ SIGNUP @expression ]
[ SIGNIN @expression ]
[ WITH JWT [ ALGORITHM @algorithm KEY @key | URL @url ] [ WITH ISSUER KEY @key ] ]
]
[ DURATION [ FOR TOKEN @duration ] [ FOR SESSION @duration ] ]
[ COMMENT @string ]
]The INFO statement can be used to see which definition statements currently exist in a database connection. All DEFINE statements can be followed up with a COMMENT.
Comments on definitions
A COMMENT is stored with the definition and returned by INFO (and by schema tools such as MCP info / list). Short, concrete comments help people and agents alike: they explain what a table or field is for, how values should be compared, and which graph edges or record-ID conventions matter.
Useful comments tend to include:
What the entity represents, and what it deliberately does not store
How to read the record ID or field (for example
record::id(id)when the ID is the canonical name)How to compare or sort unusual types (ISO date strings vs datetimes)
Cardinality or invariants ("exactly one organiser per meeting")
The main graph paths to related tables
DEFINE TABLE person TYPE NORMAL SCHEMAFULL
COMMENT "A person, deduplicated across notes. Has no fields: the record id IS the canonical full name, e.g. person:`Alice Chen`. Read the name with record::id(id). Meetings: person->attended->meeting.";
DEFINE TABLE meeting TYPE NORMAL SCHEMAFULL
COMMENT "A calendar meeting. Link attendees with RELATE person->attended->meeting.";
DEFINE TABLE attended TYPE RELATION IN person OUT meeting SCHEMAFULL
COMMENT "Attendance edge. Exactly one attendee per meeting has is_organizer = true.";
DEFINE FIELD is_organizer ON attended TYPE bool
COMMENT "True if this person ran the meeting, false if they only attended.";An example of defining a field on a table, followed by an INFO command for the same table:
DEFINE FIELD name ON TABLE person TYPE string COMMENT "Todo: add assertion for maximum length";
INFO FOR TABLE person;{
events: {},
fields: {
name: "DEFINE FIELD name ON person TYPE string COMMENT 'Todo: add assertion for maximum length' PERMISSIONS FULL"
},
indexes: {},
lives: {},
tables: {}
}An example of defining a user and a table for a database, followed by an INFO command for the current database:
DEFINE USER db_user ON DATABASE PASSWORD "strongpassword" ROLES OWNER;
DEFINE TABLE person SCHEMAFULL;
INFO FOR DB;{
"accesses": {},
"analyzers": {},
"functions": {},
"models": {},
"params": {},
"tables": {
"person": "DEFINE TABLE person TYPE ANY SCHEMAFULL
PERMISSIONS NONE"
},
"users": {
"db_user": "DEFINE USER db_user ON DATABASE PASSHASH '[REDACTED]' ROLES OWNER"
}
}