# MySQL Database Directory Layer - 完整设计文档 ## 📋 项目概述 ### 项目背景 本项目实现了一个类似 DBeaver 的数据库目录层,为前端提供树形结构的数据库对象导航功能。支持懒加载、分页、搜索、完整的 CRUD 操作以及丰富的事务支持。 ### 核心目标 - 🎯 **树形导航**: 提供直观的数据库对象树形结构 - 🔍 **智能搜索**: 支持按名称搜索所有数据库对象 - 📄 **分页加载**: 避免大数据集导致的性能问题 - 🔄 **懒加载**: 按需加载子节点,提升响应速度 - 🛠️ **完整CRUD**: 支持所有数据库对象的增删改查操作 - 🔐 **事务支持**: 所有写操作都支持事务保证数据一致性 - 🎨 **元数据丰富**: 提供详细的数据库对象元数据信息 ## 🏗️ 架构设计 ### 整体架构 ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Frontend │ │ Database Layer │ │ MySQL Server │ │ (Wails) │◄──►│ (Go) │◄──►│ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ │ Meta Layer │ │ (Node, Types) │ └─────────────────┘ ``` ### 核心组件 #### 1. Meta Layer (元数据层) - **Node**: 树形结构的节点表示 - **Metadata**: 数据库对象的元数据信息 - **Types**: 通用数据类型定义 #### 2. Interface Layer (接口层) - **Reader Interfaces**: 读取操作接口 - **Writer Interfaces**: 写入操作接口 - **Provider Interface**: 组合接口 #### 3. Driver Layer (驱动层) - **MySQL v8 Driver**: MySQL 8.0+ 版本支持 - **Connection Management**: 连接池和事务管理 - **SQL Execution**: 安全的SQL执行引擎 ## 🔧 接口设计 ### 设计原则 - ✅ **单一职责**: 每个接口职责明确 - ✅ **小接口**: 控制接口方法数量 (≤4个方法) - ✅ **组合优先**: 通过组合构建复杂功能 - ✅ **一致性**: 统一的方法签名和错误处理 ### Reader Interfaces #### NodeReader - 节点读取接口 ```go type NodeReader interface { GetRoot(ctx context.Context) (*meta.Node, error) GetChildren(ctx context.Context, nodeID string, limit, offset int) ([]*meta.Node, error) GetNode(ctx context.Context, nodeID string) (*meta.Node, error) RefreshNode(ctx context.Context, nodeID string) error } ``` #### SchemaReader - 数据库模式读取接口 ```go type SchemaReader interface { ListSchemas(ctx context.Context, limit, offset int) ([]*meta.Node, error) GetSchema(ctx context.Context, schemaName string) (*meta.Node, error) } ``` #### TableReader - 表读取接口 ```go type TableReader interface { ListTables(ctx context.Context, schemaName string, limit, offset int) ([]*meta.Node, error) GetTable(ctx context.Context, schemaName, tableName string) (*meta.Node, error) ListColumns(ctx context.Context, schemaName, tableName string, limit, offset int) ([]*meta.Node, error) GetColumn(ctx context.Context, schemaName, tableName, columnName string) (*meta.Node, error) } ``` #### ViewReader - 视图读取接口 ```go type ViewReader interface { ListViews(ctx context.Context, schemaName string, limit, offset int) ([]*meta.Node, error) GetView(ctx context.Context, schemaName, viewName string) (*meta.Node, error) } ``` #### IndexReader - 索引读取接口 ```go type IndexReader interface { ListIndexes(ctx context.Context, schemaName, tableName string, limit, offset int) ([]*meta.Node, error) GetIndex(ctx context.Context, schemaName, tableName, indexName string) (*meta.Node, error) } ``` #### TriggerReader - 触发器读取接口 ```go type TriggerReader interface { ListTriggers(ctx context.Context, schemaName, tableName string, limit, offset int) ([]*meta.Node, error) GetTrigger(ctx context.Context, schemaName, tableName, triggerName string) (*meta.Node, error) } ``` #### MetadataReader - 元数据读取接口 ```go type MetadataReader interface { GetConnectionInfo(ctx context.Context) (*meta.Metadata, error) SearchNodes(ctx context.Context, keyword string, nodeType meta.NodeType, limit, offset int) ([]*meta.Node, error) } ``` ### Writer Interfaces #### NodeWriter - 节点写入接口 ```go type NodeWriter interface { UpdateNode(ctx context.Context, nodeID string, updates map[string]interface{}, tx ...types.Transaction) error RenameNode(ctx context.Context, nodeID, newName string, tx ...types.Transaction) error DeleteNode(ctx context.Context, nodeID string, tx ...types.Transaction) error CreateNode(ctx context.Context, parentID string, nodeType meta.NodeType, metadata *meta.Metadata, tx ...types.Transaction) (*meta.Node, error) } ``` #### SchemaWriter - 数据库模式写入接口 ```go type SchemaWriter interface { CreateSchema(ctx context.Context, schemaName string, metadata *meta.Metadata, tx ...types.Transaction) (*meta.Node, error) DropSchema(ctx context.Context, schemaName string, tx ...types.Transaction) error AlterSchema(ctx context.Context, schemaName string, updates map[string]interface{}, tx ...types.Transaction) error } ``` #### TableWriter - 表写入接口 ```go type TableWriter interface { CreateTable(ctx context.Context, schemaName string, metadata *meta.Metadata, tx ...types.Transaction) (*meta.Node, error) DropTable(ctx context.Context, schemaName, tableName string, tx ...types.Transaction) error AlterTable(ctx context.Context, schemaName, tableName string, updates map[string]interface{}, tx ...types.Transaction) error RenameTable(ctx context.Context, schemaName, oldName, newName string, tx ...types.Transaction) error } ``` #### ViewWriter - 视图写入接口 ```go type ViewWriter interface { CreateView(ctx context.Context, schemaName string, metadata *meta.Metadata, tx ...types.Transaction) (*meta.Node, error) DropView(ctx context.Context, schemaName, viewName string, tx ...types.Transaction) error AlterView(ctx context.Context, schemaName, viewName string, updates map[string]interface{}, tx ...types.Transaction) error RenameView(ctx context.Context, schemaName, oldName, newName string, tx ...types.Transaction) error } ``` #### ColumnWriter - 列写入接口 ```go type ColumnWriter interface { AddColumn(ctx context.Context, schemaName, tableName string, metadata *meta.Metadata, tx ...types.Transaction) (*meta.Node, error) DropColumn(ctx context.Context, schemaName, tableName, columnName string, tx ...types.Transaction) error AlterColumn(ctx context.Context, schemaName, tableName, columnName string, updates map[string]interface{}, tx ...types.Transaction) error RenameColumn(ctx context.Context, schemaName, tableName, oldName, newName string, tx ...types.Transaction) error } ``` #### IndexWriter - 索引写入接口 ```go type IndexWriter interface { CreateIndex(ctx context.Context, schemaName, tableName string, metadata *meta.Metadata, tx ...types.Transaction) (*meta.Node, error) DropIndex(ctx context.Context, schemaName, tableName, indexName string, tx ...types.Transaction) error AlterIndex(ctx context.Context, schemaName, tableName, indexName string, updates map[string]interface{}, tx ...types.Transaction) error } ``` #### TriggerWriter - 触发器写入接口 ```go type TriggerWriter interface { CreateTrigger(ctx context.Context, schemaName, tableName string, metadata *meta.Metadata, tx ...types.Transaction) (*meta.Node, error) DropTrigger(ctx context.Context, schemaName, tableName, triggerName string, tx ...types.Transaction) error AlterTrigger(ctx context.Context, schemaName, tableName, triggerName string, updates map[string]interface{}, tx ...types.Transaction) error } ``` ### 组合接口 #### DatabaseReader - 数据库读取接口 ```go type DatabaseReader interface { NodeReader SchemaReader TableReader ViewReader IndexReader TriggerReader MetadataReader } ``` #### DatabaseWriter - 数据库写入接口 ```go type DatabaseWriter interface { NodeWriter SchemaWriter TableWriter ViewWriter ColumnWriter IndexWriter TriggerWriter } ``` #### DatabaseProvider - 数据库提供者接口 ```go type DatabaseProvider interface { DatabaseReader DatabaseWriter TransactionManager Connection Connect(ctx context.Context, config map[string]interface{}) error Disconnect(ctx context.Context) error Ping(ctx context.Context) error } ``` ## 📁 文件结构 ### 整体结构 ``` db_view/ ├── service/ │ └── common/ │ └── databases/ │ ├── interface.go # 接口定义 │ ├── meta/ # 元数据层 │ │ ├── meta.go # Node和Metadata定义 │ │ └── types.go # 基础类型定义 │ └── drivers/ # 驱动层 │ └── mysql/ │ └── version/ │ └── v8/ # MySQL 8.0+ 驱动 │ ├── connection/ │ │ └── connection.go # 连接管理 │ ├── navigation/ │ │ ├── node.go # 节点操作 │ │ └── metadata.go # 元数据操作 │ └── operations/ │ ├── schema.go # 模式操作 │ ├── table.go # 表操作 │ ├── view.go # 视图操作 │ ├── index.go # 索引操作 │ ├── trigger.go # 触发器操作 │ └── object.go # 对象操作 ``` ### 文件职责说明 #### interface.go - 定义所有接口 - 遵循单一职责原则 - 通过组合构建复杂接口 #### meta/meta.go ```go // Node 树形结构节点 type Node struct { ID string // 唯一标识符 Type NodeType // 节点类型 Metadata *Metadata // 元数据 Children []*Node // 子节点 Loaded bool // 是否已加载 ParentID string // 父节点ID } // Metadata 节点元数据 type Metadata struct { Name string // 对象名称 Description string // 描述信息 Extra map[string]interface{} // 扩展属性 } ``` #### meta/types.go - 定义基础数据类型 - 包含查询、分页、事务等相关结构体 #### 驱动实现文件 - **connection.go**: 数据库连接和事务管理 - **node.go**: 节点树操作实现 - **metadata.go**: 元数据查询和搜索实现 - **schema.go**: 数据库模式操作实现 - **table.go**: 表和列操作实现 - **view.go**: 视图操作实现 - **index.go**: 索引操作实现 - **trigger.go**: 触发器操作实现 - **object.go**: 通用对象操作实现 ## 🛠️ 技术实现 ### 核心技术栈 - **Go 1.21+**: 后端实现语言 - **MySQL 8.0+**: 目标数据库 - **Wails**: 前端框架集成 - **database/sql**: Go标准数据库接口 ### 关键技术决策 #### 1. 懒加载实现 ```go // 节点按需加载,避免一次性加载大量数据 func (c *MySQLConnection) ListChildren(ctx context.Context, nodeID string, limit, offset int) ([]*meta.Node, error) { // 只加载当前页的数据 // 支持分页参数 limit 和 offset } ``` #### 2. 事务支持 ```go // 所有写操作都支持可选事务参数 func (c *MySQLConnection) CreateTable(ctx context.Context, schemaName string, metadata *meta.Metadata, tx ...types.Transaction) (*meta.Node, error) { if len(tx) > 0 { // 使用传入的事务 return c.createTableInTransaction(ctx, schemaName, metadata, tx[0]) } // 创建新事务 return c.createTableWithNewTransaction(ctx, schemaName, metadata) } ``` #### 3. 安全SQL执行 ```go // 使用参数化查询防止SQL注入 query := "SELECT * FROM information_schema.tables WHERE table_schema = ? AND table_name = ?" rows, err := c.db.QueryContext(ctx, query, schemaName, tableName) ``` #### 4. 统一的错误处理 ```go // 统一的错误返回模式 if err != nil { return nil, fmt.Errorf("操作失败: %w", err) } ``` ### 性能优化 #### 1. 连接池管理 ```go // 使用连接池提升性能 db, err := sql.Open("mysql", dsn) db.SetMaxOpenConns(10) db.SetMaxIdleConns(5) db.SetConnMaxLifetime(time.Hour) ``` #### 2. 查询优化 - 使用 INFORMATION_SCHEMA 进行元数据查询 - 支持分页避免大数据集 - 索引优化查询性能 #### 3. 内存管理 - 及时关闭数据库连接 - 合理使用 defer 释放资源 - 避免内存泄漏 ## 🔍 搜索功能 ### 搜索实现 ```go // 支持按关键字搜索不同类型的数据库对象 func (c *MySQLConnection) SearchNodes(ctx context.Context, keyword string, nodeType meta.NodeType, limit, offset int) ([]*meta.Node, error) { switch nodeType { case meta.NodeTypeSchema: return c.searchSchemas(ctx, keyword, limit, offset) case meta.NodeTypeTable: return c.searchTables(ctx, keyword, limit, offset) // ... 其他类型 } } ``` ### 搜索范围 - 数据库模式 (Schema) - 数据表 (Table) - 视图 (View) - 列 (Column) - 索引 (Index) - 触发器 (Trigger) ## 📊 分页支持 ### 分页实现 ```go // 所有列表操作都支持分页 func (c *MySQLConnection) ListTables(ctx context.Context, schemaName string, limit, offset int) ([]*meta.Node, error) { query := ` SELECT table_name, table_type, create_time FROM information_schema.tables WHERE table_schema = ? LIMIT ? OFFSET ? ` // 执行分页查询 } ``` ### 分页参数 - **limit**: 返回记录数量限制 - **offset**: 跳过记录数量 - 支持大数据集的高效分页 ## 🔐 事务管理 ### 事务接口 ```go type Transaction interface { Commit() error Rollback() error IsActive() bool } type TransactionManager interface { BeginTransaction(ctx context.Context, opts *types.TransactionOptions) (types.Transaction, error) ExecuteInTransaction(ctx context.Context, opts *types.TransactionOptions, fn func(txCtx context.Context) error) error } ``` ### 事务选项 ```go type TransactionOptions struct { IsolationLevel string // 隔离级别 ReadOnly bool // 只读事务 TimeoutSeconds int // 超时时间 } ``` ## 🎯 使用示例 ### 基本连接 ```go // 创建连接 conn := &v8.MySQLConnection{} // 连接数据库 config := map[string]interface{}{ "host": "localhost", "port": 3306, "username": "root", "password": "password", "database": "test", } err := conn.Connect(ctx, config) ``` ### 树形导航 ```go // 获取根节点 root, err := conn.GetRoot(ctx) // 获取子节点(支持分页) children, err := conn.GetChildren(ctx, "schema:test", 50, 0) // 获取特定节点 node, err := conn.GetNode(ctx, "table:test.users") ``` ### 搜索功能 ```go // 搜索表 tables, err := conn.SearchNodes(ctx, "user", meta.NodeTypeTable, 20, 0) // 搜索所有类型 all, err := conn.SearchNodes(ctx, "test", meta.NodeTypeAll, 50, 0) ``` ### CRUD 操作 ```go // 创建表 metadata := &meta.Metadata{ Name: "new_table", Extra: map[string]interface{}{ "columns": []map[string]interface{}{ {"name": "id", "type": "INT", "primary_key": true}, {"name": "name", "type": "VARCHAR(255)"}, }, }, } table, err := conn.CreateTable(ctx, "test", metadata) // 修改表 updates := map[string]interface{}{ "comment": "Updated table comment", } err = conn.AlterTable(ctx, "test", "new_table", updates) // 删除表 err = conn.DropTable(ctx, "test", "new_table") ``` ### 事务操作 ```go // 在事务中执行多个操作 err := conn.ExecuteInTransaction(ctx, nil, func(txCtx context.Context) error { // 创建表 _, err := conn.CreateTable(txCtx, "test", tableMetadata) if err != nil { return err } // 添加索引 _, err = conn.CreateIndex(txCtx, "test", "new_table", indexMetadata) if err != nil { return err } return nil }) ``` ## 🧪 测试策略 ### 单元测试 - 每个接口方法都有对应的单元测试 - 使用 mock 数据库连接进行测试 - 测试边界条件和错误处理 ### 集成测试 - 端到端的功能测试 - 实际数据库环境测试 - 性能测试和压力测试 ## 📈 性能指标 ### 查询性能 - 节点加载: < 100ms - 搜索响应: < 200ms - 分页查询: < 50ms ### 内存使用 - 连接池: 最大10个连接 - 查询缓存: LRU缓存策略 - 内存泄漏: 0 ### 并发处理 - 最大并发连接: 100 - 事务超时: 30秒 - 查询超时: 10秒 ## 🔄 扩展性设计 ### 新数据库支持 1. 实现 DatabaseProvider 接口 2. 添加对应的驱动实现 3. 注册到驱动工厂 ### 新功能扩展 1. 在相应接口中添加新方法 2. 实现具体驱动中的方法 3. 更新组合接口 ### 配置扩展 1. 支持多种数据库配置格式 2. 动态配置加载 3. 环境变量支持 ## 🚀 部署和运维 ### 环境要求 - Go 1.21+ - MySQL 8.0+ - 内存: 512MB+ - 磁盘: 1GB+ ### 配置管理 ```yaml database: host: localhost port: 3306 username: root password: password database: test max_open_conns: 10 max_idle_conns: 5 conn_max_lifetime: 1h ``` ### 监控指标 - 连接池状态 - 查询性能统计 - 错误率监控 - 内存使用情况 ## 📚 参考资料 ### 相关标准 - [Go Database/SQL](https://golang.org/pkg/database/sql/) - [MySQL INFORMATION_SCHEMA](https://dev.mysql.com/doc/refman/8.0/en/information-schema.html) - [DBeaver Architecture](https://dbeaver.com/docs/) ### 最佳实践 - [Go Interface Design](https://github.com/golang/go/wiki/CodeReviewComments#interfaces) - [Database Connection Pooling](https://github.com/golang/go/wiki/SQLInterface) - [Context Package](https://golang.org/pkg/context/) --- ## 📝 更新日志 ### v1.0.0 (2025-09-02) - ✅ 完成 MySQL v8 驱动完整实现 - ✅ 实现所有 Reader/Writer 接口 - ✅ 支持分页、搜索、事务功能 - ✅ 按照功能粒度重新组织文件结构 - ✅ 提供详细的文档和使用示例 ### 未来规划 - 🔄 支持更多数据库类型 (PostgreSQL, Oracle, SQL Server) - 🔄 添加缓存层提升性能 - 🔄 实现更丰富的元数据查询 - 🔄 支持数据库对象比较和同步 - 🔄 添加可视化监控界面 --- *本文档详细记录了 MySQL Database Directory Layer 的完整设计和实现方案,为后续开发和维护提供重要参考。* c:\Users\GTong\OneDrive\Code\Go\Work\wails\db_view\DESIGN_DOCUMENT.md