From “Everything Is a File” to “Ask the Database”: The Hidden Evolution of Computing

Kai Nguyen

Hatched by Kai Nguyen

Aug 29, 2026

11 min read

93%

0

What if the most important feature of a database is not that it stores information, but that it lets you stop thinking about storage altogether?

A beginner often encounters computing as a collection of objects: files, folders, tables, rows, columns, indexes. These objects seem concrete and separate. Yet much of modern software rests on a more radical idea: different things can be made useful through the same small set of operations. A document, a device, a network connection, and a database table can all become approachable through carefully designed abstractions.

This is why the familiar claim that “everything is a file” and the practice of writing SQL belong to the same intellectual story. One establishes a universal surface for interacting with the machine. The other pushes that idea further, replacing instructions about where and how data is stored with a statement of what information we want.

The deeper question is not how to organize data. It is this: What should a person have to understand in order to make a machine useful?

The answer determines whether technology amplifies human thought or merely transfers mechanical labor from one interface to another.

The Great Bargain of Abstraction

Abstraction is often described as hiding complexity. That is true, but incomplete. A good abstraction does not merely conceal details. It selects which details matter and gives them a stable form.

Consider a file. At the physical level, a file is not a little document sitting intact inside a computer. It is a collection of bytes distributed across blocks of storage, tracked by metadata, interpreted by an operating system, and eventually converted into signals on a device. Yet a program can open the file, read from it, write to it, and close it without managing every sector on the disk.

The file abstraction is powerful because it turns a messy physical world into a small conceptual vocabulary. Instead of asking which disk block contains the next character, we ask for an operation on a file. The abstraction absorbs implementation details so that the user can focus on a higher level goal.

Databases make a similar bargain, but at a more ambitious scale. A table presents information as named columns and rows. A column has a name and a data type. A row represents one data point. These conventions transform an undifferentiated mass of stored values into something that can be reasoned about.

Suppose a fruit stand records its inventory in a table:

CREATE TABLE fruit_stand (
  item TEXT,
  price NUMERIC,
  unit TEXT
);

The physical database may store this information through pages, indexes, buffers, logs, and other mechanisms. The person using the table does not need to know where the bytes live. They need to know that an item is text, that a price is numeric, and that a unit describes how the price should be understood.

This is the first important connection: a database is not simply a more organized file system. It is an abstraction that changes the kind of question a user can ask.

A file oriented question sounds like this: “Open this object, move through its contents, find the relevant lines, and interpret them.” A database question sounds like this: “Return the price and item for all records matching these conditions.” The second question is shorter not because the problem is trivial, but because the system has absorbed the routine work.

The purpose of abstraction is not to make reality disappear. It is to make the right reality visible.

From Commands to Intent

There is a crucial distinction between telling a machine how to act and describing the result we want.

An imperative instruction might say: open a file, scan each record, compare the item field, copy matching values into a new structure, and return the result. SQL is generally declarative. A query states the desired result while leaving the database management system to determine how to produce it.

SELECT price, item
FROM fruit_stand;

This statement specifies the output columns and the table from which they should come. It does not explain how the database should locate the rows, whether it should use an index, or in what order it should perform internal operations. Those decisions belong to the system.

This division of labor is one of the most consequential ideas in software. The human supplies meaning. The machine supplies method.

The distinction becomes more valuable as the underlying problem grows. If a person manually searches a small text file, the difference between intent and procedure may seem negligible. But when the data spans millions of records, resides across multiple storage devices, or changes while queries are running, procedural instructions become fragile. A declarative language gives the system room to optimize, adapt, and improve its methods without requiring every user to rewrite their request.

This is the same reason a person can use the word “file” without knowing the details of a storage controller. The abstraction protects the user from implementation churn. The surface remains stable while the machinery evolves beneath it.

Yet this convenience introduces a responsibility. To use an abstraction well, we must understand its concepts, even if we do not understand every implementation detail. Someone who knows only that SQL can “get data” may write queries that are technically valid but conceptually wrong. They may select every column when only two are needed, confuse a row with a category, or treat a numeric value as meaningful without understanding its unit.

Abstraction reduces the amount of knowledge required to operate a system, but it increases the importance of the knowledge that remains. The less we manage directly, the more carefully we must choose the concepts through which we manage indirectly.

Tables Are Models, Not Containers

A common mistake is to think of a table as a digital spreadsheet with a database attached. That view misses what the table is doing intellectually.

A table is a model of some portion of the world. Its columns decide which distinctions are preserved. Its data types decide which operations make sense. Its rows determine what counts as one observation. Before a single query is written, the table has already made claims about reality.

Imagine two designs for recording purchases. The first stores:

item: apple
price: 2
unit: 6.98

The second stores:

item: apple
quantity: 2
price_per_unit: 6.98
currency: USD

Both are syntactically possible. But they do not represent the same thing. In the first design, the meaning of “price” is ambiguous and “unit” may be mistaken for a measurement. In the second, the schema makes the intended relationships easier to understand and query.

This reveals a broader principle: a schema is a theory of what matters.

The operating system file abstraction asks us to treat many resources as readable and writable objects. The database table asks us to treat information as structured relationships among named attributes. Both are acts of simplification, but neither is neutral. They create affordances. A file encourages sequential reading and writing. A relational table encourages comparison, filtering, projection, and combination.

The choice of names matters as well. A column called price invites different interpretations from one called price_in_cents. Naming conventions, including the ordinary practice of using lowercase names, may seem cosmetic, but they reduce friction and ambiguity. A consistent surface lets attention move toward the problem rather than toward deciphering notation.

