Skip to content

Instantly share code, notes, and snippets.

@mgttt
Created March 2, 2026 16:17
Show Gist options
  • Select an option

  • Save mgttt/b144f81b67faafc7a296e2c42c2c254f to your computer and use it in GitHub Desktop.

Select an option

Save mgttt/b144f81b67faafc7a296e2c42c2c254f to your computer and use it in GitHub Desktop.
.ndtb Data Format Complete Technical Specification

.NDTB 数据格式 — 完整技术规范

一、文件格式架构

1.1 文件头部结构

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 (块完整性校验)

2.2 列存储编码

列类型 编码方式 优化
u32/u64 Delta + Varint 时间戳按递增存储,差值编码
f64 Gorilla 时间序列 浮点数只存储有效变化位
String Dict + 索引 字典压缩,符号复用
Boolean 位打包 每字节存8个值
Nullable 位掩码 前置NULL bitmap

2.3 块分层索引

Level 1 (Block Index):  每块的 min/max/rowOffset
Level 2 (Page Index):   每100块的统计信息
Level 3 (Segment):      物理文件段位置

三、动态 Schema 支持

3.1 Schema 版本管理

{
  "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 }
  ]
}

3.2 向后兼容性

  • 新增列: 对旧数据自动填充 NULL
  • 删除列: 标记为 deprecated,保留 ID 不复用
  • 类型变更: 版本号+转换函数记录
  • 列重排: ID 不变,读取时按 ID 映射

3.3 运行时 Schema 演变

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);

四、压缩策略

4.1 多层压缩

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)

4.2 自适应压缩

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);

4.3 流式压缩

// 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);

五、C API 核心函数

5.1 数据库操作

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);

5.2 写入操作

// 批量写入
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);

5.3 索引和统计

// 索引管理
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);

5.4 迭代器

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);

六、事务和并发

6.1 MVCC 模型

// 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);

6.2 并发控制

// 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

七、内存映射和缓存

7.1 内存映射

// mmap 支持 (可选)
typedef struct {
  bool enableMmap;
  size_t mmapThreshold;  // > N bytes 使用 mmap
  bool prefault;         // 预故障加载
} NDTBMmapConfig;

int ndtb_set_mmap_config(NDTB *db, const NDTBMmapConfig *cfg);

7.2 LRU 块缓存

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);

八、错误处理和诊断

8.1 错误代码

#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);

8.2 日志和性能追踪

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

九、兼容性和升级

9.1 版本迁移

typedef struct {
  uint32_t fromVersion;
  uint32_t toVersion;
  int (*migrate)(const char *path);
} NDTBMigration;

int ndtb_migrate(const char *path, uint32_t targetVersion);

9.2 向前兼容性

  • 新版本的库能读旧格式,自动升级 schema
  • 旧版本库读新格式时返回 NDTB_ERR_VERSION

十、性能特性

10.1 目标性能指标

操作 目标 备注
点查询 (indexed) < 100 μs 内存缓存命中
范围查询 (100K rows) < 10 ms block skip
批量写入 (1M rows) 10-50M rows/sec 取决于压缩
全表扫描 ~100K rows/ms block sequential
压缩比 5-20x 时序数据

10.2 优化技巧

  • SIMD: 批量比较、sum、avg 使用 AVX-512
  • 并行解压: 多线程 block 解压
  • 预加载: 范围查询预读后续块
  • 列剪裁: 只读需要的列

十一、安全特性

11.1 数据完整性

// CRC32 每块验证
// Optional: SHA-256 for entire file
// Optional: 签名支持 (ed25519)

typedef struct {
  bool enableCRC;
  bool enableSHA256;
  const char *signKey;  // 可选签名密钥
} NDTBSecurityConfig;

11.2 访问控制

// 基于角色的权限 (可选)
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);

十二、扩展点和未来

12.1 插件系统

// 自定义编解码器
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);

12.2 内置支持的特性

  • JSON 类型列 (子查询)
  • 地理坐标列 (R-Tree 索引)
  • 向量列 (ANN 搜索)
  • 时间序列特殊函数 (窗口函数、lag/lead)

总结

.ndtb 是一个现代化的列式时序数据库格式,结合了: ✅ 灵活的动态 Schema — 支持演变和向后兼容 ✅ 强大的压缩 — 多层编码 + 自适应算法 ✅ 高性能 C API — 零拷贝、MVCC、并发读写 ✅ 生产级可靠性 — CRC 校验、事务、错误恢复 ✅ 可扩展性 — 插件系统、自定义编解码


建议后续开发

  1. 参考 Apache ORC / Parquet 实现细节
  2. 集成 Zstandard 作为默认压缩
  3. 实现智能块大小自适应 (根据内存和 CPU)
  4. 支持远程查询 (S3、HTTP)
  5. 异步 I/O 优化
  6. Go/Rust 语言绑定
  7. Web UI 数据探索工具
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment