Relational, Document, Graph: Pick the Database That Matches Your Relationships
February 24, 2026
Every database argument I have ever been pulled into reduces to the same hidden question. What shape do the relationships in your data actually take? Pick the model that fits that shape and the rest of the system gets cheaper. Pick the wrong one and you spend the next two years writing increasingly creative workarounds.
Relational shines when you have lots of many-to-many relationships and you need flexible queries you cannot fully predict at design time. The join is the whole point. Foreign keys, unique constraints, and check constraints keep the data honest while the schema evolves. SQL is a good language for ad hoc questions, which matters more than people admit, because analytics, support tooling, and admin dashboards are all ad hoc queries in disguise. The weakness is straightforward: object to row mapping always feels a little clunky, and very deep joins get slow without careful indexing.
Document stores fit when your unit of work is an aggregate. An order with its line items and shipping address. A user profile with preferences and settings. You almost always read and write the whole thing together, so embedding it in one JSON blob trades a join for a single key lookup. Schemas evolve loosely. The cost is that any query that crosses documents is now your problem to denormalize and maintain.
Key value is the same idea taken further. No structure, just get and put. Use it for sessions, feature flags, rate limit counters, things you key directly and never query by anything else.
Columnar stores invert the layout for analytics. Rows compress poorly across heterogeneous columns. Columns compress beautifully and let you scan ten billion rows over three columns without touching the rest. That is why your warehouse is Snowflake or BigQuery and not Postgres.
Graph databases earn their keep when the question itself is a traversal. Fraud rings, recommendation neighborhoods, organizational hierarchies, knowledge graphs. The query is "find everything within four hops of this node that matches a predicate." In a graph engine that is a few milliseconds.
The concrete failure mode I keep watching teams hit: that same traversal expressed in relational SQL as a recursive CTE. It works at small scale. Then the social graph reaches ten million edges and the planner gives up. Latency goes from twenty milliseconds to twenty seconds. The fix is not a bigger Postgres box. The fix is acknowledging that the access pattern wanted a graph all along.
Match the model to the access pattern. Everything else is taste.
The database debate is usually a relationship-shape debate in disguise. Match the model to how your data is accessed, not to what is trendy or what you already run.
Originally posted on LinkedIn. View original.