# Database

All data managed by DuckAtoms is inserted to or retrieved from a DuckDB
database, which is contained in a single file. As DuckDB is an in-process
database, only one process can access it for read/write operations at a time.
In principle multiple
processes can read from the database concurrently if they are all read-only,
but this is not utilized in the DuckAtoms package. Inside such a database the
data is structured into two tables.

## *Structures* table
The *structures* table always contains columns for:
* **id**: Unique structure identifier
* **cell**: Flattened cell vectors (3,3) -> (9,)
* **pbc**: Periodic boundary conditions
and each structure aka *ase.Atoms* object is saved in one row of the structures
table. The id is automatically
assigned and not changed, even if atoms are removed. You can add additional
*properties* aka columns to the structures table.

## *Atoms* table
The second table is made up with a row for each atom contained in each structure you
inserted. It always contains columns for:
* **id**: Unique atom identifier
* **structure_id**: Reference to the structures table
* **ase_atoms_id**: Atom index from the original ASE Atoms object
* **number**: Atomic number
* **x**, **y**, **z**: Atomic coordinates
Again the id is automatically assigned and not changed after creation and you
can add additional *properties*, such as coordination numbers, local atomic
environment descriptors etc. Those are then stored in additional columns of the
*atoms* table.

In the next section, we will explain how you can set up a database and add
custom columns to the *structures* and *atoms* tables.
