功能:增强 Schema 系统和添加新示例

- 扩展 Schema 支持更多数据类型(Duration、URL、JSON 等)
- 优化 SSTable 编码解码性能
- 添加多个新示例程序:
  - all_types: 展示所有支持的数据类型
  - new_types: 演示新增类型的使用
  - struct_tags: 展示结构体标签功能
  - time_duration: 时间和持续时间处理示例
- 完善测试用例和文档
- 优化代码结构和错误处理
This commit is contained in:
2025-10-10 00:20:45 +08:00
parent 6d04487789
commit 77087d36c6
41 changed files with 3008 additions and 452 deletions

130
CLAUDE.md
View File

@@ -131,9 +131,9 @@ database_dir/
```go
schema := NewSchema("users", []Field{
{Name: "name", Type: FieldTypeString, Indexed: false, Comment: "用户名"},
{Name: "age", Type: FieldTypeInt64, Indexed: false, Comment: "年龄"},
{Name: "email", Type: FieldTypeString, Indexed: true, Comment: "邮箱(索引)"},
{Name: "name", Type: String, Indexed: false, Comment: "用户名"},
{Name: "age", Type: Int64, Indexed: false, Comment: "年龄"},
{Name: "email", Type: String, Indexed: true, Comment: "邮箱(索引)"},
})
table, _ := db.CreateTable("users", schema)
@@ -142,7 +142,112 @@ table, _ := db.CreateTable("users", schema)
- Schema `Insert()` 时强制验证类型和必填字段
- 索引字段`Indexed: true`自动创建二级索引
- Schema 持久化到 `table_dir/schema.json`包含校验和防篡改
- 支持的类型`FieldTypeString`, `FieldTypeInt64`, `FieldTypeBool`, `FieldTypeFloat`
- **支持的类型** (17 精确映射到 Go 基础类型):
- **有符号整数** (5种): `Int`, `Int8`, `Int16`, `Int32`, `Int64`
- **无符号整数** (5种): `Uint`, `Uint8`, `Uint16`, `Uint32`, `Uint64`
- **浮点数** (2种): `Float32`, `Float64`
- **字符串** (1种): `String`
- **布尔** (1种): `Bool`
- **特殊类型** (3种): `Byte` (独立类型底层=uint8), `Rune` (独立类型底层=int32), `Decimal` (高精度十进制使用 shopspring/decimal)
- **Nullable 支持**: 字段可标记为 `Nullable: true`允许 NULL
### 类型系统详解
**精确类型映射**:
v1.x 开始SRDB 采用精确类型映射策略每个 Go 基础类型都有对应的 FieldType这带来以下优势
1. **存储优化**: 使用 `uint8` (1 字节) 存储百分比而不是 `int64` (8 字节)
2. **语义明确**: `uint32` 表示设备ID`float32` 表示传感器读数
3. **类型安全**: 编译期和运行期双重类型检查
**类型转换规则**:
```go
// 1. 相同类型:直接接受
{Name: "age", Type: Int32}
Insert(map[string]any{"age": int32(25)}) // ✓
// 2. 兼容类型:自动转换(有符号 ↔ 无符号,需非负)
{Name: "count", Type: Int64}
Insert(map[string]any{"count": uint32(100)}) // ✓
// 3. 类型提升:整数 → 浮点
{Name: "ratio", Type: Float32}
Insert(map[string]any{"ratio": int32(42)}) // ✓ 转为 42.0
// 4. JSON 兼容float64 → 整数(需为整数值)
{Name: "id", Type: Int64}
Insert(map[string]any{"id": float64(123.0)}) // ✓ JSON 反序列化场景
// 5. 负数 → 无符号:拒绝
{Name: "index", Type: Uint32}
Insert(map[string]any{"index": int32(-1)}) // ✗ 错误
```
**最佳实践**:
```go
// 推荐:根据数据范围选择合适的类型
schema, _ := NewSchema("sensors", []Field{
{Name: "device_id", Type: Uint32}, // 0 ~ 42亿
{Name: "temperature", Type: Float32}, // 单精度足够
{Name: "humidity", Type: Uint8}, // 0-100
{Name: "status", Type: Bool}, // 布尔状态
})
// 避免:盲目使用 int64 和 float64
schema, _ := NewSchema("sensors_bad", []Field{
{Name: "device_id", Type: Int64}, // 浪费 4 字节
{Name: "temperature", Type: Float64}, // 浪费 4 字节
{Name: "humidity", Type: Int64}, // 浪费 7 字节!
{Name: "status", Type: Int64}, // 浪费 7 字节!
})
```
**新增类型的使用场景**:
```go
// Byte 类型 - 状态码、标志位
{Name: "status_code", Type: Byte, Comment: "HTTP 状态码 (0-255)"}
Insert(map[string]any{"status_code": uint8(200)}) // byte 和 uint8 底层相同
// Rune 类型 - 单个字符
{Name: "grade", Type: Rune, Comment: "等级 (S/A/B/C)"}
Insert(map[string]any{"grade": rune('A')}) // rune 和 int32 底层相同
// Decimal 类型 - 金融计算
{Name: "amount", Type: Decimal, Comment: "交易金额"}
import "github.com/shopspring/decimal"
Insert(map[string]any{"amount": decimal.NewFromFloat(123.456)})
// Nullable 支持 - 可选字段
{Name: "email", Type: String, Nullable: true, Comment: "邮箱(可选)"}
Insert(map[string]any{"email": nil}) // 允许 NULL
Insert(map[string]any{"email": "user@example.com"}) // 或有值
```
**从结构体自动生成 Schema**:
```go
type Sensor struct {
DeviceID uint32 `srdb:"device_id;indexed;comment:设备ID"`
Temperature float32 `srdb:"temperature;comment:温度"`
Humidity uint8 `srdb:"humidity;comment:湿度 0-100"`
Online bool `srdb:"online;comment:是否在线"`
}
// 自动映射:
// uint32 → Uint32
// float32 → Float32
// uint8 → Uint8 (也可用 byte)
// bool → Bool
fields, _ := StructToFields(Sensor{})
schema, _ := NewSchema("sensors", fields)
```
**参考示例**:
- `examples/all_types/` - 展示所有 17 种类型的基本使用
- `examples/new_types/` - 展示新增的 ByteRuneDecimal 类型和 Nullable 支持的实际应用场景
### Query Builder
@@ -292,12 +397,25 @@ Magic (4B) | Seq (8B) | Time (8B) | FieldCount (2B) |
- **Schema 是强制的**: 所有表必须定义 Schema不再支持无 Schema 模式
- **索引非自动创建**: 需要在 Schema 中显式标记 `Indexed: true`
- **类型严格**: Schema 验证严格int int64 需要正确匹配
- **类型名称简化**:
- **重要变更**: v2.0 开始类型名称已简化使用简短形式 `String` 而非 `FieldTypeString`
- 每个 Go 类型有对应的简短常量 `int32` `Int32``string` `String`
- 插入时类型会自动转换 `int` `int32`但需要注意负数不能转为无符号类型
- **新增类型的使用**:
- **Byte**: 虽然底层是 `uint8`但在 Schema 中作为独立类型语义更清晰用于状态码标志位等
- **Rune**: 虽然底层是 `int32`但在 Schema 中作为独立类型用于存储单个 Unicode 字符
- **Decimal**: 必须使用 `github.com/shopspring/decimal` 用于金融计算等需要精确数值的场景
- **Nullable 支持**:
- 需要显式标记 `Nullable: true`默认字段不允许 NULL
- NULL 值在 Go 中表示为 `nil`
- 读取时需要检查值是否存在且不为 nil
- **选择合适的类型大小**:
- 避免盲目使用 `Int64`/`Float64`根据数据范围选择如百分比用 `Uint8`状态码用 `Byte`
- 过大的类型浪费存储和内存影响性能
- **Compaction 磁盘占用**: 合并期间旧文件和新文件共存会暂时增加磁盘使用
- **MemTable flush 异步**: 关闭时需要等待 immutable flush 完成
- **mmap 虚拟内存**: 可能显示较大的虚拟内存使用正常OS 管理不是实际 RAM
- ** panic**: 所有 panic 已替换为错误返回需要正确处理错误
- **废弃代码**: `SSTableCompressionNone` 等常量已删除
## Web UI