Graph Connections (Overview: Nodes vs Edges)
Graph Connections (Overview: Nodes vs Edges)
Level 5 — Relational Data & Graph Operations The core graph database concepts in SurrealDB, separating entities (Nodes or Vertices) from relationships (Edges or Relations), explaining how edges act as first-class records containing
inandoutpointer fields.
1. Prerequisites
- Record Link (Concept) — The single reference link.
DEFINE TABLE— Table structure configurations.
2. Term Category
Core Concept (multi-model graph data architecture): - Database Structure / Paradigm
3. Explanation
(1) Design Motivation — "Why did we design this?"
In relational databases, representing complex networks (like social connections or recommendations) requires many-to-many junction tables:
- To check if User A follows User B, you must query a
followsjunction table. - As your network grows, queries require chaining multiple self-joins.
- These SQL self-joins are slow because they scan table indexes sequentially.
We designed native Graph Connections in SurrealDB to solve this scaling problem.
Instead of treating connections as abstract keys, SurrealDB uses a first-class Node and Edge model.
Relationships are traversed in constant time, allowing you to query complex connection networks (like "friends of friends who bought product X") without SQL joins.
(2) Nodes vs. Edges in SurrealDB
graph LR
UserA["Node (user:alice)"] -- "Edge (likes)" --> PostB["Node (post:first)"]
subgraph Edge Record [likes:a8g9f]
in["in: user:alice"]
out["out: post:first"]
prop["created_at: datetime"]
end
1. Nodes (Vertices)
Nodes represent the core entities in your application (e.g. users, articles, products).
- They are standard records stored in normal database tables.
2. Edges (Relations)
Edges represent the relationships connecting the nodes (e.g. follows, bought, likes).
- In SurrealDB, edges are first-class records stored in relation tables.
- Every edge record has a unique ID (e.g.
likes:a8g9f...) and contains two mandatory fields:in: A record link pointing to the source node (the origin of the relationship).out: A record link pointing to the target node (the destination of the relationship).
- Because edges are records, you can store custom properties directly on the edge itself (e.g., saving the timestamp when a user liked a post).
(3) Reality Metaphor (Flight Routes)
Imagine looking at a global transportation map:
- Nodes (Airports): The Cities on the map (New York, London, Tokyo). They are fixed locations.
- Edges (Flight Routes): The Flight Paths connecting the cities.
- The path is not just an empty line; it has its own properties (flight number, distance, ticket price).
- The path has a start location (
inNew York) and a destination (outLondon).
4. Common Mistakes & Pitfalls
Mistake 1: Treating graph edges as simple metadata strings, unaware that they are full database records with 'in' and 'out' pointer fields
The mistake: Assuming that creating a relationship is just a string marker and trying to query edges without referencing the in and out keys in edge validation scripts.
Why it's wrong: In SurrealDB, edges are complete database records.
If you define a relation table, you must treat in and out as first-class record link fields.
If you write validation rules on the relation table, forgetting that in and out are mandatory fields will block relation writes.
Fix: Learn to write schema definitions for relation tables that validate the in and out fields as record links, matching your node tables:
-- CORRECT RELATION SCHEMA WITH NODE VALIDATION
DEFINE TABLE follows TYPE RELATION FROM user TO user;
-- Under the hood, follows contains:
-- FIELD in TYPE record<user>
-- FIELD out TYPE record<user>
Mistake 2: Treating Graph Edge Tables as Auxiliary Tables That Cannot Be Directly Queried
The mistake: Assuming graph edge tables created via RELATE cannot be queried with standard SELECT statements.
Why it's wrong: Graph edge tables in SurrealDB are first-class record tables! You can run SELECT * FROM wrote;, update edges, index edge fields, or attach changefeeds.
Incorrect:
-- Assuming edges cannot be queried directly
Fix:
SELECT * FROM wrote WHERE created_at > d"2026-01-01T00:00:00Z"; // Query edge records directly!
Mistake 3: Creating Duplicate Un-Indexed Graph Edges Between Identical Record Nodes
The mistake: Executing RELATE user:alice->likes->post:1; 10 times creating 10 duplicate edge records.
Why it's wrong: RELATE creates a new edge record with a random ID every time unless custom edge IDs or unique indexes are specified.
Incorrect:
-- Creates multiple duplicate edge records!
RELATE user:alice->likes->post:1;
RELATE user:alice->likes->post:1; // ❌ Duplicate edge created!
Fix:
DEFINE INDEX UNIQUE_LIKE ON TABLE likes FIELDS in, out UNIQUE;
RELATE user:alice->likes->post:1; // Prevented by unique index
5. Practice Exercises
Exercise 1: Multi-Model Graph vs Relational Paradigms
Scenario: Compare how graph connections are created and queried in SurrealDB versus traditional SQL relational databases.
Requirements:
- Explain how graph relations (
RELATE) replace SQL foreign key junction tables. - Explain how arrow path traversals (
->) replace SQLJOINclauses.
Answer
Implementation
SQL Relational Paradigm:
- Creates a junction table 'user_posts' (user_id FK, post_id FK).
- Requires SELECT ... FROM user JOIN user_posts ON ... JOIN post ON ...
SurrealDB Graph Paradigm:
- Creates a relation edge table using RELATE user:alice->wrote->post:p1.
- Queries connected posts using SELECT ->wrote->post FROM user:alice.
Technical Explanation
RELATEcreates direct record link pointers between source and target records.- Arrow operators (
->) follow direct pointer addresses without table scanning or index join lookups. - Unifies relational schema safety with graph database traversal speeds.
Exercise 2: Basic Relation Edge Creation with RELATE
Scenario:
Create a graph relation edge liked connecting user:alice to post:p1 with a liked_at timestamp property.
Requirements:
- Execute
RELATE user:alice -> liked -> post:p1 SET liked_at = time::now().
Answer
Implementation
CREATE user:alice SET name = "Alice";
CREATE post:p1 SET title = "SurrealDB Graph Overview";
-- Create graph relation edge
RELATE user:alice->liked->post:p1 SET liked_at = time::now();
Technical Explanation
RELATE in->edge->outestablishes a directed graph connection between two record IDs.- Stores
in(source ID),out(target ID), and custom edge properties (liked_at). - Edge tables (
liked) can be queried directly or traversed via arrow paths.
Exercise 3: Graph Arrow Traversal Execution
Scenario:
Query all posts liked by user:alice using ->liked->post.
Requirements:
- Write
SELECT ->liked->post.title FROM user:alice.
Answer
6. Related Terms
- Record Link (Concept) — The single reference link.
RELATEStatement — Creating graph edges.- Graph Traversal vs. Relational JOINs — Graph traversal vs SQL JOINs.
7. Key Takeaways
- Graph databases separate data into entity Nodes and relationship Edges.
- Nodes represent objects; Edges represent connections between objects.
- In SurrealDB, Edges are first-class records stored in relation tables.
- Every edge record contains mandatory
in(source) andout(target) pointer fields. - Edges can store custom properties (like timestamps, weights, or ratings).
- Graph traversals bypass slow SQL joins, resolving links in constant time.
- Define relation schemas explicitly using
DEFINE TABLE ... TYPE RELATION.