In short
A schema teaches Linkr how to read a database: which table holds the patients, which one the hospitalizations, where to find a date of birth. It carries two things — the DDL, which describes the tables, and the mapping, which gives them a role. It is what turns a database you can query in SQL into a warehouse Linkr understands.
The problem a schema solves
Two hospitals store the same information under different names. Here the patient table is called person and the date of birth birth_datetime; there it’s patients and dob. A third kept its in-house model.
Linkr does not guess. With no guidance, a database is just a set of tables: you can write SQL against it, and nothing more. No patient page, no cohorts, no demographic statistics.
The schema is that guidance. It says: the patient table is person; its identifier is person_id; the date of birth is birth_datetime. From there, every warehouse feature knows where to look — and the same dashboard works on OMOP in one hospital and on an in-house model in another.
The two halves of a schema
The DDL
The structure: the CREATE TABLE statements describing tables, columns and keys.
It serves two purposes: drawing the diagram, and building an empty database — this is what “New from schema” executes. Without a DDL a schema is still usable, but it cannot create a database.
The mapping
The roles: which table holds patients, hospitalizations, notes.
This is the half Linkr’s pages depend on. A schema with no mapping can only create empty tables; it is the mapping that makes a database readable.
The two are independent. You can have a DDL with no mapping — the structure is known but the roles aren’t — or the reverse, for a database that already exists and that you are only describing.
Getting a schema
Four routes, from the quickest to the longest.
Install from the catalog
The common case. OMOP CDM 5.3 and 5.4, MIMIC-III and MIMIC-IV are published and install in seconds, DDL and mapping included. The Catalog tab of the import dialog.
Import a ZIP or clone a git repository
To pick up a colleague’s schema, or another site’s. Cloning from git needs server mode; the ZIP works everywhere.
Duplicate an existing schema
Start from OMOP to describe your local variant. The original stays untouched.
Create a blank schema
For an in-house model that resembles nothing published. Only the name is required; the DDL and the mapping are filled in afterwards.
A schema’s page
Three tabs, plus the usual Readme, License and Versioning behind the More menu.
Overview
Four counters — tables, foreign keys, indexes, mapped tables — and the readme. Each counter is clickable and leads to the matching tab.
The first three counters read the DDL as text
They come from parsing the DDL, not from executing it. A DDL that declares a primary key inside the CREATE TABLE rather than through an ALTER TABLE won’t be counted, even though it is perfectly valid. The counter is a landmark, not an audit.
DDL
Two views, with a switch at the top left. This tab opens on the diagram.
- Diagram — tables as boxes, columns with their key roles, relationships as lines. You can drag tables around to make it readable, and the layout is kept. A Filter button hides the parts you don’t care about.
- Source — the text editor, with a table of contents on the left listing tables, keys and indexes, and a search field. Clicking an entry scrolls to it.
Cmd/Ctrl+Ssaves.
Groups gather related tables under a name and a colour — “Clinical Data”, “Vocabularies”. They are what make a model like OMOP, with its dozens of tables, actually readable. They also drive the diagram’s automatic layout until you have arranged one by hand.
Write one column per line
The diagram splits a CREATE TABLE body line by line. Put several columns on one line and only the first will appear — in the diagram and in the counters. The DDL still executes correctly: only the drawing is truncated.
The DDL must be written in DuckDB-compatible SQL: it is genuinely executed when an empty database is created from the schema.
Mapping
This is where tables are given a role. Same diagram/source switch, but this tab opens on the source, where editing happens through forms — never raw JSON.
Five sub-tabs:
| Sub-tab | What you declare | What depends on it |
|---|---|---|
| Patient | The patient table, the gender values, the death table | Everything. With no patient table, the Patient data page refuses to render. |
| Hospitalization | The stay table and the unit-stay table | Stay-based cohort criteria, lengths of stay, the admission timeline. |
| Notes | The clinical notes table | The Notes widget and text-based cohort criteria. |
| Events | The measurement, prescription, diagnosis tables… | The Concepts page, cohort criteria, the patient timeline. |
| Concepts | The dictionaries: label and terminology tables | Showing names instead of codes, everywhere. |
Every “table” field autocompletes from the schema’s known tables without ever forcing the value: a half-described model stays editable.
An event table's dictionary is chosen explicitly
Each event table states which dictionary translates its codes. Left empty, the first dictionary is used. The value none means “no join” — the column already holds the label, like a MIMIC drug field carrying “Vancomycin” rather than a numeric identifier.
Getting this wrong produces no error: the join happens anyway, between a drug name and an identifier, and returns nothing. It is the first thing to check when a Concepts page stays empty.
One schema, several databases
A database copies the schema at the moment it is attached. It does not point at it.
That is what makes a database robust: it keeps working if the schema is edited, deleted, or was never installed on the instance it lands on.
Editing a schema does not update existing databases
The correction does not propagate. To apply it to a database that already exists, open Edit on that database and re-select the schema: the copy is then made again.
Symmetrically, deleting a schema breaks no database — each one keeps its copy. Its card simply shows “Schema (not installed)” and stops being a link.
See a real schema
The demo contains the OMOP and MIMIC schemas. OMOP CDM 5.4 is the most telling: dozens of tables, grouped and coloured, with a complete mapping.
A few limits worth knowing
- Some fine-grained settings have no field in the editor. The care-site columns of a stay table, or the composite terminology + code joins of certain event tables, exist and are used by Linkr but cannot be entered through the interface. They arrive via an imported or installed schema. A model that needs them is therefore prepared outside the application, then imported.
- An unusual table or column name is dropped without a message. Names are checked before they enter a query; anything that isn’t a valid SQL identifier disappears from the mapping rather than being flagged. If a field “won’t save”, it is almost always an exotic character or a quote.
- A schema’s name is stored in the interface language. A schema named in French will show in French to an English-speaking user. Nothing is translated automatically.
- The identifier is frozen after creation. The name can be changed at any time.
Going further
- Databases — attaching a schema to a database.
- Concepts — what the dictionaries make possible.
- Concept mapping — aligning your local codes to a standard terminology.
- Community catalog — where OMOP and MIMIC come from.