Data model

A RhyDB database consists of typed tables and indexes.

Tables, rows and columns

A RhyDB database consists of tables. Each table has a schema that defines its columns and their types. Every row in the table follows that schema.

Column types

RhyDB supports the following types for stored columns:

NameDescription
stringText values, optionally dictionary-encoded and bitmap-indexed.
compressed stringText compressed with a shared Zstandard dictionary (e.g. used for unaligned sequences).
int32

Signed 32-bit whole numbers. Also configurable under its alias int.

int64Signed 64-bit whole numbers, for values beyond the 32-bit range.
floatDouble-precision floating-point numbers.
date

Calendar dates in YYYY-MM-DD format.

boolean

true or false values.

nucleotide sequenceAligned nucleotide symbols and their insertions.
amino-acid sequenceAligned amino-acid symbols and their insertions.

Indexes

A bitmap index can be enabled for a string column and supports efficient equality and set-membership filters. Each aligned nucleotide and amino-acid sequence has built-in bitmap structures that index symbols by reference position. A lineage index augments an indexed string column with a configured directed acyclic graph of lineage relationships, enabling queries that include sublineages.

Example schemas

The following schemas illustrate two example arrangements of tables and columns in RhyDB.

Example: one table per organism

One possible schema has a separate table for every organism. In this example, each row represents one sequence record. The columns of each table are defined independently. The model is similar to how Loculus and Pathoplexus currently organize organism-specific datasets.

measles(
  accession: string,
  date: date,
  location: string (indexed),
  lineage: string (indexed),
  sequence: compressed string,
  alignment: nucleotide sequence,
  N: amino-acid sequence,
  ...
)

mpox(
  accession: string,
  date: date,
  location: string (indexed),
  outbreak_lineage: string (indexed),
  sequence: compressed string,
  alignment: nucleotide sequence,
  ...
)

Example: shared records and separate alignments

Another possible schema stores columns shared across reference genomes in one table. A separate table for every reference genome contains a join key, aligned sequence columns and columns derived from that alignment. In this model, a sequence may be not aligned to any reference, or be aligned to one or multiple references.

records(
  accession: string,
  organism: string (indexed),
  date: date,
  location: string (indexed),
  sequence: compressed string,
  ...
)

measles_alignment(
  accesson: string,
  alignment: nucleotide sequence,
  N: amino-acid sequence,
  completeness: float,
  ...
)

mpox_alignment(
  accession: string,
  alignment: nucleotide sequence,
  completeness: float,
  ...
)