The same is true of data types. If a value is stored as text when it should be numeric, the system may be unable to perform meaningful arithmetic without additional conversion. If a date is stored in an inconsistent format, a simple query can become a semantic puzzle. Types are not merely technical restrictions. They are safeguards against confusing a representation with the thing represented.

When people complain that a database is “hard to use,” the difficulty often begins earlier than the query. It begins with a weak model. A poorly designed table forces every future user to reconstruct missing meaning through guesswork.

Every schema is a promise about what can be asked later.

That promise can be generous or restrictive. A good schema makes important questions natural. A bad one makes even simple questions depend on tribal knowledge, fragile parsing, and repeated explanation.

The Interface Is a Moral Choice About Attention

The movement from files to tables and from procedures to declarations can be understood as a way of managing scarce human attention.

Computers are exceptionally good at repetitive, exact operations. Humans are better at deciding what matters, recognizing ambiguity, and changing the question when the evidence is surprising. An interface is well designed when it assigns each kind of work to the side that performs it best.

A raw file interface may require a person to think about sequence, delimiters, locations, and control flow. A relational interface lets the person think more directly about attributes and relationships. Instead of mentally simulating the machinery, the user can ask questions such as:

  • Which items cost more than a given amount?
  • Which records belong to a particular category?
  • What columns are necessary to answer this question?
  • What information is missing or inconsistent?

The query becomes a compact expression of an investigation. It can be read, reviewed, modified, and shared. In that sense, SQL is not only a tool for retrieving information. It is a language for making a question explicit.

That matters because vague questions produce vague systems. “Show me the data” is often a sign that the user has not decided which distinctions are relevant. Replacing SELECT * with specific columns is not merely an optimization or a style preference. It is an act of intellectual discipline. It asks: what do I actually need to see?

The same discipline applies to writing data. An INSERT statement changes the state of the database. A query retrieves information. Keeping those roles conceptually distinct helps prevent accidental changes and makes a workflow easier to reason about. The semicolon that terminates a statement is a small boundary, but boundaries are essential in systems where language can alter shared state.

This leads to a practical mental model with three layers:

  1. Reality: the people, objects, events, and measurements we care about.
  2. Model: the tables, columns, types, and relationships chosen to represent them.
  3. Request: the query or statement used to inspect or change the model.

Errors often occur when these layers are confused. A stored value is mistaken for reality. A table is mistaken for the entire domain. A query is treated as though it were a neutral window rather than a selective perspective.

The model does not eliminate judgment. It relocates judgment into visible structures that can be inspected and improved.

Designing Better Questions, Not Just Better Queries

The most useful consequence of this synthesis is a change in how we approach technical work. Instead of beginning with “Which command should I type?” begin with “What layer of the problem am I trying to clarify?”

If the difficulty is physical access, an abstraction such as a file may be sufficient. If the difficulty is finding patterns among many records, a table and a declarative query are more appropriate. If the difficulty is ambiguity, no clever query will fully compensate for a confusing schema.

A reliable workflow looks like this:

First, name the thing being represented. Is a row a purchase, a product, a customer, or an event? If the answer is unclear, stop before designing the table.

Second, identify the properties that must remain distinct. Quantity, price, unit, and currency may appear together in one sentence, but they are not interchangeable. Separate columns create sharper questions.

Third, choose types that preserve intended operations. Numbers should support arithmetic. Text should preserve labels. Dates should support ordering and comparison. A type is a declaration of what the value is allowed to mean.

Fourth, write the narrowest query that answers the question. Select the needed columns rather than all columns. Use the table name that reflects its contents. Make the request readable enough that another person can verify its intent.

Fifth, distinguish inspection from intervention. Retrieval should not be confused with modification. Treat statements that change state with the care given to any action that affects other people or future decisions.

This workflow scales beyond databases. It applies to APIs, command line tools, configuration systems, and even organizational processes. Whenever a system replaces low level manipulation with a high level language, the same questions return: What does the interface represent? Which details has it hidden? Which assumptions has it made visible? What can be expressed, and what has become difficult or impossible to ask?

Key Takeaways

  • Treat abstractions as models, not magic. Learn what an interface makes easy, what it hides, and what assumptions it imposes.
  • Separate reality, representation, and request. Many technical errors come from confusing the thing itself with its schema or with the query used to inspect it.
  • Design schemas around future questions. A column name and data type should preserve distinctions that users will need to compare, calculate, filter, or explain.
  • Prefer intent over procedure when the system can carry the method. Declarative requests are often more durable because the underlying implementation can improve without changing the question.
  • Use specificity as a form of clarity. Selecting only the necessary columns and separating state changing statements from retrieval makes systems safer and reasoning easier.

The phrase “everything is a file” describes a powerful unification: many kinds of resources become manageable through a common interface. SQL reveals the next stage of that idea. Once information is given structure, we no longer need to navigate it as a sequence of bytes. We can address it through concepts, relationships, and questions.

That evolution is not just a technical convenience. It is a theory of human and machine cooperation. The machine should handle the mechanical details that do not require judgment. The human should define the distinctions, meanings, and goals that make the work worth doing.

The best abstraction therefore does not make us think less. It lets us think about better things. And the true measure of a system is not how much complexity it hides, but whether the complexity it leaves us with is the complexity that matters.

Sources

← Back to Library

Hatch New Ideas with Glasp AI 🐣

Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)

Start Hatching 🐣