Skip to main content

CamusDB tutorial

This tutorial takes you from install to working SQL. You start a CamusDB node, create a database and a table, insert and query rows, add an index, rename objects, and update and delete data. Use the camus-cli terminal shell or the Web Console, or try every step in the embedded browser playground first.

CamusDB is an open-source distributed SQL database with a full relational engine, not a thin SQL layer over a key/value store. The SQL in this tutorial runs the same on one node or on a cluster, so you can start small and add nodes later. To see what CamusDB adds over a single-node database, read Why CamusDB?.

Try it in your browser​

You can run the tutorial commands here before installing anything. The embedded playground starts with a pre-created playground database, but you can also create your own and switch to it with the database selector. Each step explains what its SQL does. Click Run to execute a step, then click Next. Next unlocks only after the current step runs without an error, so the steps always run in order. Prev goes back to an earlier step. You can also edit the SQL before running it.

WebAssembly

Run the tutorial here

This is the real CamusDB engine compiled to WebAssembly. It runs as a single in-memory node inside this browser tab.

Loading the engine...

Step 1 of 7 · Create database

Creates the factory database. IF NOT EXISTS makes the statement safe to run again. After it runs, the database selector switches to factory, so the next steps run there.

Click Run to finish this step. Next unlocks when it runs without an error.

The engine is loading. The first load downloads the WebAssembly runtime.

Single-node, in-memory engine. Data stays in this tab and resets on reload.

Video walkthrough​

Start CamusDB​

Choose one installation method. Each starts a standalone node with the HTTP API on port 5095 and gRPC on 5096. For service setup, data locations, and updates, see Server installation.

Install the .NET 10 SDK, then install the server as a global tool and start it:

dotnet tool install --global CamusDB.Server
camusdb

Connect with a SQL client​

Choose the terminal shell or the browser-based Web Console. Both connect to the node you started above and run the same SQL. The tool installation commands below require the .NET 10 SDK, including when the server runs through Homebrew or Docker.

Install the SQL shell and open it in another terminal:

dotnet tool install --global CamusDB.SqlSh
camus-cli

The shell connects to the local server, trying gRPC on port 5096 first and REST on 5095 as a fallback. A camus> prompt means you can enter SQL.

Create a database​

Create the tutorial database in your chosen client's SQL editor or prompt:

CREATE DATABASE factory;

Then select it for the remaining steps:

  • camus-cli: run USE factory;. For later sessions, you can start the shell with camus-cli factory.
  • Web Console: click factory in the database sidebar, or select it in Configure as the session database.

The database must exist before you select it. The statements below run in factory in either client.

Create a table​

Create a table to store robots:

CREATE TABLE robots (
id OID PRIMARY KEY NOT NULL,
name STRING NOT NULL,
kind STRING NOT NULL,
year INT64 DEFAULT (2024)
);

The table has four columns:

ColumnTypeNotes
idOIDPrimary key object id.
nameSTRINGRequired robot name.
kindSTRINGRequired category or model family.
yearINT64Optional year with a default value.

For UUID identifiers, use the native UUID type instead of STRING. A UUID column stores a compact 128-bit value and produces smaller index keys than the UUID's text form.

Inspect the schema​

Show the tables in the current database:

SHOW TABLES;
┌────────┐
│ tables │
├────────┤
│ robots │
└────────┘
1 rows in set (00:00:00.0526560)

Show the columns of robots:

SHOW COLUMNS FROM robots;
┌───────┬───────────┬──────┬─────┬─────────┬───────┐
│ Field │ Type │ Null │ Key │ Default │ Extra │
├───────┼───────────┼──────┼─────┼─────────┼───────┤
│ id │ Id │ NO │ PRI │ NULL │ │
│ name │ String │ NO │ │ NULL │ │
│ kind │ String │ NO │ │ NULL │ │
│ year │ Integer64 │ YES │ │ 2024 │ │
└───────┴───────────┴──────┴─────┴─────────┴───────┘
4 rows in set (00:00:00.0189059)

These commands are also useful for inspecting a table:

DESCRIBE robots;
SHOW CREATE TABLE robots;
SHOW INDEX FROM robots;

Show the table's SQL definition:

SHOW CREATE TABLE robots;
┌────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Table │ Create Table │
├────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ robots │ CREATE TABLE `robots` ( `id` OID NOT NULL, `name` STRING NOT NULL, `kind` STRING NOT NULL, `year` INT64 NULL, PRIMARY KEY (`id`)); │
└────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
1 rows in set (00:00:00.0037082)

Insert rows​

Insert one row:

INSERT INTO robots (id, name, kind, year)
VALUES (GEN_ID(), 'R2-D2', 'utility', 1977);

Insert several rows with one statement:

INSERT INTO robots (id, name, kind, year)
VALUES
(GEN_ID(), 'C-3PO', 'protocol', 1977),
(GEN_ID(), 'T-800', 'android', 1984);

Use DEFAULT to have CamusDB apply the column's default value:

INSERT INTO robots (id, name, kind, year)
VALUES (GEN_ID(), 'K-2SO', 'security', DEFAULT);

Query rows​

Select the rows in the table:

SELECT id, name, kind, year FROM robots ORDER BY year ASC;
┌──────────────────────────┬───────┬──────────┬──────┐
│ id │ name │ kind │ year │
├──────────────────────────┼───────┼──────────┼──────┤
│ 6a3dd713d615ae230488d7f2 │ R2-D2 │ utility │ 1977 │
│ 6a3dd71bd615ae230488d7f4 │ C-3PO │ protocol │ 1977 │
│ 6a3dd71bd615ae230488d7f5 │ T-800 │ android │ 1984 │
│ 6a3dd726d615ae230488d7f8 │ K-2SO │ security │ 2024 │
└──────────────────────────┴───────┴──────────┴──────┘
4 rows in set (00:00:00.0232238)

Filter the result with a WHERE clause:

SELECT name, year FROM robots WHERE year >= 1980;
┌───────┬──────┐
│ name │ year │
├───────┼──────┤
│ T-800 │ 1984 │
│ K-2SO │ 2024 │
└───────┴──────┘
2 rows in set (00:00:00.0298712)

LIKE and ILIKE match a pattern:

SELECT id, name FROM robots WHERE name ILIKE 'r%';
┌──────────────────────────┬───────┐
│ id │ name │
├──────────────────────────┼───────┤
│ 6a3dd713d615ae230488d7f2 │ R2-D2 │
└──────────────────────────┴───────┘
1 rows in set (00:00:00.0254039)

Aggregate the rows:

SELECT COUNT(*) FROM robots;
SELECT MIN(year), MAX(year) FROM robots;

Create an index​

An index lets CamusDB find matching rows without scanning every row in the table.

CREATE INDEX robots_kind_idx ON robots (kind);

Inspect the indexes:

SHOW INDEXES FROM robots;

Rename schema objects​

You can rename tables and columns. CamusDB does not rewrite any row data:

ALTER TABLE robots RENAME COLUMN kind TO category;
ALTER TABLE robots RENAME TO machines;

Update rows​

Unlike PostgreSQL and MySQL, CamusDB requires a WHERE clause on every UPDATE. To update every row, write WHERE true.

UPDATE machines
SET year = 1982
WHERE name = 'T-800';

Confirm the change:

SELECT name, year
FROM machines
WHERE name = 'T-800';

Delete rows​

CamusDB also requires a WHERE clause on every DELETE. To delete every row, write WHERE true.

DELETE FROM machines
WHERE name = 'K-2SO';

Next, read the SQL overview, Data Types, and Tables And Columns.

Then read SELECT to learn filtering, grouping, and ordering, and Joins And Subqueries for joins, subqueries, and derived tables.

Connect an application​

Use the .NET driver, TypeScript connector, or Python driver. They provide parameter binding, query results, and transaction APIs, with helpers for retryable conflicts. The libraries handle the HTTP/JSON or gRPC messages behind those APIs.

Ready for more?​

Explore the advanced samples to see CamusDB in complete ecommerce, banking, and booking applications. They demonstrate transactions, retries, idempotency, concurrency, database branching, and failure handling through .NET, EF Core, and TypeScript.