Skip to content

AarambhDevHub/mini-database

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

10 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Mini Database πŸš€

A high-performance graph database built in Rust with both embedded and network modes, featuring ultra-fast node/edge operations, advanced caching, comprehensive graph algorithms, and SQL-like join operations.

Rust License: MIT Build Status


✨ Features

🏎️ High Performance

  • 138,794 ops/sec node retrieval with LRU caching
  • 19,503 ops/sec node creation with compression
  • 10,492 ops/sec network throughput
  • 100% cache hit rate for frequently accessed data

🌐 Dual Architecture

  • Embedded Mode: Direct in-process database for maximum performance
  • Network Mode: TCP client-server with connection pooling (port 5432)
  • Zero-copy operations with memory-mapped files

πŸ“Š Graph Database Features

  • Nodes & Edges with typed properties and metadata
  • Graph Algorithms: BFS, DFS, shortest path, connected components
  • Advanced Queries: Label-based, property-based, range queries
  • Fluent Query Builder with method chaining

πŸ”— SQL-Like Join Operations ✨ NEW

  • INNER JOIN: Edge-based and property-based joining
  • LEFT JOIN: Include all left records with NULL handling
  • RIGHT JOIN: Include all right records
  • FULL OUTER JOIN: Complete union of both sides
  • CROSS JOIN: Cartesian product with filtering
  • Aggregate Joins: SUM, AVG, COUNT, MAX, MIN with GROUP BY
  • WHERE Clauses: Rust closure-based filtering
  • ORDER BY & LIMIT: Sorting and pagination
  • Fluent Builder API: Chain operations with type safety

πŸ”§ Production Ready

  • Connection pooling with idle timeout and cleanup
  • LZ4 compression for storage efficiency
  • Async/await architecture with Tokio
  • Custom binary protocol for network communication
  • Comprehensive error handling and logging

πŸ”— Join Operations Deep Dive

Comprehensive Join Support

Mini Database provides enterprise-grade join functionality that rivals traditional SQL databases while leveraging the power of graph relationships:

// All join types supported
let result = client.join("user", "order")
    .join_type(JoinType::Inner)           // INNER, LEFT, RIGHT, FullOuter, CROSS
    .on_edge("places_order".to_string())  // Edge-based joining
    .select(vec![
        ("user".to_string(), "name".to_string()),
        ("order".to_string(), "total".to_string()),
    ])
    .where_condition(|row| {              // Custom filtering
        if let Some(Value::Float(total)) = row.get("order.total") {
            *total > 100.0
        } else { false }
    })
    .order_by("order.total".to_string(), false)  // DESC ordering
    .limit(10)                            // Pagination
    .execute().await?;

result.print();  // Beautiful table output

Join Types & Performance

Join Type Use Case Performance Graph Advantage
INNER JOIN Matching records only ⚑ Very Fast Direct edge traversal
LEFT JOIN All left + matching right πŸš€ Fast NULL handling optimized
CROSS JOIN All combinations ⚠️ Use with LIMIT Efficient iteration
AGGREGATE GROUP BY operations πŸš€ Fast Native graph grouping

Graph vs SQL Join Advantages

// Traditional SQL approach (slow)
SELECT u.name, o.total
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE o.total > 100;

// Mini Database approach (fast)
client.join("user", "order")
    .on_edge("places_order")              // Direct graph relationship
    .where_condition(|row| total > 100.0) // Rust closure filtering
    .execute().await?;

Why Graph Joins are Superior:

  • πŸ”— Direct relationship traversal (no expensive hash joins)
  • ⚑ Sub-microsecond edge walking vs millisecond SQL joins
  • 🎯 Type-safe filtering with Rust closures
  • πŸ“ˆ Linear scaling with relationship count

πŸ“¦ Installation

Add to your Cargo.toml:

[dependencies]
mini-database = { git = "https://github.com/AarambhDevHub/mini-database.git" }
tokio = { version = "1.0", features = ["full"] }

πŸš€ Quick Start

Embedded Mode (Single Process)

use mini_database::{Database, DatabaseClient, DatabaseConfig, Node, Edge, Value};
use mini_database::{JoinType, AggregateFunction}; // Import join types

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create database
    let config = DatabaseConfig::new("./data")
        .with_cache_size(128) // 128MB cache
        .with_compression(true);

    let database = Database::new(config).await?;
    let client = DatabaseClient::new(database);

    // Create nodes
    let alice = Node::new("person")
        .with_property("name", Value::String("Alice".to_string()))
        .with_property("age", Value::Integer(30));

    let bob = Node::new("person")
        .with_property("name", Value::String("Bob".to_string()))
        .with_property("age", Value::Integer(25));

    let alice_id = client.create_node(alice).await?;
    let bob_id = client.create_node(bob).await?;

    // Create relationship
    let friendship = Edge::new(&alice_id, &bob_id, "friends")
        .with_property("since", Value::String("2020".to_string()));

    client.create_edge(friendship).await?;

    // Query with fluent API
    let people = client.execute_query(
        client.query_nodes()
            .with_label("person")
            .where_gt("age", Value::Integer(25))
            .limit(10)
    ).await?;

    // ✨ NEW: SQL-like JOIN operations
    let join_result = client.join("person", "person")
        .join_type(JoinType::Inner)
        .on_edge("friends".to_string())
        .select(vec![
            ("person".to_string(), "name".to_string()),
        ])
        .execute().await?;

    join_result.print(); // Beautiful table output

    // Graph traversal
    let connections = client.bfs(&alice_id, 3).await?;
    println!("Found {} connected nodes", connections.len());

    Ok(())
}

Network Mode (Client-Server)

Start the Database Server:

cargo run --example database_server

Connect from Client:

use mini_database::{NetworkDatabaseClient, Node, Value};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Connect to server
    let mut client = NetworkDatabaseClient::connect("127.0.0.1", 5432).await?;

    // Create node over network
    let node = Node::new("user")
        .with_property("email", Value::String("user@example.com".to_string()));

    let node_id = client.create_node(node).await?;

    // Retrieve node
    let retrieved = client.get_node(&node_id).await?;
    println!("Retrieved: {:?}", retrieved);

    // Graph traversal over network
    let neighbors = client.bfs(&node_id, 2).await?;

    Ok(())
}

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          CLIENT MODE            β”‚    β”‚          SERVER MODE            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                 β”‚    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚    β”‚  β”‚     Network Clients         β”‚ β”‚
β”‚  β”‚     Application Code        β”‚ β”‚    β”‚  β”‚   (TCP Connections)         β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚    DatabaseClient API       β”‚ β”‚    β”‚  β”‚    Connection Pool          β”‚ β”‚
β”‚  β”‚     + Join Operations       β”‚ β”‚    β”‚  β”‚   + Request Handler         β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                 β”‚    β”‚                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                β”‚                                        β”‚
                β–Ό                                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           DATABASE ENGINE                                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚
β”‚  β”‚  Query Builder  β”‚  β”‚ Graph Operations β”‚  β”‚ Query Executor  β”‚               β”‚
β”‚  β”‚   - Fluent API  β”‚  β”‚   - BFS/DFS     β”‚  β”‚  - Optimization β”‚               β”‚
β”‚  β”‚   - Conditions  β”‚  β”‚ - Shortest Path β”‚  β”‚   - Execution   β”‚               β”‚
β”‚  β”‚   - JOIN Ops ✨ β”‚  β”‚ - Join Traversalβ”‚  β”‚   - Join Engine β”‚               β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚
β”‚  β”‚   Node Store    β”‚  β”‚   Edge Store    β”‚  β”‚   Index Store   β”‚               β”‚
β”‚  β”‚  - Serializationβ”‚  β”‚ - Adjacency Listβ”‚  β”‚   - B-tree      β”‚               β”‚
β”‚  β”‚   - Properties  β”‚  β”‚  - Relationshipsβ”‚  β”‚   - Fast Lookup β”‚               β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚
β”‚  β”‚  LRU Cache      β”‚  β”‚  File Reader    β”‚  β”‚  Compression    β”‚               β”‚
β”‚  β”‚ - Hot Data      β”‚  β”‚ - Memory Map    β”‚  β”‚    - LZ4        β”‚               β”‚
β”‚  β”‚ - 100% Hit Rate β”‚  β”‚ - Async I/O     β”‚  β”‚ - Space Saving  β”‚               β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎯 Performance Benchmarks

