Computer Things

Subscribe
Archives
July 21, 2023

Queryability and the Sublime Mediocrity of SQL

I'm going to a small academic workshop on design next week. This got me thinking of the various meanings of "design", which got me thinking about the various purposes of "design", which got me thinking about queryability.

A system is queryable if (and I'm speaking very roughly) you can easily retrieve information you need from the system data. As an example, let's say we record scientists and the papers they worked on. You could represent the data like this:

Scientist {
    name: str
    department: Department
    papers: set of Paper
}

Paper {
    name: str
    published: date
}

In this model, it's easy to query the papers a scientist worked on, it's just one lookup. On the other hand, it's really hard to get all of the authors of a given paper, we'd have to iterate through all the Scientists to find out. Alternatively, we could do this:

Scientist {
    name: str
    department: Department
}

Paper {
    name: str
    published: date
    authors: set of Scientist

}

Then it's reversed: really easy to find the authors of a paper, hard to find which papers someone authored. Which data model is more queryable? Depends on usage patterns. Most likely we'll want to both look up the authors of a paper and a given scientist's papers, so neither model is very queryable.

There's also queries that neither model is good at, like "which scientists have coauthored a paper with Mike." One heuristic of system evolution: the diversity of queries is always increasing. So even if one of the above data models is sufficiently queryable for your current use cases, it likely won't be for your future use cases.

(Right now I'm only considering the difficulty of writing the query. Query performance is a whole other rabbit hole.)

The Sublime Mediocrity of SQL

Most of the time you won't be using either model, because you'll be storing your data in a SQL database and representing authorships as a many-to-many table:

Scientists {
    id
    name: str
}

Papers {
    id
    name: str
    published: date
}

Authorship {
    id
    paper: Paper
    author: Scientist
}

Now getting a scientist's papers is "kinda annoying":1

SELECT papers.id FROM papers 
INNER JOIN authorships AS a 
ON a.paper = papers.id AND a.author = 27

But— and this is key— getting a paper's authors is also just "kinda annoying":

SELECT scientists.id FROM scientists
INNER JOIN authorships AS a 
ON a.author = scientists.id AND a.paper = 96

So instead of one "easy" and one "awful", you have two "kinda annoyings", and that's a big win for queryability! In fact even something like "get all the people who are coauthors" rises to, at most, "pretty annoying":

SELECT s1.id, s2.id
FROM scientists AS s1, scientists AS s2 
INNER JOIN authorships AS a1 ON s1.id = a1.author 
INNER JOIN authorships AS a2 ON s2.id = a2.author 
INNER JOIN papers ON papers.id = a1.paper AND a2.paper = papers.id
WHERE s1.id < s2.id;

That's why SQL is so popular: it doesn't make anything effortless, but it keeps a wide variety of things manageable. And since your diversity of queries is only growing, having most things be manageable gives your the critical flexibility needed to keep your system queryable.

There are also a lot of queries that SQL is awful at, like most things involving graphs. That's why things like graph- and time-series databases have market niches.

Other Notes on Queryability

  • Views lets you store data in one format but make it retrievable in a different format, which adds queryability at the cost of performance. You can use materialized views but then you have caching issues.

  • There are different classes of queries, that as a group have various requirements and best practices. Some of them:

    • Analytics: How many papers did each department publish last year?
    • Auditing/Historical: What department was X working in when they published Y paper?
    • Bitemporal queries: What did we mistakenly record as Y's title when we published a press release about it?
    • Metadata: How often do people look up the authors of a given paper?
    • Transitive queries: What's Danica McKellar's Erdős number?2
    • Administrative: what records would cause problems with this data migration?

    Basically, any question someone could reasonably ask is potentially a query someone will need to write.

  • There's probably a tension between thinking of queryability as "what queries you can write" and "what you can easily write". Wikidata uses SPARQL, which seems insanely powerful but is only writable by immortal philosopher-kings. Maybe I should look into the query builder.

  • I haven't said anything about how to actually design for queryability and I have no idea how to do this.


Patreon update

Experiment continues! On the request of a few people I lowered the tiers to something a little less shitposty. A little: now getting chocolates in the mail is "only" 768 dollars a year.


  1. It's been years since I needed to write SQL I make no promises that any of this correct. Just trying to get the idea across. ↩

  2. Four. ↩

If you're reading this on the web, you can subscribe here. Updates are once a week. My main website is here.

My new book, Logic for Programmers, is now in early access! Get it here.

Don't miss what's next. Subscribe to Computer Things:
Start the conversation:
This email brought to you by Buttondown, the easiest way to start and grow your newsletter.