string
string
Level 2 — Data Types & Record Structure The primitive data type in SurrealDB used to store UTF-8 text data, supporting single or double quotes, native multi-line strings, and full emoji/unicode character sets.
1. Prerequisites
- Data Types (Overview) — The parent type system.
2. Term Category
Data Type (UTF-8 text string type): - Database Structure / Paradigm
3. Explanation
(1) Design Motivation — "Why did we design this?"
In SQL databases (like PostgreSQL), strings are divided into multiple types with physical storage trade-offs:
CHAR(N): Fixed-length strings (pads empty spaces with blanks).VARCHAR(N): Variable-length strings up to a strict limit.TEXT: Unlimited-length strings.
Managing these types and predicting length limits adds complexity during early schema design.
We designed the string type in SurrealDB to simplify text storage.
There is only one string type.
It is dynamically sized, stores UTF-8 characters natively (meaning emojis and foreign scripts work out of the box), and supports multi-line text blocks without complex escape characters, matching the clean string handling of JavaScript.
(2) Quoting & Multi-Line Strings
SurrealDB strings can be wrapped using:
- Single Quotes:
'Hello World' - Double Quotes:
"Hello World" - Multi-Line Blocks: You can press enter and write text across multiple lines inside the quotes. SurrealDB preserves the line breaks, eliminating the need to write
\noperators manually.
(3) Reality Metaphor (Unlimited Paper Rolls)
Imagine writing logs:
- PostgreSQL
VARCHAR(50): Writing on a pre-cut Label Tape exactly 50 millimeters wide.- If your name is long or you write extra words, it falls off the edge, and the system rejects it.
- SurrealDB
string: Writing on a roll of Unlimited Paper Tape.- The tape rolls out as long as your text is.
- You can write in English, draw emojis, write in different languages, and press enter to write on multiple lines.
(4) Code Examples
Creating and Defining String Fields
Let's create a profile collection with various string layouts:
DEFINE TABLE profile SCHEMAFULL;
-- 1. Enforce string type
DEFINE FIELD biography ON profile TYPE string;
DEFINE FIELD username ON profile TYPE string;
-- 2. Insert records with different string formatting
CREATE profile:alice SET
username = "Alice Emojis 🚀", // Unicode/Emoji support
biography = "Developer.
Designer.
Love databases!"; // Multi-line string, line breaks are preserved!
-- 3. Query string matches
SELECT * FROM profile WHERE username = 'Alice Emojis 🚀';
4. Common Mistakes & Pitfalls
Mistake 1: Attempting to define string length constraints using SQL syntax like 'TYPE string(255)', resulting in syntax errors
The mistake: Writing DEFINE FIELD email ON user TYPE string(255); to replicate SQL column constraints.
Why it's wrong: In SurrealQL, the string type does not accept size arguments.
Writing string(255) triggers a compiler parsing crash.
Fix: Declare the type simply as TYPE string. If you want to enforce a maximum length constraint, use the ASSERT clause with the built-in string::len() function:
-- CORRECT
DEFINE FIELD email ON user TYPE string
ASSERT string::len($value) <= 255;
Mistake 2: Forgetting String Quotes in String Field Assignment Literals
The mistake: Writing SET name = Alice without quotation marks.
Why it's wrong: Unquoted identifiers Alice are parsed as variable references or field names, causing syntax errors. Quote strings with "Alice" or 'Alice'.
Incorrect:
CREATE user SET name = Alice; // ❌ Parses Alice as variable or field identifier!
Fix:
CREATE user SET name = "Alice"; // Correct quoted string literal
Mistake 3: Using Invalid String Concatenation Operators
The mistake: Writing first + ' ' + last expecting string concatenation in older versions.
Why it's wrong: Use string::concat() or template strings `${first} ${last}` for robust string concatenation.
Incorrect:
LET $full = $first + " " + $last;
Fix:
LET $full = string::concat($first, " ", $last);
-- Or string functions:
LET $full = `${$first} ${$last}`;
5. Practice Exercises
Exercise 1: String Format Validation and Case Transformation
Scenario: A user registration service converts email input to lowercase and validates string length and format using built-in string functions.
Requirements:
- Define table
userinSCHEMAFULLmode. - Define field
emailasstringasserting valid email format. - Insert user converting email
"ALICE@EXAMPLE.COM"to lowercase usingstring::lowercase().
Answer
Implementation
DEFINE TABLE user SCHEMAFULL;
DEFINE FIELD email ON TABLE user TYPE string ASSERT string::is::email($value);
CREATE user:u1 SET email = string::lowercase("ALICE@EXAMPLE.COM");
Technical Explanation
string::lowercase()normalizes string casing at write time.string::is::email($value)validates RFC email syntax insideASSERTclauses.- Ensures consistent normalized string data across user records.
Exercise 2: String Pattern Searching with Regex
Scenario:
An admin dashboard searches for user accounts where the username starts with "admin_" using string functions or regex matching.
Requirements:
- Create users
user:a1(username = "admin_john") anduser:u2(username = "user_jane"). - Query users where
usernamestarts with"admin_"usingstring::starts_with().
Answer
Implementation
CREATE user:a1 SET username = "admin_john";
CREATE user:u2 SET username = "user_jane";
-- Filter usernames starting with 'admin_'
SELECT * FROM user WHERE string::starts_with(username, "admin_");
Technical Explanation
string::starts_with(str, prefix)performs prefix matching on string fields.string::*namespace provides rich string functions (concat,replace,trim,split).- Enables clean text filtering without complex regular expressions.
Exercise 3: String Length & Trimming Constraints
Scenario:
Enforce string length constraints on a blog post title field (between 5 and 100 characters) after trimming whitespace.
Requirements:
- Define field
titleon tablepostasstring. - Add an
ASSERTclause checkingstring::len(string::trim($value)) >= 5.
Answer
Implementation
DEFINE TABLE post SCHEMAFULL;
DEFINE FIELD title ON TABLE post TYPE string
ASSERT string::len(string::trim($value)) >= 5 AND string::len($value) <= 100;
CREATE post:p1 SET title = " SurrealQL Basics ";
Technical Explanation
string::trim()strips leading and trailing whitespace.string::len()counts character length accurately for UTF-8 strings.- Prevents empty or whitespace-only strings from bypassing validation rules.
6. Related Terms
- Data Types (Overview) — The parent type system.
- Type Casting & Coercion — Converting between types.
- String Functions (
string::*) — Related concept: String Functions (string::*).
7. Key Takeaways
- The
stringtype stores UTF-8 text sequences. - Direct NoSQL equivalent to PostgreSQL's
TEXTand MongoDB's String BSON. - Supports both single quotes (
') and double quotes ("). - Supports multi-line blocks natively, preserving line breaks on disk.
- Emojis, foreign symbols, and binary characters are saved out of the box.
- Do not write length arguments (like
string(50)); useASSERTconstraints instead. - Manipulate text fields using the extensive built-in
string::*library functions.