A database is the layer where software keeps its records in a shape it can search and connect. Which store a record lands in is settled where the shape of that record gets declared, not on a shortlist of products. The Vipkurum platform keeps records across two store families at once: an optical reading result lands on the exam’s own record, cropped question records on the document side.
So what is a proposal telling you when it names a relational database or a document database? Not how good the software will be. It is describing the records you already have, and if both terms turn up in the same document, nothing is being padded: records of different shapes can sit in different families inside the same record layer.
What a database does with a business record
Start with the unit, because the word database hides it. A database does not hold files. It holds records, and a record is a bundle of fields, each field carrying a single piece of information about a single thing: the time on an appointment, the name on a patient file, the score on an exam result. Add the fields up and you have the shape of the record, which is what the word shape means everywhere below.
A store earns its name by making several things true of that record at once. It survives the program that wrote it. It can be retrieved without walking the entire store, by a name, a date, or some other record it hangs off. And it can point at another record, the way an appointment carries its own patient on its face.
Why does a folder full of files not qualify? Because opening a file tells you what is inside it and nothing else. The software cannot say which customer it belongs to, which job it was part of, or what amount was invoiced against it on what date. Those facts only exist for software if somebody declared them as fields. Undeclared, they live in the filename or in the memory of whoever saved it, which is to say they are not in the system at all.
That is where the boundary falls for a business. Your system can only tell you what the store keeps as a record. An unanswered question at month end is rarely a reporting problem; more often the field that would answer it was never declared, and no screen can be rewritten into existence. Declare it today and last year’s records still come back empty, because a field cannot be filled in backwards.
What a spreadsheet, a file store and a cache do not do
Plenty of things hold data without being a database, and the spreadsheet is often the one you already have open. It has rows, columns, formulas. What it does not have is a link between its rows that software can follow. That link lives in the head of whoever reads the sheet: the fact that this row belongs to a customer a few tabs over is written nowhere, and it leaves when that person leaves. A formula looks like the missing link, but a formula binds to a cell address, not to a record.
A file store answers a narrower question. Hand it a file and it hands the file back, unchanged. Which record the file belongs to is a separate fact that has to live somewhere else, and that somewhere else is the record. In Secretum, a product we are still building, the split is out in the open: a character is kept as a document record, while the image that character produces is written as a file to a separate place. Lean on the file store alone and the only place left to put that fact is the filename.
And a cache? Not a family of its own. A cached read is derived from the store, so it never stands in for the copy that would bring a lost record back, which is the distinction we set out in planning backup and restore. Counting a cache as a store is counting a reflection as another object in the room.
None of which makes the spreadsheet the wrong tool by default. A list a single person keeps, whose rows never have to reference one another, gains nothing from a store. What forces the question is not volume but reference: if the job is recorded in a single ledger and billed in another, and the thing that reconciles them each month is somebody comparing columns by hand, the comparison is already standing in for a link nobody wrote.
Two store families: a row in a table and a document that stands alone
Both terms name a way of constructing a record rather than a brand on a shelf. On the relational side the record is a row in a table, and which fields that row will carry is declared before any row exists, so every row in the table carries the same set. A patient table gives every patient a name, a date of birth and a contact field; any of them may sit empty, but all of them are declared. The declaration pays off the moment you want a total, because the store already knows every row carries the same fields.
The link itself is just a field pointing at another record. A field on an appointment says which patient it belongs to; another says which step of a treatment plan it answers to. In the relational model records sit in tables, and the binding between them is carried by a field that refers to another record. The term promises nothing about speed, security or quality, so reading it as a compliment reads it wrong.
Declared fields have a name: the schema. A schema is what the store knows about the shape of a record, which fields exist, which are mandatory, which one refers to what. Where a schema exists the store can police itself, and code attempting to write an undeclared field is stopped at the door, which puts the integrity of the record outside the application entirely.
On the document side the record carries its own shape instead. Records in the same store may carry different fields, and a new field arrives without the schema being redeclared; the record is read with whatever happens to be inside it. The guarantee moves with it. What promises a complete record is no longer the store but the code that writes it. So there is no ranking to draw here, only two constructions for two kinds of record, and the question of which fits cannot be answered until somebody asks what shape the records actually have.
Why one system keeps two kinds of store side by side
Which raises the sharper question: why would a single system carry both? The Vipkurum platform does. Timetables, exams, students, guardians and payment handling all sit inside the same application, while MySQL and MongoDB run beside each other in the record layer. There is another face to that setup, the one where a single record layer serves many surfaces and an institution boundary gets drawn, and it has its own article in how multi-tenant systems are built.
What interests us here is narrower: which record goes where? Take the tools built under the same roof. The optical reading tool lifts the marks off an image of the form and writes its result onto the exam’s own record, landing on the table side, onto a record that was already there. The chain that gets it there, upload through to record, belongs to scoring exam sheets without an OMR device.
The question cropping tool ends up in the other family: its cropped images and question records sit on the document side. Both tools were built under the roof of the same platform and both do image work, yet their records still land in different families, which is the quickest way to see that the sorting follows the shape of what each one keeps rather than the tool.
We are not dressing that up as a preference. The split is what we have on record; a written reason for why either tool landed where it did is not, and a reason we do not hold is a reason we will not write. What is observable is the shape. An exam result comes off every form the same way, marks and their matches, and attaches to a record that already exists. In the cropped question, the answer sits inside the question’s own record.
A last thing to close off: it does not follow that each tool runs both stores. The optical reading tool’s stack contains no document side at all; the question cropping tool’s contains no table side. The families sit beside each other across the platform, not inside each tool, and without that said the sentence reads as though every system stands up two stores. It does not. The next question is usually maintenance: does carrying both families cost more to maintain? We have a setup where they sit side by side, and we cannot put a number on what maintaining it costs.
There is a ceiling on this article, and it is worth naming. Several institutions sharing a single system under their own brands brings decisions of its own, and those belong to separate work on the enterprise software side.
The shape of the record decides which store it lands in
Four real records, set side by side, make the order visible: where fields are declared up front and records refer to one another, the table side; where shape differs from one record to the next, the document side. Read the rows for that.
| Record | Shape of the record | How it links to another record | Which store family it sits in |
|---|---|---|---|
| A dental treatment plan and the appointment attached to it | Fields declared up front: which tooth, which procedure, which session in the sequence | The appointment names the plan step it sits under | Table side; every record carries the same fields |
| An exam result read off an optical form | Comes off every form the same way: the marks and their matches | The result is written onto the exam’s own record | Table side; the result lands on a record already there |
| A cropped question and its image | Question, image and answer as a single piece | The answer is not in a separate document, it is inside the question’s record | Document side; the record is whole in itself |
| An AI character in Secretum, a product we are still building | Not fixed: the record gains fields as the character gains abilities (still in development) | The record sits under an account, not under a session | Document side; shape can differ from record to record |
Start with the clinic row. In the dental clinic CRM each tooth gets its own entry in the plan and the work is split into sessions in a set order, and each appointment is tied to a named step inside it, so the link lives in the record and not on a screen. Why it was built that way is a different question, one we took up in separating appointments from service requests. Here only the declaration matters: which tooth, which procedure, which session, in the same place on every plan record.
The cropped question row sits at the far end. A cropped question holds its image and its answer together, with the answer stored inside the question’s own record, not in a separate document beside it. Nothing in our portfolio illustrates the document shape more plainly. Rebuild that record on the table side and the question, the image and the answer become separate rows, with the links between them declared on top.
None of this amounts to a rule. It is what four records look like when you read them next to each other, and our portfolio holds no further pairing to set beside them; an example we do not have is one we will not invent. If you could write a sentence of the form records shaped like this belong in that store, the decision would be easy. You cannot, because the same shape sits inside different links in different systems, and when the links move so does the answer.
What we do with a record whose shape is still growing
Secretum is a product we are still building. It is not live yet, and how the character record is constructed is still open. This is the only place in our portfolio where the reason for choosing the document side is written down, so this section stays with a single record.
The character is kept as a document record because of the state the record is in. Give a character a new ability and the list of fields it carries grows longer, and that growth has not finished. Nothing forces us to redeclare the shape on each addition; the new field simply comes into being inside the record. Close the list today and every ability arriving tomorrow would begin by reopening it.
Persistence shows up here too. The character sits under an account as a lasting record, so a closed session leaves its name, its settings and the history it has gathered untouched. Where the record is anchored, the account and not the session, is a decision apart from its shape: one settles what the record looks like, the other what it hangs from.
The price of that freedom has to be written down as well. Where shape is not identical across records, the store makes no promise about which records carry a given field, so the promise has to be built in code. Work the schema absorbs on the table side moves up into the application layer on the document side. It is a trade, and naming it as one is more honest than selling the flexibility on its own.
The reverse holds with equal force. Where shape has settled, the same freedom buys nothing: the clinic’s plan record has its fields declared up front and sits on the table side, with no use for flexibility, because which fields would arrive was answered long ago. Novelty is not the trigger either, since a new product can have a settled record shape. The trigger is narrower. If it has not yet been written down which fields a record will carry, locking the shape is premature.
What a store type in your proposal tells you about your records
Which brings us back to the proposal. The store type named there is not grading the software; it is describing your records, and it puts a question to you: are the fields declared up front and the records pointing at one another, or is the shape still growing?
A store type on its own will not answer what a business is really asking. Vipkurum carries both families in its record layer, yet the institution boundary is carried by the record itself and not by the family: no institution’s student, guardian or payment records reach another, and a manager’s report draws only on their own institution’s data. Move the same record into the other family and the boundary question would still be asked in the same place.
The clinic shows the same separation. Treatment, scheduling and billing are all read off a single patient record there, which is not a store type decision but a decision about what the record binds to. Switching store types would not create that link; the definition of the record is what creates it. So the line in your proposal speaks to the shape of the record, not to what it binds to.
And the moment that decision gets taken is before anything is set up, with the shape of the record and its links committed before the first line is written. We covered the timing of that commitment, and the cost of reversing it, in why software architecture matters. Shape is this article’s half of the question; timing is that one’s.
Reading the term is not always enough either. Where shape has not settled, the term carries no promise, because which fields will arrive has not been written down. Secretum sits in exactly that position, and we are still building it. So if a line like that turns up in your proposal, the thing worth asking about is not a product name but which fields the record will carry and what it will be bound to.
We settle the shape your records keep, and what they bind to, before the first line is written; the system architecture engagement is where that list of decisions goes on the table.