Files
srdb/examples/complex/README.md

10 KiB
Raw Blame History

SRDB 复杂类型示例

这个示例演示了 SRDB 支持的所有 21 种数据类型的使用方法,包括:

  • 结构体自动生成 Schema
  • 所有基本类型和特殊类型的插入与查询
  • 边界值测试
  • 索引查询
  • 分页查询
  • 复杂类型Object/Array的序列化

📊 支持的 21 种类型

基本类型 (14种)

分类 类型 Go 类型 说明
字符串 String string UTF-8 字符串
有符号整数 Int int 平台相关
Int8 int8 -128 ~ 127
Int16 int16 -32768 ~ 32767
Int32 int32 -2^31 ~ 2^31-1
Int64 int64 -2^63 ~ 2^63-1
无符号整数 Uint uint 平台相关
Uint8 uint8 0 ~ 255
Uint16 uint16 0 ~ 65535
Uint32 uint32 0 ~ 4294967295
Uint64 uint64 0 ~ 2^64-1
浮点数 Float32 float32 单精度
Float64 float64 双精度
布尔 Bool bool true/false

特殊类型 (5种)

类型 Go 类型 说明 使用场景
Byte byte 0-255独立类型 状态码、百分比、标志位
Rune rune Unicode 字符(独立类型) 等级、分类字符
Decimal decimal.Decimal 高精度十进制 金融计算、货币金额
Time time.Time 时间戳 日期时间
Duration time.Duration 时长 超时、间隔、运行时长

复杂类型 (2种)

类型 Go 类型 说明
Object map[string]any, struct{} JSON 编码存储
Array []any, []string, []int JSON 编码存储

🚀 快速开始

1. 构建并运行

cd examples/complex
go run main.go

2. 使用参数

# 指定数据目录
go run main.go --dir ./mydata

# 清理数据并重新生成
go run main.go --clean

# 指定目录并清理
go run main.go --dir ./mydata --clean

3. 构建可执行文件

go build -o complex
./complex --clean

📝 代码结构

结构体定义

type DeviceRecord struct {
    // 字符串
    DeviceID string `srdb:"device_id;indexed;comment:设备ID"`
    Name     string `srdb:"name;comment:设备名称"`

    // 有符号整数 (5种)
    Signal     int   `srdb:"signal;comment:信号强度"`
    ErrorCode  int8  `srdb:"error_code;comment:错误码"`
    DeltaTemp  int16 `srdb:"delta_temp;comment:温差"`
    RecordNum  int32 `srdb:"record_num;comment:记录号"`
    TotalBytes int64 `srdb:"total_bytes;comment:总字节数"`

    // 无符号整数 (5种)
    Flags      uint   `srdb:"flags;comment:标志位"`
    Status     uint8  `srdb:"status;comment:状态"`
    Port       uint16 `srdb:"port;comment:端口"`
    SessionID  uint32 `srdb:"session_id;comment:会话ID"`
    Timestamp  uint64 `srdb:"timestamp;comment:时间戳"`

    // 浮点数 (2种)
    TempValue float32 `srdb:"temp_value;comment:温度值"`
    Latitude  float64 `srdb:"latitude;comment:纬度"`
    Longitude float64 `srdb:"longitude;comment:经度"`

    // 布尔
    IsOnline bool `srdb:"is_online;indexed;comment:在线状态"`

    // 特殊类型
    BatteryPct byte            `srdb:"battery_pct;comment:电量百分比"`
    Level      rune            `srdb:"level;comment:等级字符"`
    Price      decimal.Decimal `srdb:"price;comment:价格"`
    CreatedAt  time.Time       `srdb:"created_at;comment:创建时间"`
    RunTime    time.Duration   `srdb:"run_time;comment:运行时长"`

    // 复杂类型
    Settings map[string]any `srdb:"settings;comment:设置"`
    Tags     []string       `srdb:"tags;comment:标签列表"`
}