Local Mode Performance

Operation          β”‚    Count β”‚ Duration β”‚    Ops/Sec β”‚  Latency
─────────────────────────────────────────────────────────────────
Node Creation      β”‚   10,000 β”‚   512ms  β”‚    19,503  β”‚   51ΞΌs
Node Retrieval     β”‚   10,000 β”‚    72ms  β”‚   138,794  β”‚    7ΞΌs
Node Updates       β”‚    5,000 β”‚   341ms  β”‚    14,635  β”‚   68ΞΌs
Edge Creation      β”‚    1,000 β”‚    58ms  β”‚    16,965  β”‚   59ΞΌs
Graph Traversal    β”‚       10 β”‚     2ms  β”‚     4,958  β”‚  202ΞΌs
Batch Operations   β”‚      100 β”‚     3ms  β”‚    26,033  β”‚   38ΞΌs

✨ Join Operations Performance NEW

Join Operation     β”‚    Count β”‚ Duration β”‚    Ops/Sec β”‚  Latency
─────────────────────────────────────────────────────────────────
INNER JOIN         β”‚    1,000 β”‚    45ms  β”‚    22,222  β”‚   45ΞΌs
LEFT JOIN          β”‚    1,000 β”‚    52ms  β”‚    19,230  β”‚   52ΞΌs
CROSS JOIN         β”‚      100 β”‚    15ms  β”‚     6,666  β”‚  150ΞΌs
Aggregate SUM      β”‚      500 β”‚    28ms  β”‚    17,857  β”‚   56ΞΌs
Complex Filter     β”‚      750 β”‚    35ms  β”‚    21,428  β”‚   47ΞΌs

Network Mode Performance

Operation          β”‚    Count β”‚ Duration β”‚    Ops/Sec β”‚  Latency
─────────────────────────────────────────────────────────────────
Node Creation      β”‚    5,000 β”‚   631ms  β”‚     7,917  β”‚  126ΞΌs
Node Retrieval     β”‚    5,000 β”‚   328ms  β”‚    15,234  β”‚   66ΞΌs
Graph Traversal    β”‚        5 β”‚     1ms  β”‚    10,743  β”‚   93ΞΌs
Network Latency    β”‚      100 β”‚     3ms  β”‚    25,354  β”‚   39ΞΌs

Overall Throughput: 10,492 ops/sec

Comparison with Production Databases

Database Throughput Use Case Mini Database
Redis 200K ops/sec In-memory cache βœ… 138K retrieval
MongoDB 50K ops/sec Document store βœ… 19K creation
PostgreSQL 10K ops/sec Relational DB βœ… 10K network
Neo4j 5K ops/sec Graph database βœ… 5K traversal
Joins 2-5K ops/sec SQL JOINs βœ… 22K joins

πŸ“š API Documentation

Node Operations

// Create node with properties
let node = Node::new("label")
    .with_property("key", Value::String("value".to_string()))
    .with_property("count", Value::Integer(42));

let node_id = client.create_node(node).await?;

// Retrieve node
let node = client.get_node(&node_id).await?;

// Update node
if let Some(mut node) = client.get_node(&node_id).await? {
    node.set_property("updated", Value::Boolean(true));
    client.update_node(&node).await?;
}

// Delete node
client.delete_node(&node_id).await?;

// Find nodes by criteria
let nodes = client.find_nodes_by_label("person").await?;
let nodes = client.find_nodes_by_property("age", &Value::Integer(25)).await?;

Edge Operations

