# Core Concepts

This page gives you the mental model for ApexBase before you dive into the API reference.

## Database Root

An `ApexClient` opens a root directory:

```python
from apexbase import ApexClient

client = ApexClient("./data")
```

The root directory contains the default database and any named databases. ApexBase stores each table as a `.apex` file.

## Databases

ApexBase supports multiple isolated databases under one root directory. The default database maps to the root directory. Named databases live in subdirectories.

```python
client.use_database("analytics")
client.use(database="analytics", table="events")

print(client.list_databases())
print(client.current_database)
```

SQL can refer to another database with `database.table` syntax:

```python
client.execute("""
    SELECT u.name, e.event
    FROM default.users u
    JOIN analytics.events e ON u.id = e.user_id
""")
```

## Tables

Tables are explicit. Create or select a table before using table-scoped methods such as `store()`, `retrieve_all()`, and `list_fields()`.

```python
client.create_table("users")
client.use_table("users")
```

You can also create tables with SQL:

```python
client.execute("CREATE TABLE IF NOT EXISTS users")
```

## Schemas

You may let ApexBase infer column types from the first write, or provide a schema up front for clearer contracts and faster bulk loading.

```python
client.create_table("orders", schema={
    "order_id": "int64",
    "customer": "string",
    "total": "float64",
    "paid": "bool",
})
```

## Records And Columns

ApexBase accepts row-oriented dictionaries, lists of dictionaries, and columnar dictionaries. For bulk ingest, columnar data is usually the fastest path.

```python
client.store({"name": "Alice", "age": 30})

client.store([
    {"name": "Bob", "age": 25},
    {"name": "Charlie", "age": 35},
])

client.store({
    "name": ["Diana", "Eve"],
    "age": [28, 41],
})
```

Every stored row has an internal `_id`. SQL hides `_id` unless you request it explicitly.

## ResultView

Queries return a `ResultView`, which can convert to Python-native rows or columnar DataFrame formats.

```python
result = client.execute("SELECT * FROM users")

rows = result.to_dict()
pandas_df = result.to_pandas()
polars_df = result.to_polars()
arrow_table = result.to_arrow()
```

Use `ResultView` when you want to move smoothly between SQL, Python lists, Pandas, Polars, and PyArrow.

## Durability

Durability is configured when opening the client:

| Mode | Best for | Behavior |
| --- | --- | --- |
| `fast` | Local analytics, scratch data, benchmarks | Prioritizes throughput |
| `safe` | Application data with balanced speed and safety | Synchronous writes |
| `max` | Highest crash safety | Fsync on each write |

```python
client = ApexClient("./data", durability="safe")
```

## Interfaces

The same storage engine can be reached through several interfaces:

- Python API for embedded applications and notebooks.
- Rust embedded API for native Rust applications.
- PostgreSQL Wire server for SQL clients and database tools.
- Arrow Flight server for high-throughput columnar result streaming.

Start with the Python API unless you already know you need a wire protocol or Rust integration.