核心步骤

  1. 从结构体生成 Schema

    fields, err := srdb.StructToFields(DeviceRecord{})
    
  2. 创建表

    table, err := srdb.OpenTable(&srdb.TableOptions{
        Dir:    "./data",
        Name:   "devices",
        Fields: fields,
    })
    
  3. 插入数据(使用 map

    device := map[string]any{
        "device_id":   "IOT-2025-0001",
        "name":        "智能环境监测站",
        "signal":      -55,
        "error_code":  int8(0),
        "port":        uint16(8080),
        "temp_value":  float32(23.5),
        "is_online":   true,
        "battery_pct": byte(85),
        "level":       rune('S'),
        "price":       decimal.NewFromFloat(999.99),
        "created_at":  time.Now(),
        "run_time":    3*time.Hour + 25*time.Minute,
        "settings":    map[string]any{"interval": 60},
        "tags":        []string{"indoor", "hvac"},
    }
    table.Insert(device)
    
  4. 查询数据

    rows, err := table.Query().OrderBy("_seq").Rows()
    for rows.Next() {
        row := rows.Row()
        data := row.Data()
        // 处理数据...
    }
    
  5. 索引查询

    table.BuildIndexes()
    rows, _ := table.Query().Eq("device_id", "IOT-2025-0001").Rows()
    
  6. 分页查询

    rows, total, err := table.Query().OrderBy("_seq").Paginate(1, 10)
    

🎯 示例输出

运行程序后,你会看到漂亮的表格化输出:

╔═══════════════ 设备记录 #1 (seq=1) ═══════════════╗
║ ID: IOT-2025-0001                                   ║
║ 名称: 智能环境监测站                                 ║
╟─────────────────── 整数类型 ────────────────────────╢
║ Signal(int):    -55                                 ║
║ ErrorCode(i8):  0                                   ║
║ DeltaTemp(i16): 150                                 ║
║ RecordNum(i32): 12345                               ║
║ TotalBytes(i64):1073741824                          ║
║ Flags(uint):    0xF                                 ║
║ Status(u8):     200                                 ║
║ Port(u16):      8080                                ║
║ SessionID(u32): 987654321                           ║
║ Timestamp(u64): 1760210986                          ║
╟───────────────── 浮点/布尔 ──────────────────────╢
║ Temperature(f32): 23.50°C                           ║
║ 坐标(f64): (39.904200, 116.407396)                  ║
║ Online(bool): true                                  ║
╟───────────────── 特殊类型 ──────────────────────╢
║ Battery(byte): 85%                                  ║
║ Level(rune):   S                                    ║
║ Price(decimal): ¥999.99                             ║
║ CreatedAt(time): 2025-10-12 03:29:46               ║
║ RunTime(duration): 3h25m0s                         ║
╟───────────────── 复杂类型 ──────────────────────╢
║ Settings(object): 4 项配置                          ║
║   • report_interval      = 60                      ║
║   • sample_rate          = 100                     ║
║   • auto_calibrate       = true                    ║
║   • threshold            = 25                      ║
║ Tags(array): 4 个标签                              ║
║   [indoor hvac monitoring enterprise]               ║
╚═════════════════════════════════════════════════════╝

💡 关键特性

1. 边界值测试

示例包含各类型的边界值测试:

device := map[string]any{
    "error_code":  int8(127),              // int8 最大值
    "delta_temp":  int16(-32768),          // int16 最小值
    "record_num":  int32(2147483647),      // int32 最大值
    "total_bytes": int64(9223372036854775807), // int64 最大值
    "status":      uint8(255),             // uint8 最大值
    "port":        uint16(65535),          // uint16 最大值
}

2. 索引查询优化

使用索引加速查询:

// 结构体中标记索引
DeviceID string `srdb:"device_id;indexed"`
IsOnline bool   `srdb:"is_online;indexed"`

// 构建索引
table.BuildIndexes()

// 使用索引查询
rows, _ := table.Query().Eq("device_id", "IOT-2025-0001").Rows()
rows, _ := table.Query().Eq("is_online", true).Rows()

3. 分页查询

支持返回总数的分页:

rows, total, err := table.Query().OrderBy("_seq").Paginate(1, 2)
fmt.Printf("总记录数: %d\n", total)

4. 复杂类型序列化

Object 和 Array 自动序列化为 JSON

// Object: map[string]any
"settings": map[string]any{
    "report_interval": 60,
    "sample_rate":     100,
    "auto_calibrate":  true,
}

// Array: []string
"tags": []string{"indoor", "hvac", "monitoring"}

// 查询时自动反序列化
settings := data["settings"].(map[string]any)
tags := data["tags"].([]any)

📚 类型选择最佳实践

整数类型

// ❌ 不推荐:盲目使用 int64
Port   int64  // 端口号 0-65535浪费 6 字节
Status int64  // 状态码 0-255浪费 7 字节

// ✅ 推荐:根据数据范围选择
Port   uint16 // 0-655352 字节
Status uint8  // 0-2551 字节

浮点数类型

// ❌ 不推荐
Temperature float64 // 温度用单精度足够

// ✅ 推荐
Temperature float32 // -40°C ~ 125°C单精度足够
Latitude    float64 // 地理坐标需要双精度

特殊类型使用

// Byte: 百分比、状态码
BatteryLevel byte   // 0-100

// Rune: 单字符等级
Grade        rune   // 'S', 'A', 'B', 'C'

// Decimal: 金融计算
Price        decimal.Decimal  // 避免浮点精度问题

// Time: 时间戳
CreatedAt    time.Time

// Duration: 时长
Timeout      time.Duration

🔧 依赖

import (
    "code.tczkiot.com/wlw/srdb"
    "github.com/shopspring/decimal"
)

确保已安装 decimal 包:

go get github.com/shopspring/decimal

📖 相关文档

🤝 贡献

如果你有更好的示例或发现问题,欢迎提交 Issue 或 Pull Request。

📄 许可证

MIT License - 详见项目根目录 LICENSE 文件