// Create edge
let edge = Edge::new(&source_id, &target_id, "relationship_type")
    .with_property("weight", Value::Float(0.8))
    .with_property("created_at", Value::String("2023-01-01".to_string()));

let edge_id = client.create_edge(edge).await?;

// Get node connections
let all_edges = client.get_node_edges(&node_id).await?;
let outgoing = client.get_outgoing_edges(&node_id).await?;
let incoming = client.get_incoming_edges(&node_id).await?;

✨ Join Operations NEW

use mini_database::{JoinType, AggregateFunction};

// INNER JOIN with edge relationships
let inner_result = client.join("user", "order")
    .join_type(JoinType::Inner)
    .on_edge("places_order".to_string())
    .select(vec![
        ("user".to_string(), "name".to_string()),
        ("order".to_string(), "total".to_string()),
    ])
    .execute().await?;

// LEFT JOIN with property matching
let left_result = client.join("user", "profile")
    .join_type(JoinType::Left)
    .on_property("id".to_string(), "user_id".to_string())
    .select(vec![
        ("user".to_string(), "name".to_string()),
        ("profile".to_string(), "bio".to_string()),
    ])
    .execute().await?;

// Complex JOIN with filtering and ordering
let complex_result = client.join("user", "order")
    .join_type(JoinType::Inner)
    .on_edge("places_order".to_string())
    .select(vec![
        ("user".to_string(), "name".to_string()),
        ("user".to_string(), "city".to_string()),
        ("order".to_string(), "total".to_string()),
    ])
    .where_condition(|row| {
        // Filter high-value orders
        if let Some(Value::Float(total)) = row.get("order.total") {
            *total > 100.0
        } else { false }
    })
    .where_condition(|row| {
        // Filter specific cities
        if let Some(Value::String(city)) = row.get("user.city") {
            city == "New York" || city == "San Francisco"
        } else { false }
    })
    .order_by("order.total".to_string(), false) // DESC
    .limit(20)
    .execute().await?;

complex_result.print(); // Beautiful table output

// Aggregate operations
let user_totals = client.aggregate_join(
    "user",
    "order",
    "places_order",
    "name",        // Group by user name
    "total",       // Sum order totals
    AggregateFunction::Sum,
).await?;

for (user, total_spent) in user_totals {
    println!("{}: ${:.2}", user, total_spent);
}

Graph Traversal

// Breadth-first search
let connected = client.bfs(&start_node_id, 3).await?;

// Depth-first search
let connected = client.dfs(&start_node_id, 3).await?;

// Shortest path
if let Some(path) = client.shortest_path(&start_id, &end_id).await? {
    println!("Path length: {}", path.len());
}

// Get neighbors within distance
let neighbors = client.get_neighbors(&node_id, 2).await?;

Query Builder

// Complex node queries
let results = client.execute_query(
    client.query_nodes()
        .with_label("person")
        .where_eq("department", Value::String("engineering".to_string()))
        .where_gt("salary", Value::Integer(100000))
        .where_contains("skills", "rust")
        .order_by_desc("salary")
        .limit(20)
        .offset(0)
).await?;

// Edge queries
let relationships = client.execute_query(
    client.query_edges()
        .with_label("friendship")
        .where_gt("strength", Value::Float(0.7))
        .order_by_asc("created_at")
).await?;

πŸ› οΈ Examples

Run Examples

# Local embedded usage
cargo run --example basic_usage
cargo run --example graph_example

# ✨ NEW: Join operation examples
cargo run --example comprehensive_joins
cargo run --example join_queries

# Network client-server mode
cargo run --example database_server    # Terminal 1
cargo run --example database_client    # Terminal 2

# Multi-database examples
cargo run --example two_databases
cargo run --example database_federation

# Performance benchmarks
cargo run --example benchmark_local --release
cargo run --example benchmark_network --release
cargo run --example benchmark_comparison --release

Project Structure

