# Store and update keyed records

A simple key-value task fits a table with a primary key and a value column. The key contract prevents several rows from representing the same identifier, while ordinary SQL supports lookup, replacement and deletion.

```sql
CREATE TABLE app_values(key TEXT PRIMARY KEY, value TEXT NOT NULL);
INSERT INTO app_values VALUES ('theme', 'light');

INSERT INTO app_values(key, value) VALUES ('theme', 'dark')
ON CONFLICT(key) DO UPDATE SET value = excluded.value;

SELECT value FROM app_values WHERE key = 'theme' FORMAT csv;
```

The final value is `dark`. An absolute-value upsert can be repeated without appending another row for the same key. It does not automatically make a multi-key application operation atomic; use an explicit transaction when several records must change together.

Choose types according to the stored value. Use JSON when the value is a document that will be queried structurally, or separate columns when fields need their own constraints and predicates. A native Map inside one row has different duplicate-key and missing-value rules from this table.

For multiple application processes, connect to one server rather than opening one shared database file independently.

See [table constraints](https://coordinatordb.com/docs/reference/statements/create/table), [upserts](https://coordinatordb.com/docs/reference/statements/insert-into), [JSON](https://coordinatordb.com/docs/reference/data-types/json) and [deployment modes](https://coordinatordb.com/docs/get-started/about/deployment-modes).
