Magic: "NDTB" (4 bytes, ASCII)
Version: uint32_le (当前: 0x01000000)
Flags: uint32_le (压缩、加密、索引等标志位)
Header Length: uint32_le (自此字段开始,到Schema JSON结束的字节数)
Created: uint64_le (Unix timestamp, ms)
Modified: uint64_le (Unix timestamp, ms)
Reserved: 128 bytes (future extensions)
1.2 模式部分 (Schema Section)
Schema Length: uint32_le
Schema JSON: {
"version": "2.0",
"columns": [
{ "id": 0, "name": "symbol_id", "type": "u32", "nullable": false },
{ "id": 1, "name": "timestamp", "type": "u64", "nullable": false },
{ "id": 2, "name": "price", "type": "f64", "nullable": false },
{ "id": 3, "name": "volume", "type": "f64", "nullable": true }
],
"compression": "gorilla|zstd|lz4",
"blockSize": 8192,
"rowCount": 1000000
}
Schema CRC32: uint32_le
1.3 索引部分 (Index Section) — 可选
Index Type: uint8 (0=none, 1=sparse, 2=full)
Index Entries: {
"timestamp": {
"min": 1704067200000,
"max": 1704153600000,
"rowOffsets": [0, 10000, 20000, ...]
},
"symbol_id": {
"unique": ["BTC", "ETH", "SOL"],
"offsets": { "BTC": 0, "ETH": 50000, "SOL": 100000 }
}
}
Index CRC32: uint32_le
2.1 块结构 (Column-Oriented)
Block Header:
- Block Type: uint8 (0=raw, 1=delta, 2=gorilla, 3=dict)
- Compression: uint8
- Row Count: uint32_le
- Uncompressed Size: uint32_le
- Compressed Size: uint32_le
Data: Compressed column data
CRC32: uint32_le (块完整性校验)
列类型
编码方式
优化
u32/u64
Delta + Varint
时间戳按递增存储,差值编码
f64
Gorilla 时间序列
浮点数只存储有效变化位
String
Dict + 索引
字典压缩,符号复用
Boolean
位打包
每字节存8个值
Nullable
位掩码
前置NULL bitmap
Level 1 (Block Index): 每块的 min/max/rowOffset
Level 2 (Page Index): 每100块的统计信息
Level 3 (Segment): 物理文件段位置
{
"schemaVersion" : 2 ,
"schemaHistory" : [
{ "version" : 1 , "timestamp" : 1704067200000 , "changes" : " initial" },
{ "version" : 2 , "timestamp" : 1704153600000 , "changes" : " added_vwap_column" }
],
"columns" : [
{ "id" : 0 , "name" : " symbol_id" , "type" : " u32" , "addedIn" : 1 , "deprecated" : false },
{ "id" : 4 , "name" : " vwap" , "type" : " f64" , "addedIn" : 2 , "deprecated" : false }
]
}
新增列: 对旧数据自动填充 NULL
删除列: 标记为 deprecated,保留 ID 不复用
类型变更: 版本号+转换函数记录
列重排: ID 不变,读取时按 ID 映射
typedef struct {
uint32_t schemaVersion ;
uint32_t activeColumnCount ;
NDTBColumn * columns ;
NDTBSchemaChange * changes ; // 增量变更链表
} NDTBSchema ;
// API
int ndtb_add_column (NDTB * db , const NDTBColumn * col );
int ndtb_deprecate_column (NDTB * db , uint32_t colId );
NDTBSchema * ndtb_get_schema_at_version (NDTB * db , uint32_t ver );
Level 1 - 列级编码(无损):
- Delta for monotonic (timestamp)
- Gorilla for time-series floats
- Dictionary for categories (symbol)
- Varint for small integers
Level 2 - 块级压缩(可选):
- Zstandard (2-10 倍压缩,快速)
- LZ4 (实时流)
- DEFLATE (最大压缩)
Level 3 - 段级 (Segment-level):
- 可选后处理压缩
- 支持加密 (AES-256-GCM)
typedef struct {
double entropy ; // Shannon entropy
uint32_t distinctCount ; // 唯一值数量
char * recommendedMethod ; // "dict", "delta", "gorilla", "raw"
} NDTBCompressionHint ;
NDTBCompressionHint ndtb_analyze_column (const void * data , uint32_t rows );
// Streaming Compressor
typedef struct {
size_t bufSize ;
uint8_t * buffer ;
size_t pos ;
void * compCtx ; // ZSTD/LZ4 context
} NDTBCompressor ;
NDTBCompressor * ndtb_compressor_new (const char * method , int level );
int ndtb_compress_append (NDTBCompressor * c , const void * data , size_t len );
int ndtb_compress_flush (NDTBCompressor * c , uint8_t * * out , size_t * outLen );
typedef struct NDTB NDTB ;
// 打开/创建
NDTB * ndtb_open (const char * path , int flags );
NDTB * ndtb_create (const char * path , const NDTBSchema * schema );
int ndtb_close (NDTB * db );
int ndtb_sync (NDTB * db ); // 持久化到磁盘
// 查询
int ndtb_query (NDTB * db , const char * sqlFilter , NDTBResult * * out );
int ndtb_query_range (NDTB * db , uint32_t colId , void * min , void * max , NDTBResult * * out );
int ndtb_get_row (NDTB * db , uint64_t rowId , NDTBRow * * out );
// 批量写入
typedef struct {
uint32_t columnId ;
void * data ;
size_t count ;
uint8_t * nullBitmap ; // Optional, for nullable columns
} NDTBColumnData ;
int ndtb_insert_batch (NDTB * db , const NDTBColumnData * cols , uint32_t colCount );
// 流式 Append Writer
typedef struct NDTBAppender NDTBAppender ;
NDTBAppender * ndtb_appender_new (NDTB * db , size_t bufferSize );
int ndtb_append_row (NDTBAppender * app , const NDTBRow * row );
int ndtb_append_batch (NDTBAppender * app , const NDTBColumnData * cols );
int ndtb_appender_flush (NDTBAppender * app );
int ndtb_appender_free (NDTBAppender * app );
// 索引管理
int ndtb_create_index (NDTB * db , uint32_t colId , const char * indexType );
int ndtb_drop_index (NDTB * db , uint32_t colId );
// 统计信息
typedef struct {
uint64_t rowCount ;
uint32_t blockCount ;
double compressionRatio ;
uint64_t fileSize ;
NDTBColumnStats * colStats ; // Per-column min/max/nullCount
} NDTBStats ;
NDTBStats * ndtb_get_stats (NDTB * db );
void ndtb_free_stats (NDTBStats * stats );
typedef struct NDTBIter NDTBIter ;
NDTBIter * ndtb_iter_new (NDTB * db );
int ndtb_iter_next (NDTBIter * iter , NDTBRow * * out );
int ndtb_iter_seek (NDTBIter * iter , uint64_t rowId );
void ndtb_iter_free (NDTBIter * iter );
// Read Version
typedef struct {
uint32_t versionId ;
uint64_t snapshotTime ; // 版本创建时间戳
uint32_t readLevel ; // 读隔离级别
} NDTBReadVersion ;
NDTBReadVersion * ndtb_begin_read (NDTB * db , int isolationLevel );
int ndtb_commit_read (NDTBReadVersion * ver );
// Write Transaction
typedef struct {
uint32_t txnId ;
uint64_t startTime ;
void * writeLog ;
} NDTBWriteTxn ;
NDTBWriteTxn * ndtb_begin_write (NDTB * db );
int ndtb_commit_write (NDTBWriteTxn * txn );
int ndtb_rollback_write (NDTBWriteTxn * txn );
// Lock-free read + MVCC write
// - 读操作:获取版本 ID,无 lock
// - 写操作:write-ahead log + 原子 version bump
// - 冲突:optimistic + retry
int ndtb_set_isolation_level (NDTB * db , int level );
// NDTB_ISO_READ_UNCOMMITTED
// NDTB_ISO_READ_COMMITTED
// NDTB_ISO_REPEATABLE_READ
// NDTB_ISO_SERIALIZABLE
// mmap 支持 (可选)
typedef struct {
bool enableMmap ;
size_t mmapThreshold ; // > N bytes 使用 mmap
bool prefault ; // 预故障加载
} NDTBMmapConfig ;
int ndtb_set_mmap_config (NDTB * db , const NDTBMmapConfig * cfg );
typedef struct {
size_t cacheSize ; // 字节
uint32_t blockCount ; // 缓存块数
double hitRatio ; // 统计信息
} NDTBCacheConfig ;
int ndtb_set_cache_config (NDTB * db , const NDTBCacheConfig * cfg );
NDTBCacheStats * ndtb_get_cache_stats (NDTB * db );
#define NDTB_OK 0
#define NDTB_ERR_FILE -1
#define NDTB_ERR_CORRUPT -2
#define NDTB_ERR_SCHEMA -3
#define NDTB_ERR_OOM -4
#define NDTB_ERR_CRC -5
#define NDTB_ERR_ENCODING -6
#define NDTB_ERR_COMPRESSION -7
#define NDTB_ERR_TIMEOUT -8
const char * ndtb_strerror (int errCode );
typedef void (* NDTBLogFn )(int level , const char * msg );
typedef void (* NDTBMetricsFn )(const char * name , double value );
int ndtb_set_log_callback (NDTBLogFn fn );
int ndtb_set_metrics_callback (NDTBMetricsFn fn );
// 性能指标
// - query_latency_ms
// - compression_ratio
// - cache_hit_rate
// - block_read_count
typedef struct {
uint32_t fromVersion ;
uint32_t toVersion ;
int (* migrate )(const char * path );
} NDTBMigration ;
int ndtb_migrate (const char * path , uint32_t targetVersion );
新版本的库能读旧格式,自动升级 schema
旧版本库读新格式时返回 NDTB_ERR_VERSION
操作
目标
备注
点查询 (indexed)
< 100 μs
内存缓存命中
范围查询 (100K rows)
< 10 ms
block skip
批量写入 (1M rows)
10-50M rows/sec
取决于压缩
全表扫描
~100K rows/ms
block sequential
压缩比
5-20x
时序数据
SIMD : 批量比较、sum、avg 使用 AVX-512
并行解压 : 多线程 block 解压
预加载 : 范围查询预读后续块
列剪裁 : 只读需要的列
// CRC32 每块验证
// Optional: SHA-256 for entire file
// Optional: 签名支持 (ed25519)
typedef struct {
bool enableCRC ;
bool enableSHA256 ;
const char * signKey ; // 可选签名密钥
} NDTBSecurityConfig ;
// 基于角色的权限 (可选)
typedef struct {
char * user ;
char * role ;
uint32_t permissions ; // READ, WRITE, DELETE, ALTER
} NDTBUser ;
int ndtb_grant_permission (NDTB * db , const char * user , uint32_t perm );
// 自定义编解码器
typedef struct {
const char * name ;
int (* compress )(const void * in , size_t inLen , void * * out , size_t * outLen );
int (* decompress )(const void * in , size_t inLen , void * * out , size_t * outLen );
} NDTBCodec ;
int ndtb_register_codec (const NDTBCodec * codec );
JSON 类型列 (子查询)
地理坐标列 (R-Tree 索引)
向量列 (ANN 搜索)
时间序列特殊函数 (窗口函数、lag/lead)
.ndtb 是一个现代化的列式时序数据库格式,结合了:
✅ 灵活的动态 Schema — 支持演变和向后兼容
✅ 强大的压缩 — 多层编码 + 自适应算法
✅ 高性能 C API — 零拷贝、MVCC、并发读写
✅ 生产级可靠性 — CRC 校验、事务、错误恢复
✅ 可扩展性 — 插件系统、自定义编解码
参考 Apache ORC / Parquet 实现细节
集成 Zstandard 作为默认压缩
实现智能块大小自适应 (根据内存和 CPU)
支持远程查询 (S3、HTTP)
异步 I/O 优化
Go/Rust 语言绑定
Web UI 数据探索工具