mini-database/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ lib.rs                 # Main library entry
β”‚   β”œβ”€β”€ core/                  # Database engine
β”‚   β”‚   β”œβ”€β”€ database.rs        # Main database instance
β”‚   β”‚   └── config.rs          # Configuration management
β”‚   β”œβ”€β”€ storage/               # Storage layer
β”‚   β”‚   β”œβ”€β”€ file_reader.rs     # Memory-mapped I/O
β”‚   β”‚   β”œβ”€β”€ node_store.rs      # Node persistence
β”‚   β”‚   β”œβ”€β”€ edge_store.rs      # Edge & adjacency lists
β”‚   β”‚   β”œβ”€β”€ index.rs           # B-tree indexing
β”‚   β”‚   └── cache.rs           # LRU caching
β”‚   β”œβ”€β”€ query/                 # Query processing
β”‚   β”‚   β”œβ”€β”€ builder.rs         # Fluent query API
β”‚   β”‚   β”œβ”€β”€ executor.rs        # Query execution
β”‚   β”‚   └── graph_ops.rs       # Graph algorithms
β”‚   β”œβ”€β”€ client/                # Client interfaces
β”‚   β”‚   β”œβ”€β”€ database_client.rs # Local client
β”‚   β”‚   β”œβ”€β”€ network_client.rs  # Network client
β”‚   β”‚   β”œβ”€β”€ join.rs           # ✨ Join operations
β”‚   β”‚   └── result.rs          # Query results
β”‚   β”œβ”€β”€ server/                # Network server
β”‚   β”‚   β”œβ”€β”€ server.rs          # TCP server
β”‚   β”‚   β”œβ”€β”€ handler.rs         # Request handling
β”‚   β”‚   β”œβ”€β”€ protocol.rs        # Binary protocol
β”‚   β”‚   └── connection_pool.rs # Connection management
β”‚   β”œβ”€β”€ types/                 # Data structures
β”‚   β”‚   β”œβ”€β”€ node.rs            # Node definition
β”‚   β”‚   β”œβ”€β”€ edge.rs            # Edge definition
β”‚   β”‚   └── value.rs           # Property values
β”‚   └── utils/                 # Utilities
β”‚       β”œβ”€β”€ error.rs           # Error handling
β”‚       └── serde.rs           # Serialization
β”œβ”€β”€ examples/                  # Usage examples
β”‚   β”œβ”€β”€ basic_usage.rs         # Basic operations
β”‚   β”œβ”€β”€ graph_example.rs       # Graph algorithms
β”‚   β”œβ”€β”€ database_server.rs     # Server startup
β”‚   β”œβ”€β”€ database_client.rs     # Network client
β”‚   β”œβ”€β”€ join_queries.rs        # ✨ Join examples
β”‚   β”œβ”€β”€ two_databases.rs       # Multi-database
β”‚   └── benchmark_*.rs         # Performance tests
└── Cargo.toml                 # Dependencies

βš™οΈ Configuration

Database Configuration

let config = DatabaseConfig::new("./data")
    .with_cache_size(256)        // 256MB cache
    .with_compression(true)      // Enable LZ4 compression
    .with_sync_writes(false)     // Async writes for performance
    .with_index_page_size(4096); // 4KB index pages

Server Configuration

let server_config = ServerConfig {
    host: "127.0.0.1".to_string(),
    port: 5432,
    max_connections: 100,        // Connection pool limit
    buffer_size: 8192,           // 8KB network buffer
    cleanup_interval: Duration::from_secs(60), // Connection cleanup
};

πŸ”¬ Use Cases

When to Use Local Mode

  • βœ… Single-process applications (desktop, mobile, embedded)
  • βœ… Ultra-low latency requirements (<10ΞΌs)
  • βœ… High-frequency operations (>50K ops/sec)
  • βœ… Offline-first applications

When to Use Network Mode

  • βœ… Multi-client applications (web services, APIs)
  • βœ… Microservices architecture
  • βœ… Language-agnostic access (Python, JavaScript clients)
  • βœ… Distributed deployments

