DESIGN_DOCUMENT.md 19 KB

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 - 节点读取接口

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 - 数据库模式读取接口

type SchemaReader interface {
    ListSchemas(ctx context.Context, limit, offset int) ([]*meta.Node, error)
    GetSchema(ctx context.Context, schemaName string) (*meta.Node, error)
}

TableReader - 表读取接口

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 - 视图读取接口

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 - 索引读取接口

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 - 触发器读取接口

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 - 元数据读取接口

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 - 节点写入接口

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 - 数据库模式写入接口

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 - 表写入接口

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 - 视图写入接口

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 - 列写入接口

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 - 索引写入接口

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 - 触发器写入接口

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 - 数据库读取接口

type DatabaseReader interface {
    NodeReader
    SchemaReader
    TableReader
    ViewReader
    IndexReader
    TriggerReader
    MetadataReader
}

DatabaseWriter - 数据库写入接口

type DatabaseWriter interface {
    NodeWriter
    SchemaWriter
    TableWriter
    ViewWriter
    ColumnWriter
    IndexWriter
    TriggerWriter
}

DatabaseProvider - 数据库提供者接口

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

// 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. 懒加载实现

// 节点按需加载,避免一次性加载大量数据
func (c *MySQLConnection) ListChildren(ctx context.Context, nodeID string, limit, offset int) ([]*meta.Node, error) {
    // 只加载当前页的数据
    // 支持分页参数 limit 和 offset
}

2. 事务支持

// 所有写操作都支持可选事务参数
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执行

// 使用参数化查询防止SQL注入
query := "SELECT * FROM information_schema.tables WHERE table_schema = ? AND table_name = ?"
rows, err := c.db.QueryContext(ctx, query, schemaName, tableName)

4. 统一的错误处理

// 统一的错误返回模式
if err != nil {
    return nil, fmt.Errorf("操作失败: %w", err)
}

性能优化

1. 连接池管理

// 使用连接池提升性能
db, err := sql.Open("mysql", dsn)
db.SetMaxOpenConns(10)
db.SetMaxIdleConns(5)
db.SetConnMaxLifetime(time.Hour)

2. 查询优化

  • 使用 INFORMATION_SCHEMA 进行元数据查询
  • 支持分页避免大数据集
  • 索引优化查询性能

3. 内存管理

  • 及时关闭数据库连接
  • 合理使用 defer 释放资源
  • 避免内存泄漏

🔍 搜索功能

搜索实现

// 支持按关键字搜索不同类型的数据库对象
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)

📊 分页支持

分页实现

// 所有列表操作都支持分页
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: 跳过记录数量
  • 支持大数据集的高效分页

🔐 事务管理

事务接口

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
}

事务选项

type TransactionOptions struct {
    IsolationLevel string // 隔离级别
    ReadOnly       bool   // 只读事务
    TimeoutSeconds int    // 超时时间
}

🎯 使用示例

基本连接

// 创建连接
conn := &v8.MySQLConnection{}

// 连接数据库
config := map[string]interface{}{
    "host":     "localhost",
    "port":     3306,
    "username": "root",
    "password": "password",
    "database": "test",
}
err := conn.Connect(ctx, config)

树形导航

// 获取根节点
root, err := conn.GetRoot(ctx)

// 获取子节点(支持分页)
children, err := conn.GetChildren(ctx, "schema:test", 50, 0)

// 获取特定节点
node, err := conn.GetNode(ctx, "table:test.users")

搜索功能

// 搜索表
tables, err := conn.SearchNodes(ctx, "user", meta.NodeTypeTable, 20, 0)

// 搜索所有类型
all, err := conn.SearchNodes(ctx, "test", meta.NodeTypeAll, 50, 0)

CRUD 操作

// 创建表
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")

事务操作

// 在事务中执行多个操作
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+

配置管理

database:
  host: localhost
  port: 3306
  username: root
  password: password
  database: test
  max_open_conns: 10
  max_idle_conns: 5
  conn_max_lifetime: 1h

监控指标

  • 连接池状态
  • 查询性能统计
  • 错误率监控
  • 内存使用情况

📚 参考资料

相关标准

最佳实践


📝 更新日志

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