Beyond Rows and Columns: Exploring the Missing Third Dimension

img-2

Row-oriented databases are optimized for retrieving and updating complete records. Columnar databases are optimized for aggregating attributes across very large datasets. Graph databases are optimized for traversing relationships between many connected entities. Which one you need depends on whether your dominant workload is entity-centric, analytics-centric, or relationship-centric.

Most engineers are fluent in rows and columns. Relationships tend to get modeled around rather than designed for, and that is where query plans quietly fall apart. Think of this as a practical lens rather than a strict database taxonomy: each model reflects a different primary access pattern.

Row-Based Storage: Built for Whole Records

In the row-based (relational) model, each row represents a record or an entity. A row in a customers table holds the name, address, phone number, and email of one customer, laid out contiguously so the whole record returns in one read.

Row stores fit well when:

  • You insert, update, or delete individual records frequently and need transactional guarantees.
  • Your queries touch many columns of one record, such as finding customers in a given city within an age range.
  • Your unit of work is the entity, not the aggregate.

Examples are MySQL, PostgreSQL, Oracle, Microsoft SQL Server, and SQLite. Document and key-value databases like MongoDB and Redis sit in the same dimension, also optimized for full entity retrieval.

Column-Based Storage: Built for Attribute Aggregation

In the column-based (columnar) model, each column represents one attribute across all records: one column holds every customer name, another every address. Values in a column share a type and often repeat, so they compress well and scan quickly.

Columnar stores fit well when:

  • You run calculations or aggregations over millions or billions of records.
  • Your queries touch few attributes at a time, such as finding the average age of all customers.
  • Scan throughput matters more than single-record latency.

Examples are Cassandra, ScyllaDB, Amazon Redshift, ClickHouse, and DuckDB. Time series databases like InfluxData and Timescale are also column-based, optimized for aggregating many events over a time window.

Graph Storage: Built for Relationship Traversal

In the network-based (graph) model, entities are nodes and their connections are stored as first-class edges, rather than reconstructed at query time from matching key values across tables. Examples are Neo4j, Amazon Neptune, and FalkorDB, most of which expose a traversal language such as Cypher for expressing relationships as patterns instead of repeated joins.

In a graph, a customer connects directly to transactions, payment cards, devices, merchants, and other customers who share an IP address. A fraud analyst can traverse five hops across those connections in a single query. The same traversal in a relational database requires five or more joins, each one multiplying query complexity.

Why Edge Storage Decides Traversal Cost

Storing relationships is not the same as storing them in a form that is efficient to traverse. Most graph databases use adjacency lists, which are compact but require following pointers node by node on every hop, so cost tracks the stored data’s shape rather than the query’s.

Unlike most graph databases, which store relationships as adjacency lists, FalkorDB represents the relationship topology using sparse adjacency matrices and GraphBLAS operations. This makes multi-hop traversal a first-class computational primitive rather than a secondary lookup: a hop becomes a sparse matrix operation, and a multi-hop pattern becomes a sequence the planner can reorder and evaluate as linear algebra. In practice, edge storage sits at the center of the design, not at its periphery.

When a Graph Database Is the Wrong Choice

A graph model is not a general replacement for the first two dimensions. Reach for something else in these cases:

  • Single-record CRUD transactions: relational databases are faster and simpler.
  • Large-scale aggregations across millions of rows: columnar layout and compression make wide scans more efficient than traversal.
  • Simple key-value lookups: key-value stores carry lower overhead than a planner plus a graph model.
  • Data with few or no meaningful relationships between entities: a graph adds modeling cost and returns no traversal benefit.
  • Fixed, shallow join paths that rarely change: a two-table join with the right indexes is already efficient.

Workloads Where Graph Databases Fit

Before choosing a model, check whether relationship traversal is the actual bottleneck. These are the workloads where it usually is:

  • Fraud detection: traversing transaction networks to find connected fraudulent actors. The signal lives in the network’s shape (shared devices, cards, IP ranges), surfacing several hops out, where each extra join multiplies cost.
  • Recommendation engines: multi-hop paths from user to item through shared attributes. Candidate generation explores many indirect paths per request, and each degree of separation adds a join layer.
  • Knowledge graphs and GraphRAG: connecting entities for LLM context retrieval. Answer quality depends on pulling a connected subgraph inside a tight latency budget: a traversal problem, not a similarity lookup.
  • IT and network dependency analysis: mapping service and infrastructure relationships. Questions like “what breaks if this service fails” are transitive closure queries whose depth is unknown at write time.
  • Identity and access management: resolving complex permission chains. Effective access comes from nested groups, inherited roles, and delegated grants, so answering requires walking a chain of variable length.

Choosing Between the Three

Each model has advantages and disadvantages depending on the type and purpose of your data. The question is not which wins in the abstract, but which access pattern dominates your workload:

  • Entity-centric and transactional: start with a row store.
  • Analytics-centric and aggregation-heavy: start with a columnar store.
  • Relationship-centric with variable-depth traversal: start with a graph.

In many production systems the answer is a hybrid: a row store as the system of record, a columnar store for analytics, and a graph for the relationship layer serving traversal and AI retrieval. Choosing deliberately per workload beats forcing all three patterns through one engine.

Frequently Asked Questions

When should I use a graph database instead of PostgreSQL?

Use a graph database when queries traverse relationships of variable or unknown depth, such as multi-hop fraud rings or permission chains. PostgreSQL handles fixed, shallow joins well. Once one traversal needs recursive CTEs or five or more joins, a graph model is usually simpler.

What is the difference between adjacency lists and adjacency matrices?

An adjacency list stores, for each node, a list of its neighbors, so a hop means following pointers through that list. An adjacency matrix stores connectivity as a matrix where a nonzero entry marks an edge. Sparse matrix form lets a traversal run as linear algebra.

Why are graph databases useful for GraphRAG and AI applications?

GraphRAG retrieves context for an LLM by following relationships between entities, not by vector similarity alone. A graph stores those relationships explicitly, so retrieval expands from a starting entity to related facts within a bounded number of hops, producing context with structure.

When is a columnar database a better choice than a graph database?

Choose columnar storage when the workload aggregates one or a few attributes across very large volumes of records: sums, averages, percentiles, or time-window rollups. Column-wise layout and compression make those scans efficient. If scanning an attribute answers the question, a graph adds overhead.

Author

  • Guy Korland

    Guy Korland serves as CEO at FalkorDB, where he drives graph database architecture for generative AI and retrieval-augmented generation workflows. He holds a PhD in Computer Science from Tel Aviv University and brings over 20 years of experience in database engineering. He previously led Redis’ incubation arm as SVP & CTO, oversaw platform architecture as GM & CTO at Stor.ai (Self-Point), co-founded and served as CTO of Shopetti, and directed R&D as VP at GigaSpaces.