# TsDB2 完整操作教程 本教程涵盖 TsDB2 时序数据库的所有核心操作,包括建表、增删改查、条件查询、索引管理、事务控制等。 --- ## 📋 目录 1. [基础概念](#1-基础概念) 2. [建表与索引](#2-建表与索引) 3. [插入数据 (Create)](#3-插入数据-create) 4. [查询数据 (Read)](#4-查询数据-read) 5. [更新数据 (Update)](#5-更新数据-update) 6. [删除数据 (Delete)](#6-删除数据-delete) 7. [条件查询详解](#7-条件查询详解) 8. [排序与分页](#8-排序与分页) 9. [聚合查询](#9-聚合查询) 10. [多表关联](#10-多表关联) 11. [事务与提交](#11-事务与提交) 12. [高级特性](#12-高级特性) --- ## 1. 基础概念 ### 1.1 数据模型定义 TsDB2 使用 Go struct 定义数据模型,通过 `tsdb` tag 指定字段类型: ```go package main import ( "TsDB2/DB" "fmt" ) // 员工表模型 type Employee struct { DB.BaseModel // 必须嵌入,提供 ID 字段 Name string `tsdb:"32byte"` // 字符串字段,最大32字节 Age int64 `tsdb:"8byte"` // 整数字段,8字节 Score int64 `tsdb:"8byte"` // 整数字段,8字节 Dept string `tsdb:"16byte"` // 字符串字段,最大16字节 } // 订单表模型 type Order struct { DB.BaseModel EmployeeID int64 `tsdb:"8byte"` Amount int64 `tsdb:"8byte"` Status int64 `tsdb:"8byte"` // 0=pending, 1=done, 2=cancel } ``` **支持的字段类型:** - `1byte` ~ `256byte`: 变长字符串/二进制 - `8byte`: int64 / uint64 - `4byte`: int32 / uint32 - `2byte`: int16 / uint16 - `1byte`: int8 / uint8 ### 1.2 打开数据库 ```go // 打开或创建数据库文件 db, err := DB.Open("mydb.db") if err != nil { panic(err) } defer db.Close() // 程序退出前关闭 // 设置自动提交延迟(防抖) db.SetAutoCommitDelay(500 * time.Millisecond) // 500ms 后自动 Commit ``` --- ## 2. 建表与索引 ### 2.1 创建表 ```go // ✅ 推荐方式:自动推导表名(从类型名 Employee -> "employee") empTbl, err := DB.UseTable[Employee](db) if err != nil { panic(err) } // 可选:手动指定表名 orderTbl, err := DB.UseTable[Order](db, "orders") // 自定义表名为 "orders" if err != nil { panic(err) } ``` **工作原理:** - `UseTable[Employee](db)` → 自动推导表名为 `"employee"`(首字母小写) - `UseTable[OrderItem](db)` → 自动推导表名为 `"orderItem"` - `UseTable[T](db, "custom_name")` → 使用自定义表名 ### 2.2 创建索引 TsDB2 支持多种索引类型: ```go // 获取表的底层 Core 对象 empCore, _ := db.CoreDB().FindTable("employee") // 1️⃣ 主键 B+ 树索引(自动创建,基于 ID 字段) // 无需手动创建,UseTable 时自动生成 pk_employee // 2️⃣ 二级 B+ 树索引(单字段) empCore.CreateIndex("idx_age", page.IndexTypeBTree, []byte{2}) // Age 字段索引 empCore.CreateIndex("idx_dept", page.IndexTypeBTree, []byte{4}) // Dept 字段索引 // 3️⃣ 时序索引(时间范围查询优化) // empCore.CreateIndex("idx_time", page.IndexTypeTime, []byte{1}) // 4️⃣ 复合索引(多字段组合) // empCore.CreateIndex("idx_age_dept", page.IndexTypeCompose, []byte{2, 4}) orderCore, _ := db.CoreDB().FindTable("order") orderCore.CreateIndex("idx_status", page.IndexTypeBTree, []byte{3}) // Status 索引 ``` **索引类型说明:** - `IndexTypePrimary` (2): 主键索引,叶子节点存 `[Key → DataPage]` - `IndexTypeBTree` (5): 二级 B+ 树索引,叶子节点存 `[Key → PKID]` - `IndexTypeTime` (1): 时序索引,优化时间范围查询 - `IndexTypeCompose` (4): 复合索引,多字段联合索引 --- ## 3. 插入数据 (Create) ### 3.1 单行插入 ```go err := empTbl.Insert(&Employee{ Name: "张三", Age: 25, Score: 95, Dept: "工程部", }) if err != nil { fmt.Printf("插入失败: %v\n", err) } ``` ### 3.2 批量插入 ```go // 插入 10000 条员工记录 for i := 1; i <= 10000; i++ { err := empTbl.Insert(&Employee{ Name: fmt.Sprintf("Emp%07d", i), Age: int64(20 + (i % 50)), // 年龄 20~69 Score: int64(i % 1000), // 分数 0~999 Dept: []string{"工程部", "销售部", "人事部", "财务部", "运维部"}[i%5], }) if err != nil { panic(fmt.Sprintf("插入第 %d 行失败: %v", i, err)) } // 每 1000 行打印进度 if i%1000 == 0 { fmt.Printf("已插入 %d 行\n", i) } } ``` ### 3.3 性能优化:批量 Commit ```go // 禁用自动提交,手动控制 Commit 时机 db.SetAutoCommitDelay(0) // 禁用防抖 // 批量插入 10 万行 for i := 1; i <= 100000; i++ { empTbl.Insert(&Employee{...}) } // 一次性提交所有数据 fmt.Println("开始 Commit...") t1 := time.Now() if err := db.Commit(); err != nil { panic(err) } fmt.Printf("Commit 完成,耗时: %.2fs\n", time.Since(t1).Seconds()) ``` **性能对比:** - 每行自动 Commit: 10万行约 100秒 - 批量 Commit: 10万行约 4秒(**快 25 倍**) --- ## 4. 查询数据 (Read) ### 4.1 主键精确查询 ```go // 根据 ID 查询 emp, err := empTbl.Find(1) if err != nil { fmt.Printf("未找到 ID=1 的记录\n") } else { fmt.Printf("ID=%d, Name=%s, Age=%d, Score=%d, Dept=%s\n", emp.ID, emp.Name, emp.Age, emp.Score, emp.Dept) } ``` ### 4.2 条件查询 ```go // WHERE Age = 25 rows, err := empTbl.Where("Age", "=", int64(25)).Find() if err != nil { panic(err) } fmt.Printf("找到 %d 名 25 岁的员工\n", len(rows)) for _, emp := range rows { fmt.Printf(" - %s (Score: %d)\n", emp.Name, emp.Score) } ``` ### 4.3 遍历所有记录 ```go // 全表扫描 allEmps, err := empTbl.Find() // 无条件,返回所有记录 if err != nil { panic(err) } fmt.Printf("总共有 %d 名员工\n", len(allEmps)) // 循环处理 for i, emp := range allEmps { if emp.Score >= 90 { fmt.Printf("[%d] 优秀员工: %s, Score=%d\n", i+1, emp.Name, emp.Score) } } ``` --- ## 5. 更新数据 (Update) ### 5.1 根据主键更新 ```go // 更新 ID=1 的员工信息 err := empTbl.Update(&Employee{ BaseModel: DB.BaseModel{ID: 1}, // 必须指定 ID Name: "李四", Age: 30, Score: 98, Dept: "技术部", }) if err != nil { fmt.Printf("更新失败: %v\n", err) } // 验证更新 emp, _ := empTbl.Find(1) fmt.Printf("更新后: Name=%s, Age=%d\n", emp.Name, emp.Age) // 输出: 更新后: Name=李四, Age=30 ``` ### 5.2 批量更新(循环) ```go // 给所有工程部员工加 10 分 emps, _ := empTbl.Where("Dept", "=", "工程部").Find() for _, emp := range emps { emp.Score += 10 empTbl.Update(emp) } fmt.Printf("已为 %d 名工程部员工加分\n", len(emps)) ``` --- ## 6. 删除数据 (Delete) ### 6.1 根据主键删除 ```go // 删除 ID=2 的员工 err := empTbl.Delete(2) if err != nil { fmt.Printf("删除失败: %v\n", err) } // 验证删除 _, err = empTbl.Find(2) if err != nil { fmt.Println("✅ ID=2 已成功删除") } ``` ### 6.2 批量删除(循环) ```go // 删除所有分数低于 60 的员工 lowScores, _ := empTbl.Where("Score", "<", int64(60)).Find() fmt.Printf("找到 %d 名低分员工\n", len(lowScores)) for _, emp := range lowScores { empTbl.Delete(emp.ID) } fmt.Println("✅ 已删除所有低分员工") // 验证 remaining, _ := empTbl.Count() fmt.Printf("剩余员工数: %d\n", remaining) ``` ### 6.3 级联删除 ```go // 删除部门时,同时删除该部门所有员工 deptToDelete := "临时工" emps, _ := empTbl.Where("Dept", "=", deptToDelete).Find() for _, emp := range emps { empTbl.Delete(emp.ID) } fmt.Printf("已删除 %d 名 %s 员工\n", len(emps), deptToDelete) ``` --- ## 7. 条件查询详解 ### 7.1 比较运算符 ```go // 等于 (=) rows, _ := empTbl.Where("Age", "=", int64(25)).Find() // 不等于 (!=) rows, _ = empTbl.Where("Status", "!=", int64(0)).Find() // 大于 (>) rows, _ = empTbl.Where("Score", ">", int64(90)).Find() // 大于等于 (>=) rows, _ = empTbl.Where("Age", ">=", int64(30)).Find() // 小于 (<) rows, _ = empTbl.Where("Score", "<", int64(60)).Find() // 小于等于 (<=) rows, _ = empTbl.Where("Age", "<=", int64(25)).Find() ``` ### 7.2 范围查询 ```go // WHERE Age >= 20 AND Age <= 30 rows, _ := empTbl. Where("Age", ">=", int64(20)). Where("Age", "<=", int64(30)). Find() fmt.Printf("20~30岁员工: %d 人\n", len(rows)) ``` ### 7.3 IN 查询 ```go // WHERE Dept IN ("工程部", "技术部") rows, _ := empTbl.Where("Dept", "in", []string{"工程部", "技术部"}).Find() fmt.Printf("工程/技术部员工: %d 人\n", len(rows)) ``` ### 7.4 LIKE 模糊查询 ```go // WHERE Name LIKE "张%" rows, _ := empTbl.Where("Name", "like", "张%").Find() fmt.Printf("姓张的员工: %d 人\n", len(rows)) // WHERE Name LIKE "%三" rows, _ = empTbl.Where("Name", "like", "%三").Find() fmt.Printf("名字以'三'结尾的员工: %d 人\n", len(rows)) ``` ### 7.5 多条件组合 ```go // WHERE Age > 25 AND Score >= 80 AND Dept = "工程部" rows, _ := empTbl. Where("Age", ">", int64(25)). Where("Score", ">=", int64(80)). Where("Dept", "=", "工程部"). Find() fmt.Printf("符合条件的员工: %d 人\n", len(rows)) ``` ### 7.6 OR 条件 ```go // 使用 OrCondition import "TsDB2/DB/core" cond := core.OrCondition{ core.EqCondition{Field: "Dept", Value: "工程部"}, core.EqCondition{Field: "Dept", Value: "技术部"}, } rows, _ := empTbl.WhereCondition(cond).Find() ``` --- ## 8. 排序与分页 ### 8.1 升序排序 ```go // ORDER BY Age ASC rows, _ := empTbl.OrderBy("Age").Find() fmt.Println("按年龄升序:") for _, emp := range rows[:5] { // 只看前5条 fmt.Printf(" %s: %d岁\n", emp.Name, emp.Age) } ``` ### 8.2 降序排序 ```go // ORDER BY Score DESC rows, _ := empTbl.OrderBy("Score", true).Find() // true = 降序 fmt.Println("按分数降序(前5名):") for i, emp := range rows[:5] { fmt.Printf(" [%d] %s: %d分\n", i+1, emp.Name, emp.Score) } ``` ### 8.3 LIMIT 限制数量 ```go // ORDER BY Age ASC LIMIT 10 rows, _ := empTbl.OrderBy("Age").Limit(10).Find() fmt.Printf("最年轻的 10 名员工:\n") for _, emp := range rows { fmt.Printf(" %s: %d岁\n", emp.Name, emp.Age) } ``` ### 8.4 OFFSET + LIMIT 分页 ```go // 每页 20 条 pageSize := 20 // 第1页 page1, _ := empTbl.OrderBy("Age").Offset(0).Limit(pageSize).Find() fmt.Printf("第1页: %d 条\n", len(page1)) // 第2页 page2, _ := empTbl.OrderBy("Age").Offset(pageSize).Limit(pageSize).Find() fmt.Printf("第2页: %d 条\n", len(page2)) // 第3页 page3, _ := empTbl.OrderBy("Age").Offset(pageSize*2).Limit(pageSize).Find() fmt.Printf("第3页: %d 条\n", len(page3)) ``` ### 8.5 完整分页示例 ```go func printPage(tbl *DB.Table[Employee], pageNum, pageSize int) { offset := (pageNum - 1) * pageSize rows, _ := tbl.OrderBy("Age").Offset(offset).Limit(pageSize).Find() fmt.Printf("\n=== 第 %d 页 (共 %d 条) ===\n", pageNum, len(rows)) for _, emp := range rows { fmt.Printf(" %-15s %2d岁 %3d分 %s\n", emp.Name, emp.Age, emp.Score, emp.Dept) } } // 打印前3页 for page := 1; page <= 3; page++ { printPage(empTbl, page, 20) } ``` --- ## 9. 聚合查询 ### 9.1 COUNT 计数 ```go // SELECT COUNT(*) FROM employee total, err := empTbl.Count() if err != nil { panic(err) } fmt.Printf("员工总数: %d\n", total) // 带条件的 COUNT youngCount, _ := empTbl.Where("Age", "<", int64(25)).Count() fmt.Printf("25岁以下员工: %d 人\n", youngCount) ``` ### 9.2 MIN/MAX(通过排序实现) ```go // 最小年龄 minAgeRows, _ := empTbl.OrderBy("Age").Limit(1).Find() if len(minAgeRows) > 0 { fmt.Printf("最小年龄: %d岁 (%s)\n", minAgeRows[0].Age, minAgeRows[0].Name) } // 最大分数 maxScoreRows, _ := empTbl.OrderBy("Score", true).Limit(1).Find() if len(maxScoreRows) > 0 { fmt.Printf("最高分数: %d分 (%s)\n", maxScoreRows[0].Score, maxScoreRows[0].Name) } ``` ### 9.3 SUM/AVG(循环计算) ```go // 计算平均分数 allEmps, _ := empTbl.Find() var totalScore int64 for _, emp := range allEmps { totalScore += emp.Score } avgScore := float64(totalScore) / float64(len(allEmps)) fmt.Printf("平均分数: %.2f\n", avgScore) // 各部门平均分 deptMap := make(map[string][]int64) for _, emp := range allEmps { deptMap[emp.Dept] = append(deptMap[emp.Dept], emp.Score) } for dept, scores := range deptMap { var sum int64 for _, s := range scores { sum += s } avg := float64(sum) / float64(len(scores)) fmt.Printf(" %s: 平均 %.2f 分 (%d 人)\n", dept, avg, len(scores)) } ``` --- ## 10. 多表关联 ### 10.1 简单关联查询 ```go // 查询某员工的所有订单 employeeID := int64(1) orders, _ := orderTbl.Where("EmployeeID", "=", employeeID).Find() fmt.Printf("员工 %d 的订单数: %d\n", employeeID, len(orders)) for _, order := range orders { fmt.Printf(" 订单ID=%d, 金额=%d, 状态=%d\n", order.ID, order.Amount, order.Status) } ``` ### 10.2 嵌套循环关联 ```go // 查询每个员工的订单总数 emps, _ := empTbl.Find() for _, emp := range emps[:10] { // 只看前10名员工 orders, _ := orderTbl.Where("EmployeeID", "=", int64(emp.ID)).Find() fmt.Printf("%-15s: %d 个订单\n", emp.Name, len(orders)) } ``` ### 10.3 复杂关联 + 条件 ```go // 查询工程部员工的状态为"已完成"的订单 deptEmps, _ := empTbl.Where("Dept", "=", "工程部").Find() var totalAmount int64 var orderCount int for _, emp := range deptEmps { orders, _ := orderTbl. Where("EmployeeID", "=", int64(emp.ID)). Where("Status", "=", int64(1)). // 1 = done Find() for _, order := range orders { totalAmount += order.Amount orderCount++ } } fmt.Printf("工程部已完成订单: %d 笔, 总金额: %d\n", orderCount, totalAmount) ``` --- ## 11. 事务与提交 ### 11.1 手动 Commit ```go // 禁用自动提交 db.SetAutoCommitDelay(0) // 执行多个操作 empTbl.Insert(&Employee{Name: "A", Age: 25, Score: 90, Dept: "IT"}) empTbl.Insert(&Employee{Name: "B", Age: 30, Score: 85, Dept: "HR"}) empTbl.Delete(5) // 一次性提交 if err := db.Commit(); err != nil { fmt.Printf("提交失败: %v\n", err) // 可以回滚或重试 } else { fmt.Println("✅ 事务提交成功") } ``` ### 11.2 防抖自动提交 ```go // 设置 500ms 防抖 db.SetAutoCommitDelay(500 * time.Millisecond) // 连续插入,最后一次操作后 500ms 自动 Commit for i := 1; i <= 100; i++ { empTbl.Insert(&Employee{...}) } // 等待自动提交 time.Sleep(1 * time.Second) fmt.Println("数据已自动提交") ``` ### 11.3 脏页阈值自动提交 ```go // 当脏页超过 500 页时自动触发 Commit db.SetDirtyThreshold(500) // 大量插入时会自动分批 Commit for i := 1; i <= 100000; i++ { empTbl.Insert(&Employee{...}) } // 无需手动 Commit,系统会根据脏页阈值自动提交 ``` ### 11.4 提交策略预设(推荐) TsDB2 提供三种预设配置,可根据业务场景选择: ```go // 方式1: 使用预设(最简单) db.SetCommitPreset("batch") // 离线批量导入 db.SetCommitPreset("online") // 在线业务默认 db.SetCommitPreset("safe") // 金融/医疗关键数据 // 方式2: 手动配置 db.SetDirtyThreshold(500) // 脏页阈值(页数) db.SetAutoCommitDelay(time.Second) // 防抖超时 ``` #### 预设对比 | 预设 | 脏页阈值 | 内存占用 | 防抖超时 | 断电风险 | 适用场景 | |------|---------|---------|---------|---------|----------| | **batch** | 500页 | 8MB | 1s | ~10,000行 | 离线导入、日志归档 | | **online** | 100页 | 1.6MB | 500ms | ~2,000行 | Web应用、API服务 | | **safe** | 20页 | 320KB | 100ms | ~400行 | 金融交易、医疗记录 | #### 选择建议 **离线批量导入(batch)** ```go db, _ := DB.Open("import.db") db.SetCommitPreset("batch") // 高吞吐 tbl, _ := DB.UseTable[Record](db) for i := 1; i <= 1_000_000; i++ { tbl.Insert(&Record{Name: fmt.Sprintf("Emp%07d", i)}) } // 性能: ~28s 插入 100万行 // 风险: 断电最多丢失 1万行(可重跑脚本) ``` **在线业务(online)** ```go db, _ := DB.Open("app.db") db.SetCommitPreset("online") // 平衡 tbl, _ := DB.UseTable[Order](db) http.HandleFunc("/api/order", func(w http.ResponseWriter, r *http.Request) { order := parseOrder(r) tbl.Insert(order) // 每次请求插入 // 500ms 后自动落盘,断电最多丢失 2000行 }) ``` **关键数据(safe)** ```go db, _ := DB.Open("finance.db") db.SetCommitPreset("safe") // 最高安全 tbl, _ := DB.UseTable[Transaction](db) func transfer(from, to string, amount float64) { tbl.Insert(&Transaction{From: from, To: to, Amount: amount}) // 100ms 后自动落盘,断电最多丢失 400行 // 适合银行转账、医疗记录等关键业务 } ``` ### 11.5 Close 兜底提交 ```go // 即使忘记 Commit,Close 时也会自动提交 db, _ := DB.Open("test.db") tbl, _ := DB.UseTable[Employee](db, "test") for i := 1; i <= 1000; i++ { tbl.Insert(&Employee{...}) } // 没有手动 Commit db.Close() // ✅ Close 内部会调用 Commit,确保数据持久化 // 重新打开验证 db2, _ := DB.Open("test.db") tbl2, _ := DB.UseTable[Employee](db2, "test") count, _ := tbl2.Count() fmt.Printf("Close 后数据保留: %d 条\n", count) // 输出: 1000 条 ``` --- ## 12. 高级特性 ### 12.1 Schema 演进(添加字段) ```go // V1: 初始版本 type EmployeeV1 struct { DB.BaseModel Name string `tsdb:"32byte"` Age int64 `tsdb:"8byte"` } // V2: 添加新字段 type EmployeeV2 struct { DB.BaseModel Name string `tsdb:"32byte"` Age int64 `tsdb:"8byte"` Email string `tsdb:"64byte"` // 新增字段 } // TsDB2 自动处理 schema 版本迁移 tbl, _ := DB.UseTable[EmployeeV2](db, "employee") ``` ### 12.2 删除字段(软删除) ```go // 标记字段为 dropped(不物理删除,保持兼容性) empCore.DropField("Score") // Score 字段标记为已删除 // 查询时不再返回该字段 emp, _ := tbl.Find(1) // emp.Score 将为默认值 0 ``` ### 12.3 删除表 ```go // 删除整个表(回收所有页) err := db.DropTable("order") if err != nil { fmt.Printf("删除表失败: %v\n", err) } // 验证删除 _, exists := db.CoreDB().FindTable("order") if !exists { fmt.Println("✅ order 表已删除") } ``` ### 12.4 索引管理 ```go // 查看所有索引 table, _ := db.CoreDB().FindTable("employee") for _, idx := range table.GetIndexes() { fmt.Printf("索引: %s, 类型: %d, 根页: %d\n", idx.Name, idx.Type, idx.EntryPage) } // 删除索引 table.DropIndex("idx_age") ``` ### 12.5 性能监控 ```go // 统计信息 fi, _ := os.Stat("mydb.db") fmt.Printf("数据库大小: %.2f MB\n", float64(fi.Size())/1024/1024) // 表统计 count, _ := empTbl.Count() fmt.Printf("员工表行数: %d\n", count) // BufferPool 统计 bp := db.CoreDB().GetBufferPool() fmt.Printf("缓存页数: %d\n", bp.Len()) fmt.Printf("脏页数: %d\n", bp.DirtyCount()) ``` ### 12.6 并发安全 ```go // TsDB2 不是线程安全的,需要在应用层加锁 var mu sync.Mutex go func() { mu.Lock() defer mu.Unlock() empTbl.Insert(&Employee{...}) }() go func() { mu.Lock() defer mu.Unlock() empTbl.Find(1) }() ``` --- ## 🎯 完整示例:员工管理系统 ```go package main import ( "TsDB2/DB" "fmt" "time" ) type Employee struct { DB.BaseModel Name string `tsdb:"32byte"` Age int64 `tsdb:"8byte"` Score int64 `tsdb:"8byte"` Dept string `tsdb:"16byte"` } func main() { // 1. 打开数据库 db, _ := DB.Open("company.db") defer db.Close() db.SetAutoCommitDelay(0) // 手动控制 // 2. 建表 + 索引(自动推导表名) tbl, _ := DB.UseTable[Employee](db) // ✅ 无需传递 "employee" core, _ := db.CoreDB().FindTable("employee") core.CreateIndex("idx_age", page.IndexTypeBTree, []byte{2}) core.CreateIndex("idx_dept", page.IndexTypeBTree, []byte{4}) // 3. 批量插入 fmt.Println("插入数据...") depts := []string{"工程部", "销售部", "人事部", "财务部", "运维部"} for i := 1; i <= 1000; i++ { tbl.Insert(&Employee{ Name: fmt.Sprintf("Emp%04d", i), Age: int64(20 + (i % 50)), Score: int64(50 + (i % 51)), Dept: depts[i%5], }) } db.Commit() // 4. 查询 fmt.Println("\n=== 查询示例 ===") // 4.1 主键查询 emp, _ := tbl.Find(1) fmt.Printf("ID=1: %s, %d岁\n", emp.Name, emp.Age) // 4.2 条件查询 young, _ := tbl.Where("Age", "<", int64(25)).Find() fmt.Printf("25岁以下: %d 人\n", len(young)) // 4.3 排序 + 分页 top10, _ := tbl.OrderBy("Score", true).Limit(10).Find() fmt.Println("分数Top 10:") for i, e := range top10 { fmt.Printf(" [%d] %s: %d分\n", i+1, e.Name, e.Score) } // 4.4 聚合 total, _ := tbl.Count() fmt.Printf("总人数: %d\n", total) // 5. 更新 fmt.Println("\n=== 更新示例 ===") tbl.Update(&Employee{ BaseModel: DB.BaseModel{ID: 1}, Score: 100, }) emp, _ = tbl.Find(1) fmt.Printf("ID=1 更新后分数: %d\n", emp.Score) // 6. 删除 fmt.Println("\n=== 删除示例 ===") tbl.Delete(2) _, err := tbl.Find(2) if err != nil { fmt.Println("ID=2 已删除") } // 7. 复杂查询 fmt.Println("\n=== 复杂查询 ===") itHighScore, _ := tbl. Where("Dept", "=", "工程部"). Where("Score", ">", int64(80)). Find() fmt.Printf("工程部高分员工: %d 人\n", len(itHighScore)) fmt.Println("\n✅ 所有操作完成!") } ``` --- ## 📚 参考资料 - **Analyzer 工具**: 可视化查看数据库内部结构 - **full_test**: 完整功能测试用例 - **no_commit_test**: 事务与自动提交流程测试 --- **祝使用愉快!** 🎉