| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- ==================================================================
- TsDB2 ORM 全量特性验证
- 主键表(_id) / Hash 二级 / B+ 二级 / 时序表(_ts)
- ==================================================================
- ==================================================================
- 【0. 建表与索引清单 (索引类型由 vrtx tag 自动决定)】
- employee.pk_employee IndexType=2 EntryPage=0
- employee.idx_age IndexType=6 EntryPage=0
- employee.idx_score IndexType=5 EntryPage=0
- metric.pk_metric IndexType=1 EntryPage=0
- [OK] Age 字段使用 Hash 索引 (IndexType=6)
- [OK] Score 字段使用 B+ 树索引 (IndexType=5)
- [OK] 主键 _id 使用 Primary 索引 (IndexType=2)
- [OK] 时序主键 _ts 使用 Time 索引 (IndexType=1)
- ==================================================================
- 【1. 主键表 CRUD (Employee: _id + Hash(Age) + B+(Score))】
- [OK] Insert 20000 行 (0.98s, 20410 行/s), Count=20000
- [OK] 主键 Find(12345) 命中且字段正确
- [OK] Hash 等值查询 Age=25 → 10000 行 (期望 10000), 均摊 43.384183ms
- [OK] Hash 范围查询 Age∈[60,70] → 2000 行 (期望 2000), 均摊 18.16533ms (全桶扫描)
- [OK] B+ 范围查询 Score∈[200,299] → 2000 行, 有序=true, 均摊 21.993054ms
- → 延迟对比: Hash 等值 43.384183ms | Hash 范围 18.16533ms | B+ 范围 21.993054ms
- [OK] OrderBy(Score desc).Limit(5) 返回 5 行且分数降序
- [OK] Offset(10).Limit(5) 分页返回 5 行
- [OK] Where(Dept=D1).Count()=4000 (期望 4000, 全表扫描无索引)
- [OK] First() 返回单条
- [OK] Scan 流式遍历 Limit(100) → 100 行
- [OK] FindAll() → 20000 行
- [INFO] Update 只传 Score 后: Name="" Age=0 Score=777 Dept="" (改前 Name="Emp001001")
- [OK] Update 为整行覆盖语义 (未赋值字段被清零)
- [OK] 改 Age(25→123) 100 行后: Age=25 → 9900 (期望 9900), Age=123 → 100 (期望 100)
- [OK] 改 Score(1→5000): 旧值计数=18, 新值计数=1
- [OK] Delete 200 行: Count 20000→19800 (失败 0), Find(1)/(200) 失败, Find(201) 成功
- [OK] 删除后 Hash 索引级联清理: Age=123 → 0 (期望 0); B+ 索引级联清理: Score=5000 → 0 (期望 0)
- ==================================================================
- 【2. 时序表 CRUD (Metric: _ts + 时序索引)】
- [OK] 顺序写入 20000 个时间点 (0.31s, 64148 点/s), Count=20000
- [OK] 时序主键 Find(ts) 精确命中
- [OK] 时间范围 [_ts∈3.0s~3.999s] → 1000 行 (期望 1000), 有序=true, 在界内=true, 均摊 1.042896ms
- [OK] OrderBy(_ts desc).Limit(10) 取到最新 10 个点且降序
- [OK] Where(Host=h2).Count()=5000 (期望 5000, 无索引全扫描)
- [OK] 时序行 Update → Find 校验 Value=9999
- [OK] 时序行 Delete(ts) 后: Find 失败, Count=19999 (期望 19999)
- ==================================================================
- 【3. 时序写入的两个关键特征 (乱序 / 缺省时间戳)】
- [OK] LateMetric 顺序写入 1000 点, Count=1000
- [INFO] 乱序补写 3 个中间时间点: 插入错误=0, 主键 Find 命中=3/3, 时间范围扫描回读=1003 行 (期望 1003)
- [OK] 乱序补写的点可被主键 Find 命中
- [OK] 时间范围扫描包含乱序补写的点 (1003 行)
- [INFO] 不设置 _ts 插入后, 结构体回写得到的 TS=1004
- [OK] 缺省 _ts 时由 ORM 自动分配 (非真实时间戳, 等于行序号)
- ==================================================================
- 【4. 事务 (ORM 增删改 + 提交/回滚)】
- [OK] 事务内插入 10 行并提交 → Where(Dept=TX)=10
- [OK] 事务内插入后回滚 → Where(Dept=RB)=0 (期望 0)
- ==================================================================
- 【5. 关闭重开 (持久化验证)】
- [OK] 重开后 employee Count 19810 → 19810
- [OK] 重开后 metric Count 19999 → 19999
- [OK] 重开后主键 Find(201) 命中
- [OK] 重开后时序 Find(ts) 命中
- [OK] 重开后 Hash 索引可用: Age=25 → 9900
- [OK] 重开后 B+ 索引可用: Score∈[300,399] → 2010 行
- 数据库文件: 6.61 MB
- ==================================================================
- 【6. 四种索引形态特性对比】
- 主键 _id
- IndexType = 2 Primary
- 底层结构 = B+ 树
- 叶子/条目 = 叶子直接存行数据(DataPage)
- 查询复杂度 = 等值/范围 O(logN), 天然按 pk 有序
- ORM 声明 = 内嵌 DB.BaseModel
- Hash 二级
- IndexType = 6 Hash
- 底层结构 = 桶目录 + 溢出链
- 叶子/条目 = 叶子存 pkID, 需回主键取行
- 查询复杂度 = 等值 O(1); 范围=全桶扫描 O(N)
- ORM 声明 = vrtx:"index:x,type:hash"
- B+ 二级
- IndexType = 5 BTree
- 底层结构 = B+ 树
- 叶子/条目 = 叶子存 pkID, 需回主键取行
- 查询复杂度 = 等值/范围/有序 均 O(logN)
- ORM 声明 = vrtx:"index:x" (默认)
- 时序 _ts
- IndexType = 1 Time
- 底层结构 = 扁平时间条目链
- 叶子/条目 = [Begin,Last,DataPageID] → 分段 DataPage
- 查询复杂度 = 时间范围只加载命中分段; 等值需扫段内行
- ORM 声明 = 内嵌 DB.TimeSeriesModel
- ==================================================================
- 总计: 通过 39, 失败 0
- ==================================================================
|