Skip to main content

Database

Struct Database 

Source
pub struct Database { /* private fields */ }
Expand description

MoteDB 数据库实例

§快速开始

use motedb::Database;

// 打开数据库
let db = Database::open("data.mote")?;

// SQL 操作
db.execute("CREATE TABLE users (id INT, name TEXT, email TEXT)")?;
db.execute("INSERT INTO users VALUES (1, 'Alice', 'alice@example.com')")?;
let results = db.query("SELECT * FROM users WHERE id = 1")?;

// 多模态索引
db.execute("CREATE INDEX users_email ON users(email)")?;  // 列索引
db.execute("CREATE VECTOR INDEX docs_vec ON docs(embedding)")?;  // 向量索引
```ignore///

# 1. SQL 操作
- `query()` / `execute()`: 执行 SQL 语句

# 2. 事务管理
- `begin_transaction()`: 开始事务
- `commit_transaction()`: 提交事务
- `rollback_transaction()`: 回滚事务
- `savepoint()`: 创建保存点

# 3. 批量操作
- `batch_insert()`: 批量插入行
- `batch_insert_with_vectors()`: 批量插入向量数据

# 4. 索引管理
- `create_column_index()`: 创建列索引(快速等值/范围查询)
- `create_vector_index()`: 创建向量索引(KNN搜索)
- `create_text_index()`: 创建全文索引(BM25搜索)
- `create_ioctree_index()`: 创建i-Octree 3D空间索引

# 5. 查询API
- `query_by_column()`: 按列值查询(使用索引)
- `vector_search()`: 向量KNN搜索
- `text_search()`: 全文搜索(BM25)
- `query_timestamp_range()`: 时间序列查询

# 6. 统计信息
- `stats()`: 数据库统计信息
- `vector_index_stats()`: 向量索引统计
- `transaction_stats()`: 事务统计

# 7. 持久化
- `flush()`: 刷新数据到磁盘
- `checkpoint()`: 创建检查点
- `close()`: 关闭数据库

Implementations§

Source§

impl Database

Source

pub fn create<P: AsRef<Path>>(path: P) -> Result<Self>

创建新数据库

§Examples
let db = Database::create("data.mote")?;
Source

pub fn create_with_config<P: AsRef<Path>>( path: P, config: DBConfig, ) -> Result<Self>

使用自定义配置创建数据库

§Examples
use motedb::DBConfig;

let config = DBConfig {
    memtable_size_mb: 16,
    ..Default::default()
};
let db = Database::create_with_config("data.mote", config)?;
Source

pub fn open<P: AsRef<Path>>(path: P) -> Result<Self>

打开已存在的数据库

§Examples
let db = Database::open("data.mote")?;
Source

pub fn open_with_config<P: AsRef<Path>>( path: P, config: DBConfig, ) -> Result<Self>

Open an existing database with custom configuration

Use this to apply edge-optimized settings when reopening:

let config = DBConfig::for_edge();
let db = Database::open_with_config("data.mote", config)?;
Source

pub fn flush(&self) -> Result<()>

刷新所有数据到磁盘

§Examples
db.execute("INSERT INTO users VALUES (1, 'Alice', 25)")?;
db.flush()?; // 确保数据持久化
Source

pub fn wait_for_indexes_ready(&self) -> bool

Wait until all pending index build batches have been processed.

Call after flush() to ensure indexes are fully built before querying. Returns true if all batches completed, false on timeout.

Source

pub fn columnar_store(&self) -> &ColumnarStore

Access the columnar segment store (for TimeSeries tables).

Source

pub fn checkpoint(&self) -> Result<()>

Checkpoint: flush data + persist indexes + truncate WAL

Stronger durability guarantee than flush() alone. Use before closing to ensure full recoverability.

Source

pub fn checkpoint_full(&self) -> Result<()>

Full checkpoint with index rebuild (slower but thorough). Used internally on shutdown to ensure index completeness.

Source

pub fn vacuum(&self) -> Result<()>

VACUUM: reclaim space by forcing compaction and dropping tombstones.

This runs a full compaction cycle across all LSM levels, dropping tombstone entries and reclaiming disk space. Also flushes column indexes to disk and ensures they are consistent.

§Cost
  • Blocks writes during compaction (may take seconds to minutes).
  • Rewrites all SSTables.
§When to use
  • After bulk DELETE operations
  • Before taking a backup
  • Periodically in long-running deployments (e.g., weekly)
Source

pub fn close(&self) -> Result<()>

关闭数据库(显式调用,通常由 Drop 自动处理)

Sets the closed flag so all subsequent operations return DatabaseClosed error. Idempotent: safe to call multiple times.

§Examples
db.close()?;
// All subsequent operations will return an error
Source

pub fn max_result_rows(&self) -> Option<usize>

🚀 执行 SQL 查询(流式零内存开销)

返回流式结果,支持:

  1. 流式遍历(零内存开销)
  2. 物化为 Vec(等同于旧的 execute)
§Examples
// 方式 1: 流式处理大结果集(推荐)
let result = db.execute("SELECT * FROM users WHERE age > 18")?;
result.for_each(|columns, row| {
    println!("{:?}: {:?}", columns, row);
    Ok(())
})?;

// 方式 2: 物化为 Vec(兼容旧 API)
let result = db.execute("SELECT * FROM users")?;
let materialized = result.materialize()?;
match materialized {
    QueryResult::Select { columns, rows } => {
        println!("Found {} rows", rows.len());
    }
    _ => {}
}

// 其他语句(INSERT/UPDATE/DELETE/CREATE/DROP)
db.execute("CREATE TABLE users (id INT, name TEXT, email TEXT)")?;
db.execute("INSERT INTO users VALUES (1, 'Alice', 'alice@example.com')")?;
db.execute("UPDATE users SET email = 'new@example.com' WHERE id = 1")?;
db.execute("DELETE FROM users WHERE id = 1")?;
db.execute("CREATE INDEX users_email ON users(email)")?;
db.execute("CREATE VECTOR INDEX docs_vec ON docs(embedding)")?;

Returns the configured max_result_rows limit, if any. Use with for_each() or materialize_with_limit() for bounded queries.

Source

pub fn query(&self, sql: &str) -> Result<Vec<Vec<Value>>>

Convenience method: execute a SELECT query and return rows directly. This is shorthand for execute(sql)?.materialize()? + pattern match.

Returns an empty Vec for non-SELECT statements.

§Example
let rows = db.query("SELECT * FROM users WHERE age > 18")?;
for row in rows {
    println!("{:?}", row);
}
Source

pub fn row_count(&self, table_name: &str) -> Result<usize>

Get the approximate row count for a table without executing SQL. Returns the live row count from the ColSegmentStore if available, otherwise falls back to the LSM row counter.

Source

pub fn execute(&self, sql: &str) -> Result<StreamingQueryResult>

Source

pub fn execute_prepared( &self, sql: &str, params: Vec<Value>, ) -> Result<StreamingQueryResult>

Execute a parameterized query.

The SQL string is parsed once and cached (by the same LRU statement cache as execute()). On subsequent calls with the same SQL text, the cached AST is reused — only the bind values change. This eliminates the Lexer → Parser overhead for repeated queries.

Use ? for positional parameters:

// First call: parses + caches
let result = db.execute_prepared("SELECT * FROM users WHERE id = ?", vec![Value::Integer(42)])?;
// Second call: cache hit, skips parser
let result = db.execute_prepared("SELECT * FROM users WHERE id = ?", vec![Value::Integer(99)])?;
Source

pub fn begin_transaction(&self) -> Result<u64>

开始新事务

§Examples
let tx_id = db.begin_transaction()?;

db.execute("INSERT INTO users VALUES (1, 'Alice', 25)")?;
db.execute("INSERT INTO users VALUES (2, 'Bob', 30)")?;

db.commit_transaction(tx_id)?;
Source

pub fn commit_transaction(&self, tx_id: u64) -> Result<()>

提交事务

§Examples
let tx_id = db.begin_transaction()?;
db.execute("INSERT INTO users VALUES (1, 'Alice', 25)")?;
db.commit_transaction(tx_id)?;
Source

pub fn rollback_transaction(&self, tx_id: u64) -> Result<()>

回滚事务

§Examples
let tx_id = db.begin_transaction()?;
db.execute("INSERT INTO users VALUES (1, 'Alice', 25)")?;
db.rollback_transaction(tx_id)?; // 撤销所有修改
Source

pub fn savepoint(&self, tx_id: u64, name: &str) -> Result<()>

创建保存点(事务内的检查点)

§Examples
let tx_id = db.begin_transaction()?;

db.execute("INSERT INTO users VALUES (1, 'Alice', 25)")?;
db.savepoint(tx_id, "sp1")?;

db.execute("INSERT INTO users VALUES (2, 'Bob', 30)")?;
db.rollback_to_savepoint(tx_id, "sp1")?; // 只回滚 Bob 的插入

db.commit_transaction(tx_id)?;
Source

pub fn rollback_to_savepoint(&self, tx_id: u64, name: &str) -> Result<()>

回滚到保存点

Source

pub fn release_savepoint(&self, tx_id: u64, name: &str) -> Result<()>

释放保存点

Source

pub fn batch_insert( &self, table_name: &str, rows: Vec<Row>, ) -> Result<Vec<RowId>>

批量插入行(比逐行插入快10-20倍)

注意: 此方法接受底层 Row 类型(Vec<Value>),如果需要使用 HashMap,请使用 batch_insert_map()

§Examples
use motedb::types::{Value, Row};

let mut rows = Vec::new();
for i in 0..1000 {
    let row = vec![
        Value::Integer(i),
        Value::Text(format!("User{}", i)),
    ];
    rows.push(row);
}

let row_ids = db.batch_insert("users", rows)?;
println!("Inserted {} rows", row_ids.len());
Source

pub fn batch_insert_map( &self, table_name: &str, sql_rows: Vec<SqlRow>, ) -> Result<Vec<RowId>>

批量插入行(使用 HashMap,比逐行插入快10-20倍)

这是 batch_insert() 的友好版本,接受 HashMap<String, Value> 格式的行数据。

§Examples
use motedb::types::{Value, SqlRow};
use std::collections::HashMap;

let mut rows = Vec::new();
for i in 0..1000 {
    let mut row = HashMap::new();
    row.insert("id".to_string(), Value::Integer(i));
    row.insert("name".to_string(), Value::Text(format!("User{}", i)));
    rows.push(row);
}

let row_ids = db.batch_insert_map("users", rows)?;
println!("Inserted {} rows", row_ids.len());
Source

pub fn batch_insert_with_vectors_map( &self, table_name: &str, sql_rows: Vec<SqlRow>, vector_columns: &[&str], ) -> Result<Vec<RowId>>

Source

pub fn batch_insert_with_vectors( &self, table_name: &str, rows: Vec<Row>, _vector_columns: &[&str], ) -> Result<Vec<RowId>>

批量插入带向量的数据(自动构建向量索引)

注意: 此方法接受底层 Row 类型(Vec<Value>),如果需要使用 HashMap,请使用 batch_insert_with_vectors_map()

§Examples
use motedb::types::{Value, Row};

let mut rows = Vec::new();
for i in 0..1000 {
    let row = vec![
        Value::Integer(i),
        Value::Vector(vec![0.1; 128]),
    ];
    rows.push(row);
}

let row_ids = db.batch_insert_with_vectors("documents", rows, &["embedding"])?;
Source

pub fn create_column_index( &self, table_name: &str, column_name: &str, ) -> Result<()>

批量插入带向量的数据(使用 HashMap,自动构建向量索引)

§Examples
use motedb::types::{Value, SqlRow};
use std::collections::HashMap;

let mut rows = Vec::new();
for i in 0..1000 {
    let mut row = HashMap::new();
    row.insert("id".to_string(), Value::Integer(i));
    row.insert("embedding".to_string(), Value::Vector(vec![0.1; 128]));
    rows.push(row);
}

let row_ids = db.batch_insert_with_vectors_map("documents", rows, &["embedding"])?;

创建列索引(用于快速等值/范围查询)

§Examples
// 创建列索引后,WHERE email = '...' 查询速度提升40倍
db.create_column_index("users", "email")?;

// 查询会自动使用索引
let results = db.query("SELECT * FROM users WHERE email = 'alice@example.com'")?;
Source

pub fn create_vector_index( &self, index_name: &str, dimension: usize, ) -> Result<()>

创建向量索引(用于KNN相似度搜索)

§Examples
// 为128维向量创建索引
db.create_vector_index("docs_embedding", 128)?;

// SQL 向量搜索
let query = "SELECT * FROM docs
             ORDER BY embedding <-> [0.1, 0.2, ...]
             LIMIT 10";
let results = db.query(query)?;
Source

pub fn create_text_index(&self, index_name: &str) -> Result<()>

创建全文索引(用于BM25文本搜索)

§Examples
// 创建全文索引
db.create_text_index("articles_content")?;

// SQL 全文搜索
let results = db.query(
    "SELECT * FROM articles WHERE MATCH(content, 'rust database')"
)?;
Source

pub fn query_by_column( &self, table_name: &str, column_name: &str, value: &Value, ) -> Result<Vec<RowId>>

按列值查询(使用列索引,等值查询)

§Examples
use motedb::Value;

// 前提:已创建列索引
db.create_column_index("users", "email")?;

// 快速查询(使用索引)
let row_ids = db.query_by_column(
    "users",
    "email",
    &Value::Text("alice@example.com".into())
)?;
Source

pub fn query_by_column_range( &self, table_name: &str, column_name: &str, start: &Value, end: &Value, ) -> Result<Vec<RowId>>

按列范围查询(使用列索引)

§Examples
use motedb::Value;

// 查询年龄在 20-30 之间的用户
let row_ids = db.query_by_column_range(
    "users",
    "age",
    &Value::Integer(20),
    &Value::Integer(30)
)?;
Source

pub fn query_by_column_between( &self, table_name: &str, column_name: &str, start: &Value, start_inclusive: bool, end: &Value, end_inclusive: bool, ) -> Result<Vec<RowId>>

按列范围查询(精确控制边界,使用列索引)

§边界语义
  • start_inclusive: 下界是否包含(>= vs >)
  • end_inclusive: 上界是否包含(<= vs <)
§Examples
use motedb::Value;

// 查询 id >= 100 AND id < 200 (左闭右开)
let row_ids = db.query_by_column_between(
    "users",
    "id",
    &Value::Integer(100), true,
    &Value::Integer(200), false
)?;

向量KNN搜索

§Examples
// 查找最相似的10个向量
let query_vec = vec![0.1; 128];
let results = db.vector_search("docs_embedding", &query_vec, 10)?;

for (row_id, distance) in results {
    println!("RowID: {}, Distance: {}", row_id, distance);
}
Source

pub fn text_search_ranked( &self, index_name: &str, query: &str, top_k: usize, ) -> Result<Vec<(RowId, f32)>>

全文搜索(BM25排序)

§Examples
// 搜索包含关键词的文档(BM25排序)
let results = db.text_search_ranked("articles_content", "rust database", 10)?;

for (row_id, score) in results {
    println!("RowID: {}, BM25 Score: {}", row_id, score);
}
Source

pub fn query_timestamp_range(&self, start: i64, end: i64) -> Result<Vec<RowId>>

时间序列范围查询

§Examples
// 查询指定时间范围内的记录
let start_ts = 1609459200; // 2021-01-01 00:00:00
let end_ts = 1640995200;   // 2022-01-01 00:00:00
let row_ids = db.query_timestamp_range(start_ts, end_ts)?;
Source

pub fn vector_index_stats(&self, index_name: &str) -> Result<VectorIndexStats>

获取向量索引统计信息

§Examples
let stats = db.vector_index_stats("docs_embedding")?;
println!("向量数量: {}", stats.vector_count);
println!("平均邻居数: {}", stats.avg_neighbors);
Source

pub fn create_ioctree_index(&self, index_name: &str) -> Result<()>

Create an i-Octree 3D spatial index for point cloud data

Use for SLAM, robotics, and 3D perception workloads.

3D KNN query: find k nearest neighbors

Returns (row_id, distance) pairs sorted by distance.

Source

pub fn transaction_stats(&self) -> TransactionStats

3D radius search: find all points within radius 获取事务统计信息

§Examples
let stats = db.transaction_stats();
println!("活跃事务数: {}", stats.active_transactions);
println!("已提交事务数: {}", stats.committed_transactions);
Source

pub fn insert_row(&self, table_name: &str, row: Row) -> Result<RowId>

插入行(底层API,推荐使用 SQL INSERT)

注意: 此方法接受底层 Row 类型(Vec<Value>),如果需要使用 HashMap,请使用 insert_row_map()

§Examples
use motedb::types::{Value, Row};

let row = vec![
    Value::Integer(1),
    Value::Text("Alice".into()),
];

let row_id = db.insert_row("users", row)?;
Source

pub fn insert_row_with_txn( &self, table_name: &str, txn_id: u64, row: Row, ) -> Result<RowId>

Insert a row within a transaction. The row is buffered and only written to storage when the transaction commits. Use this instead of insert_row when operating inside a transaction.

Source

pub fn insert_row_map(&self, table_name: &str, sql_row: SqlRow) -> Result<RowId>

插入行(使用 HashMap)

这是 insert_row() 的友好版本,接受 HashMap<String, Value> 格式的行数据。

§Examples
use motedb::types::{Value, SqlRow};
use std::collections::HashMap;

let mut row = HashMap::new();
row.insert("id".to_string(), Value::Integer(1));
row.insert("name".to_string(), Value::Text("Alice".into()));

let row_id = db.insert_row_map("users", row)?;
Source

pub fn get_row(&self, table_name: &str, row_id: RowId) -> Result<Option<Row>>

获取行(底层API,推荐使用 SQL SELECT)

Source

pub fn get_row_map( &self, table_name: &str, row_id: RowId, ) -> Result<Option<SqlRow>>

获取行(返回 HashMap 格式)

§Examples
if let Some(row) = db.get_row_map("users", 1)? {
    println!("Name: {:?}", row.get("name"));
}
Source

pub fn update_row( &self, table_name: &str, row_id: RowId, new_row: Row, ) -> Result<()>

更新行(底层API,推荐使用 SQL UPDATE)

Source

pub fn delete_row(&self, table_name: &str, row_id: RowId) -> Result<()>

删除行(底层API,推荐使用 SQL DELETE)

Trait Implementations§

Source§

impl Drop for Database

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V