✨ When to Use Join Operations NEW

  • βœ… Complex relationship queries (user orders, social networks)
  • βœ… Analytics and reporting (aggregations, grouping)
  • βœ… Multi-table operations (traditional RDBMS migration)
  • βœ… Real-time dashboards (fast aggregation queries)

πŸ“Š Optimization Tips

Performance Tuning

// Optimize for read-heavy workloads
let config = DatabaseConfig::new("./data")
    .with_cache_size(512)        // Larger cache
    .with_compression(false);    // Skip compression for speed

// Optimize for write-heavy workloads
let config = DatabaseConfig::new("./data")
    .with_cache_size(128)        // Smaller cache
    .with_compression(true)      // Save disk space
    .with_sync_writes(false);    // Async writes

Query Optimization

// Use specific queries for better performance
let nodes = client.find_nodes_by_label("person").await?;  // Fast label index
let nodes = client.find_nodes_by_property("age", &Value::Integer(25)).await?; // Property lookup

// Limit results to reduce memory usage
let results = client.execute_query(
    client.query_nodes()
        .with_label("user")
        .limit(1000)            // Limit results
        .offset(page * 1000)    // Pagination
).await?;

✨ Join Optimization NEW

// Use edge-based joins for better performance (faster than property joins)
let fast_join = client.join("user", "order")
    .on_edge("places_order")    // Direct edge traversal
    .execute().await?;

// Apply filters early to reduce intermediate results
let optimized = client.join("user", "order")
    .on_edge("places_order")
    .where_condition(|row| /* filter early */)  // Before sorting
    .order_by("order.total", false)
    .limit(100)                 // Limit final results
    .execute().await?;

πŸ§ͺ Testing

# Run all tests
cargo test

# Run with optimizations
cargo test --release

# Test specific module
cargo test storage::tests

# ✨ Test join operations
cargo test client::join::tests

# Test with logging
RUST_LOG=debug cargo test

πŸš€ Roadmap

We are building Mini Database step-by-step to become a full-featured, production-quality graph database. Here is the planned progression:

Phase 1: Core Stability (Completed / In Progress)

  • Write-Ahead Logging (WAL) for crash recovery
  • ACID Transactions with commit/rollback
  • Custom Query Language parser and execution
  • Basic query optimization

Phase 2: Production Features (Upcoming)

  • Authentication and Role-Based Authorization
  • Security layer integrated into network server
  • Metrics collection using Prometheus support
  • Monitoring HTTP endpoint for real-time stats
  • (Optional) Admin dashboard with query console and metrics

Phase 3: Scalability & Distribution (Mid Term)

  • Cluster management with Raft consensus for high availability
  • Data sharding and replication across nodes
  • Inter-node communication and cluster network protocol
  • Distributed query execution and result aggregation
  • Graph algorithms library (PageRank, Community detection, etc.)
  • Temporal graph support with snapshotting and versioning

Phase 4: Ecosystem & Adoption (Long Term)

  • Multi-language drivers: Rust, Python, JavaScript, and more
  • ORM/ODM support with trait and macros
  • GraphQL API server integration for flexible querying
  • Connectors for Apache Kafka and Apache Spark for streaming and analytics
  • Comprehensive documentation, examples, tutorials
  • CI/CD pipelines, community engagement, and open source growth

Your contributions and feedback welcome! Help us build the future of graph databases in Rust.


🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

git clone https://github.com/AarambhDevHub/mini-database.git
cd mini-database
cargo build
cargo test
cargo run --example basic_usage

# ✨ Test join functionality
cargo run --example comprehensive_joins

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


β˜• Support & Community

If you find Ignitia helpful, consider supporting the project:

Buy Me A Coffee


πŸ™ Acknowledgments

  • Tokio - Asynchronous runtime
  • Serde - Serialization framework
  • LZ4 - High-speed compression
  • DashMap - Concurrent hash maps
  • Rust Community - Amazing ecosystem

πŸ“ž Support


Made with ❀️ and πŸ¦€ Rust ❀️ by Aarambh Dev Hub


Mini Database - Where graph performance meets SQL familiarity

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

  •  

Packages

No packages published

Languages