# Schema

The SQL interface exposes a fixed set of tables. Unknown tables and columns are rejected before a query runs, and [`GET /sql/v1/catalog`](https://dev.nominal.io/sql-reference/rest-api/catalog.md) returns the live list.

These tables are the platform’s own data model made queryable, so the names will be familiar if you have used Nominal through the app. Reading the [data model overview](https://dev.nominal.io/platform/data-model.md) is not a prerequisite, but it explains what assets, runs, datasets, and tags are for, which makes the schema below easier to navigate. The [glossary](https://dev.nominal.io/platform/reference/glossary.md) covers the rest of the terms.

The tables fall into two groups, and the difference determines both how you query them and which functions you can use.

## Telemetry tables

Time-series and log data. **Every query against these must filter by `dataset_rid`.**

| Table | Value type | Purpose |
| --- | --- | --- |
| [`points_double`](https://dev.nominal.io/sql-reference/schema/points_double.md) | `DOUBLE` | Floating-point time series |
| [`points_int`](https://dev.nominal.io/sql-reference/schema/points_int.md) | `BIGINT` | Integer time series |
| [`points_string`](https://dev.nominal.io/sql-reference/schema/points_string.md) | `VARCHAR` | String and enum time series |
| [`points_struct`](https://dev.nominal.io/sql-reference/schema/points_struct.md) | `VARIANT` | Structured, JSON-valued time series |
| [`logs`](https://dev.nominal.io/sql-reference/schema/logs.md) |  | Timestamped log messages |
| [`channels`](https://dev.nominal.io/sql-reference/schema/channels.md) |  | The channels in a dataset, with their tags and data types |

Any dataset can also be read as a table of its own, named by its quoted RID, as in `FROM "<ri.catalog.instance.dataset.identifier>"`. It reads all of the dataset’s points and log entries without a `dataset_rid` filter. See [Reading a whole dataset](https://dev.nominal.io/sql-guides/writing-queries.md#reading-a-whole-dataset).

## Metadata tables

Descriptive records about assets, runs, datasets, and events. No scoping requirement, so these are where you start when you don’t yet know a `dataset_rid`.

| Table | Purpose |
| --- | --- |
| [`assets`](https://dev.nominal.io/sql-reference/schema/assets.md) | Physical things you collect data from |
| [`runs`](https://dev.nominal.io/sql-reference/schema/runs.md) | Time ranges of activity |
| [`run_assets`](https://dev.nominal.io/sql-reference/schema/run_assets.md) | Which assets each run covers |
| [`datasets`](https://dev.nominal.io/sql-reference/schema/datasets.md) | Data sources, with their time bounds |
| [`events`](https://dev.nominal.io/sql-reference/schema/events.md) | Points or intervals of interest |
| [`event_assets`](https://dev.nominal.io/sql-reference/schema/event_assets.md) | Which assets each event is associated with |

## Your query log

[`query_history`](https://dev.nominal.io/sql-reference/schema/query_history.md) sits outside both groups and records the SQL queries you have run. It needs no scoping predicate. You read your own queries from every workspace in your organization, and org admins read everyone’s.

## Column types

Columns report these logical types:

| Type | Notes |
| --- | --- |
| `TIMESTAMP` | Nanosecond precision in the telemetry tables, microsecond precision in the metadata tables. See [Reading timestamps](https://dev.nominal.io/sql-reference/rest-api/query.md#reading-timestamps) for how to read it in Python. |
| `VARCHAR` | Text. |
| `DOUBLE` | Floating point. |
| `BIGINT` | 64-bit integer. |
| `MAP` | Key-value pairs. `tags` and `args` map strings to strings, while `properties` holds typed values. See [Properties](https://dev.nominal.io/sql-reference/schema/assets.md#asset-properties). |
| `ARRAY` | Repeated values, of strings unless noted. |
| `VARIANT` | JSON, in `points_struct.value`. See [points_struct](https://dev.nominal.io/sql-reference/schema/points_struct.md). |

Whole `MAP` and `ARRAY` columns from the metadata tables come back as text, such as `[hotfire, propulsion]` for `labels`. Index into them in the query, as in `labels[1]` or `properties['<key>']['value']`, to get the parts.

## Tags

The `points_*` and `logs` tables each carry a `tags` column of type `MAP`, holding the key-value pairs recorded alongside a series. Tag keys are arbitrary, set at ingest time, and vary between datasets. See [Tags](https://dev.nominal.io/platform/data-model.md#channels) for how they are assigned, and [Filtering by tag](https://dev.nominal.io/sql-guides/writing-queries.md#filtering-by-tag) for how to query them.

## Next steps

- [Writing queries](https://dev.nominal.io/sql-guides/writing-queries.md): scoping, limits, and query patterns.
- [Function reference](https://dev.nominal.io/sql-reference/schema/function-reference.md): the allowlist, and which functions are telemetry-only.
- [Catalog endpoint](https://dev.nominal.io/sql-reference/rest-api/catalog.md): the live schema, straight from the REST API.

- [Function reference](https://dev.nominal.io/sql-reference/schema/function-reference.md)
- [points_double](https://dev.nominal.io/sql-reference/schema/points_double.md)
- [points_int](https://dev.nominal.io/sql-reference/schema/points_int.md)
- [points_string](https://dev.nominal.io/sql-reference/schema/points_string.md)
- [points_struct](https://dev.nominal.io/sql-reference/schema/points_struct.md)
- [logs](https://dev.nominal.io/sql-reference/schema/logs.md)
- [channels](https://dev.nominal.io/sql-reference/schema/channels.md)
- [assets](https://dev.nominal.io/sql-reference/schema/assets.md)
- [runs](https://dev.nominal.io/sql-reference/schema/runs.md)
- [run_assets](https://dev.nominal.io/sql-reference/schema/run_assets.md)
- [datasets](https://dev.nominal.io/sql-reference/schema/datasets.md)
- [events](https://dev.nominal.io/sql-reference/schema/events.md)
- [event_assets](https://dev.nominal.io/sql-reference/schema/event_assets.md)
- [query_history](https://dev.nominal.io/sql-reference/schema/query_history.md)
