9bNine Bits

Relational Databases vs. Graph Databases

A relational database stores data in fixed tables and finds relationships by joining those tables at query time. A graph database stores data as nodes and edges, with each node holding direct pointers to its neighbors, so it can walk relationships without computing a join. Neither model is strictly better; the right choice depends on how deep and how unpredictable your relationship queries are.
Relational Databases vs. Graph Databases

What each model actually is

A relational database organizes data into tables of rows and columns. Relationships between tables exist only as foreign key values; there is no physical link between a row in one table and a row in another until a query joins them. The join is computed every time, by matching key values across tables.

A graph database organizes data as nodes (entities) and edges (relationships), where each edge is a first-class record connecting two nodes and can carry its own properties. Many graph engines use index-free adjacency: each node stores direct references to its adjacent edges, so moving from one node to its neighbors is a pointer lookup, not a search through an index or a table scan.

The term "RGDB" is sometimes used loosely to mean a relational database that has been extended or layered with graph capability, as opposed to a database built as a graph engine from the start.

How traversal cost differs internally

In a relational database, following a chain of relationships means joining the same table to itself (or across tables) once per hop. A one-hop query (find a user's direct friends) is a single join and is usually fast with the right index. A multi-hop query (find friends of friends of friends) requires either several nested joins or a recursive query, and the cost tends to grow with each additional hop because the engine has to re-evaluate matches at every level.

In a graph database, each hop is a pointer traversal from the current node to its stored adjacency list. The cost of one hop does not depend on the total size of the dataset, only on the number of edges at that node. This is the main reason graph engines outperform relational joins on deep or variable-depth traversals, such as shortest-path or recommendation queries.

Example: hierarchical traversal in both models

Here is the same problem, finding every employee who reports up to a given manager at any depth, solved two ways. PostgreSQL can do this with a recursive common table expression:

WITH RECURSIVE org_chart AS (
  SELECT id, name, manager_id
  FROM employees
  WHERE id = 1

  UNION ALL

  SELECT e.id, e.name, e.manager_id
  FROM employees e
  JOIN org_chart o ON e.manager_id = o.id
)
SELECT * FROM org_chart;

This works correctly, but the planner has to re-run the join step for every level of depth, and performance depends heavily on indexing manager_id. A graph engine using a Cypher-style query language expresses the same traversal as a single pattern match. Exact syntax varies by engine; the example below follows the general openCypher pattern-matching style:

MATCH (m:Employee {id: 1})

The * means "any number of hops," and the engine walks edges directly instead of re-joining a table at each level.

When relational is the better fit

  • Data is naturally tabular: orders, invoices, inventory, accounts.
  • Relationships are shallow and known in advance (one or two joins).
  • You need strong transactional guarantees, mature tooling, and a query language (SQL) that most of your team already knows.
  • Reporting and aggregation across large, well-structured tables matters more than traversal.

When a graph model is the better fit

  • The question is about paths and connections, not just records: fraud rings, recommendation chains, dependency graphs, social networks.
  • The traversal depth is unknown or varies per query.
  • The relationships themselves carry important data (weight, type, timestamp on an edge), not just a foreign key.
  • You expect the relationship schema to change often; graphs tolerate new edge and node types without a migration.

A middle path: graph extensions on a relational engine

Rather than running two separate database systems, some teams add graph query capability to an existing relational database. Apache AGE is an open-source PostgreSQL extension that adds a graph data type and openCypher-style querying inside PostgreSQL, so graph and relational tables can live in the same database and even be joined in a single query. This avoids duplicating data between two systems, at the cost of not matching the raw traversal performance of a database built as a graph engine from the ground up. For deep, high-volume graph workloads, a dedicated graph database is usually still faster.

Common mistakes

  • Forcing deep traversals into pure SQL with many nested joins or recursive CTEs when the real workload is graph-shaped. The query will work but will not scale.
  • Moving everything to a graph database because one feature needs path traversal, then losing the mature reporting, indexing, and tooling that a relational engine already gives you for the rest of the data.
  • Modeling edges as a plain join table in a relational schema and expecting graph-database-level traversal performance from it; a join table is still a join, not index-free adjacency.
  • Ignoring index-free adjacency when picking a graph engine. Not every product marketed as a graph database actually uses index-free adjacency internally; check how the engine stores edges before assuming traversal speed.

Common questions

Can I model graph data in a relational database?

Yes. A common approach is a nodes table and an edges table with foreign keys, queried with recursive CTEs for multi-hop traversal. It works for shallow or moderate depth but tends to slow down as traversal depth and data volume grow.

What does index-free adjacency mean?

It means each node stores direct references to its connected edges, so the database can move to a neighboring node with a pointer lookup instead of searching an index or scanning a table. This is the main performance advantage native graph engines have for deep traversals.

Is a graph database always faster than a relational database?

No. For simple lookups, shallow joins, and aggregate reporting, a well-indexed relational database is usually just as fast or faster. Graph engines pull ahead specifically on deep or variable-depth relationship traversal.

What is Apache AGE?

Apache AGE is an open-source extension that adds graph data types and openCypher-style querying to PostgreSQL, letting graph and relational data coexist in one database rather than running two separate systems.

What does RGDB usually refer to?

It is not a standard, widely defined term. It generally refers to a relational database system extended with graph capabilities, as distinct from a database built as a native graph engine from the start.

Sources

  1. PostgreSQL Documentation: Recursive Queries
  2. Apache AGE (Apache Software Foundation)
  3. openCypher Project

About this page

Last reviewed October 30, 2026 by the Nine Bits editors. Read our editorial policy or report an error.