- 拆分 FileSystem.vue 为模块化组件架构 - 新增 Markdown Mermaid 图表渲染支持 - 新增 180+ 编程语言代码高亮 - 修复编辑/预览模式切换渲染问题 - 优化亮色/暗色模式主题适配 - 新增 TypeScript 类型定义
749 lines
29 KiB
Markdown
749 lines
29 KiB
Markdown
# 表结构查看功能设计
|
||
|
||
**设计日期**:2026-01-28
|
||
**设计范围**:MySQL、Redis、MongoDB 表结构查看界面设计
|
||
**状态**:设计阶段
|
||
|
||
---
|
||
|
||
## 设计概览
|
||
|
||
表结构查看功能提供统一的界面查看不同数据库类型的结构信息,支持:
|
||
- **MySQL**:表字段详情、索引信息
|
||
- **MongoDB**:文档示例、字段统计、索引信息
|
||
- **Redis**:Key 类型、TTL、值预览、长度统计
|
||
|
||
**核心特性**:
|
||
- 统一的对话框界面
|
||
- 根据数据库类型自动适配展示内容
|
||
- 支持 Tab 切换不同信息视图
|
||
- 表格、JSON 等多种展示方式
|
||
- 响应式设计,适配不同屏幕尺寸
|
||
|
||
---
|
||
|
||
## 一、功能概述
|
||
|
||
表结构查看功能允许用户查看不同数据库类型的结构信息:
|
||
- **MySQL**:表字段信息、索引信息
|
||
- **MongoDB**:集合文档示例、字段统计、索引信息
|
||
- **Redis**:Key 类型、TTL、值预览、长度统计
|
||
|
||
---
|
||
|
||
## 二、界面设计
|
||
|
||
### 2.1 触发方式
|
||
|
||
#### 方式一:连接树右键菜单(推荐)
|
||
- 在连接树中,右键点击表/集合/Key节点
|
||
- 显示上下文菜单,包含"查看结构"选项
|
||
- 点击后在结果面板的"结构"Tab中展示
|
||
|
||
#### 方式二:连接树节点操作按钮
|
||
- 在表/集合/Key节点上悬停显示操作按钮
|
||
- 点击"结构"图标按钮,在结果面板展示
|
||
|
||
#### 方式三:双击节点
|
||
- 双击表/集合/Key节点,自动切换到"结构"Tab并加载结构信息
|
||
|
||
**推荐实现方式一**,用户体验最佳。
|
||
|
||
---
|
||
|
||
### 2.2 展示位置设计
|
||
|
||
#### 在结果面板中展示
|
||
表结构信息展示在现有的 `ResultPanel` 组件中,作为第三个 Tab:
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 结果面板 │
|
||
├─────────────────────────────────────────────────────────┤
|
||
│ [结果] [消息] [结构] │
|
||
├─────────────────────────────────────────────────────────┤
|
||
│ [查看模式] [编辑模式] [刷新] [导出] │
|
||
├─────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ [结构 Tab 内容区域] │
|
||
│ ┌─────────┬─────────┬─────────┐ │
|
||
│ │ 字段信息 │ 索引信息 │ 其他信息 │ │
|
||
│ └─────────┴─────────┴─────────┘ │
|
||
│ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
#### 模式切换
|
||
- **查看模式**(默认):只读展示,显示表结构信息
|
||
- **编辑模式**:可编辑模式,支持修改字段、添加/删除索引等操作
|
||
- **切换方式**:通过模式切换按钮或 Tab 切换
|
||
|
||
#### 展示区域属性
|
||
- **位置**:结果面板(`ResultPanel`)的第三个 Tab
|
||
- **Tab 标题**:根据数据库类型显示
|
||
- MySQL: `结构 - ${database}.${table}`
|
||
- MongoDB: `结构 - ${database}.${collection}`
|
||
- Redis: `结构 - ${key}`
|
||
- **高度**:跟随结果面板高度(可调整,默认 300px)
|
||
- **滚动**:内容超出时自动滚动
|
||
|
||
#### 优势
|
||
- ✅ 无需弹出窗口,界面更简洁
|
||
- ✅ 与查询结果、消息在同一区域,操作连贯
|
||
- ✅ 可以同时查看结构信息和查询结果
|
||
- ✅ 符合现有架构,无需新增组件
|
||
|
||
---
|
||
|
||
### 2.3 内容展示设计
|
||
|
||
#### MySQL 表结构
|
||
|
||
**Tab 1: 字段信息**
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 字段名 │ 类型 │ 是否NULL │ 键 │ 默认值 │ 额外信息 │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ id │ int(11) │ NO │ PRI │ NULL │ auto_inc │
|
||
│ name │ varchar(50) │ YES │ │ NULL │ │
|
||
│ email │ varchar(100)│ NO │ UNI │ NULL │ │
|
||
│ created_at│ datetime │ NO │ │ NULL │ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**字段说明**:
|
||
- **字段名**:列名
|
||
- **类型**:数据类型(int, varchar, text, datetime 等)
|
||
- **是否NULL**:YES/NO
|
||
- **键**:PRI(主键)、UNI(唯一键)、MUL(多键)
|
||
- **默认值**:默认值或 NULL
|
||
- **额外信息**:auto_increment、on update 等
|
||
|
||
**Tab 2: 索引信息**
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 索引名 │ 唯一 │ 字段 │ 排序 │ 索引类型 │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ PRIMARY │ 是 │ id │ ASC │ BTREE │
|
||
│ idx_email │ 是 │ email │ ASC │ BTREE │
|
||
│ idx_name │ 否 │ name │ ASC │ BTREE │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**字段说明**:
|
||
- **索引名**:索引名称
|
||
- **唯一**:是/否
|
||
- **字段**:索引字段(可能有多个,用逗号分隔)
|
||
- **排序**:ASC/DESC
|
||
- **索引类型**:BTREE、HASH 等
|
||
|
||
---
|
||
|
||
#### MongoDB 集合结构
|
||
|
||
**Tab 1: 文档示例**
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 文档 1 │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ { │
|
||
│ "_id": ObjectId("..."), │
|
||
│ "name": "John", │
|
||
│ "email": "john@example.com", │
|
||
│ "age": 30, │
|
||
│ "created_at": ISODate("2026-01-01T00:00:00Z") │
|
||
│ } │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
[显示最多 5 个文档示例,JSON 格式,可折叠展开]
|
||
```
|
||
|
||
**Tab 2: 字段统计**
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 字段名 │ 出现次数 │ 占比 │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ _id │ 5 │ 100% (基于5个文档示例) │
|
||
│ name │ 5 │ 100% │
|
||
│ email │ 4 │ 80% │
|
||
│ age │ 3 │ 60% │
|
||
│ created_at │ 2 │ 40% │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
|
||
文档总数: 1000
|
||
⚠️ 字段统计基于文档示例(最多5个),仅供参考
|
||
```
|
||
|
||
**性能分析与优化建议**:
|
||
|
||
#### 当前实现分析
|
||
|
||
1. **字段统计**(当前实现):
|
||
- **查询方式**:基于文档示例(最多5个)进行统计
|
||
- **性能影响**:✅ **低** - 只查询5个文档,几乎无性能影响
|
||
- **准确性**:⚠️ **不准确** - 仅基于5个文档,不能代表全表字段分布
|
||
- **适用场景**:快速预览,了解集合可能包含的字段
|
||
|
||
2. **文档总数**(当前实现):
|
||
- **查询方式**:`CountDocuments({})` - 全表扫描
|
||
- **性能影响**:⚠️ **中等** - 大数据集(百万级+)可能较慢
|
||
- **优化建议**:使用 `estimatedDocumentCount()` 获取估算值(更快)
|
||
|
||
#### 优化方案
|
||
|
||
**方案一:保持当前实现(推荐)**
|
||
- ✅ **优点**:性能好,响应快
|
||
- ⚠️ **缺点**:字段统计不准确
|
||
- **适用**:快速预览场景,不需要精确统计
|
||
|
||
**方案二:采样统计(已确定采用)** ✅ 默认采样 10个文档
|
||
- 使用 `$sample` 聚合管道随机采样10个文档进行统计
|
||
- **性能影响**:✅ **低** - 采样10个文档,性能良好
|
||
- **准确性**:✅ **适中** - 比5个文档更准确,比全表扫描性能更好
|
||
- **实现方式**:使用 MongoDB `$sample` 聚合管道(已实现)
|
||
- **异步加载**:✅ 全异步执行,不阻塞主流程
|
||
- **前端展示**:✅ 显示"基于10个文档采样统计,仅供参考"
|
||
- **未来扩展**:支持可配置采样数量(P2)
|
||
|
||
**方案三:全表统计(不推荐)**
|
||
- 扫描所有文档统计字段
|
||
- **性能影响**:❌ **高** - 大数据集可能非常慢
|
||
- **适用**:小数据集(< 10万文档)
|
||
|
||
#### 推荐实现
|
||
|
||
```go
|
||
// 方案一:保持当前实现(快速预览)
|
||
// 字段统计基于文档示例(5个),性能好但准确性低
|
||
fieldStats := make(map[string]int)
|
||
for _, doc := range sampleDocs { // 5个文档
|
||
for key := range doc {
|
||
fieldStats[key]++
|
||
}
|
||
}
|
||
|
||
// 方案二:采样统计(可选,通过参数控制)
|
||
// 如果用户需要更准确的统计,可以采样更多文档
|
||
if needAccurateStats {
|
||
pipeline := []bson.M{
|
||
{"$sample": bson.M{"size": 1000}}, // 采样1000个文档
|
||
{"$project": bson.M{"keys": bson.M{"$objectToArray": "$$ROOT"}}},
|
||
{"$unwind": "$keys"},
|
||
{"$group": bson.M{
|
||
"_id": "$keys.k",
|
||
"count": bson.M{"$sum": 1},
|
||
}},
|
||
}
|
||
// 执行聚合查询...
|
||
}
|
||
```
|
||
|
||
#### 前端展示建议
|
||
|
||
1. **明确标注**:字段统计显示"基于X个文档示例,仅供参考"
|
||
2. **可选刷新**:提供"精确统计"按钮,用户需要时再执行采样统计
|
||
3. **性能提示**:大数据集时提示"精确统计可能较慢"
|
||
4. **缓存策略**:字段统计结果缓存5-10分钟,避免重复查询
|
||
|
||
#### 最终建议(已确定)
|
||
|
||
- **默认实现**:✅ 使用采样统计,默认采样10个文档(性能好,准确性适中)
|
||
- **文档总数**:✅ 使用 `estimatedDocumentCount()` 替代 `CountDocuments()` 提升性能
|
||
- **前端展示**:明确标注"基于10个文档采样统计,仅供参考"
|
||
- **后续优化**:可考虑提供"精确统计"按钮,采样更多文档(100-1000个),作为P2功能
|
||
|
||
**Tab 3: 索引信息**
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 索引名 │ 唯一 │ 键定义 │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ _id_ │ 是 │ {"_id": 1} │
|
||
│ idx_email │ 是 │ {"email": 1} │
|
||
│ idx_name │ 否 │ {"name": 1, "age": -1} │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
#### Redis Key 信息
|
||
|
||
**单页展示(无 Tab)**
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Key 信息 │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ Key 名称: user:1001 │
|
||
│ Key 类型: hash │
|
||
│ TTL: 3600 秒 (1 小时) │
|
||
│ 长度: 5 个字段 │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ 值预览: │
|
||
│ { │
|
||
│ "name": "John", │
|
||
│ "email": "john@example.com", │
|
||
│ "age": "30" │
|
||
│ } │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**字段说明**:
|
||
- **Key 名称**:完整的 Key 名称
|
||
- **Key 类型**:string、hash、list、set、zset 等
|
||
- **TTL**:过期时间(秒),-1 表示永不过期,-2 表示 Key 不存在
|
||
- **长度**:根据类型显示(string=字符数,hash/list/set/zset=元素数)
|
||
- **值预览**:限制显示前 200 字符,过长时显示省略号
|
||
|
||
---
|
||
|
||
## 三、组件设计
|
||
|
||
### 3.1 组件结构
|
||
|
||
```
|
||
ResultPanel.vue (现有组件,扩展)
|
||
└── 新增 "结构" Tab
|
||
├── StructureContent.vue (结构内容组件)
|
||
│ ├── 模式切换(查看/编辑)
|
||
│ ├── MySQLStructure.vue (MySQL 专用)
|
||
│ │ ├── ViewMode.vue (查看模式)
|
||
│ │ │ ├── FieldsTab.vue (字段信息子Tab)
|
||
│ │ │ └── IndexesTab.vue (索引信息子Tab)
|
||
│ │ └── EditMode.vue (编辑模式)
|
||
│ │ ├── FieldsEditor.vue (字段编辑表格)
|
||
│ │ ├── IndexesEditor.vue (索引编辑表格)
|
||
│ │ └── EditToolbar.vue (保存/取消按钮)
|
||
│ ├── MongoStructure.vue (MongoDB 专用)
|
||
│ │ ├── ViewMode.vue (查看模式)
|
||
│ │ │ ├── SampleDocsTab.vue (文档示例子Tab)
|
||
│ │ │ ├── FieldStatsTab.vue (字段统计子Tab)
|
||
│ │ │ └── IndexesTab.vue (索引信息子Tab)
|
||
│ │ └── EditMode.vue (编辑模式)
|
||
│ │ └── IndexesEditor.vue (索引编辑,MongoDB不支持字段编辑)
|
||
│ └── RedisStructure.vue (Redis 专用,仅查看模式)
|
||
└── 状态管理(通过 composable)
|
||
```
|
||
|
||
### 3.2 组件接口
|
||
|
||
#### ResultPanel.vue Props(扩展)
|
||
```typescript
|
||
interface Props {
|
||
// ... 现有 props
|
||
structureData?: {
|
||
connectionId: number
|
||
database: string
|
||
tableName: string
|
||
dbType: 'mysql' | 'mongo' | 'redis'
|
||
} | null // 表结构数据,null 表示不显示结构Tab
|
||
}
|
||
```
|
||
|
||
#### 新增 Composable: useStructureState.ts
|
||
```typescript
|
||
export function useStructureState() {
|
||
const structureLoading = ref(false)
|
||
const structureError = ref('')
|
||
const structureData = ref<any>(null)
|
||
const structureInfo = ref<{
|
||
connectionId: number
|
||
database: string
|
||
tableName: string
|
||
dbType: 'mysql' | 'mongo' | 'redis'
|
||
} | null>(null)
|
||
|
||
// 编辑模式相关
|
||
const editMode = ref<'view' | 'edit'>('view')
|
||
const editData = ref<any>(null) // 编辑中的数据(用于撤销)
|
||
const hasChanges = ref(false) // 是否有未保存的修改
|
||
|
||
const loadStructure = async (connectionId, database, tableName, dbType) => {
|
||
// 加载表结构数据
|
||
}
|
||
|
||
const clearStructure = () => {
|
||
structureData.value = null
|
||
structureInfo.value = null
|
||
editMode.value = 'view'
|
||
editData.value = null
|
||
hasChanges.value = false
|
||
}
|
||
|
||
const switchToEditMode = () => {
|
||
// 切换到编辑模式,复制数据到 editData
|
||
editData.value = JSON.parse(JSON.stringify(structureData.value))
|
||
editMode.value = 'edit'
|
||
hasChanges.value = false
|
||
}
|
||
|
||
const switchToViewMode = () => {
|
||
// 切换到查看模式
|
||
editMode.value = 'view'
|
||
editData.value = null
|
||
hasChanges.value = false
|
||
}
|
||
|
||
const saveStructure = async () => {
|
||
// 保存结构修改,生成 ALTER TABLE 语句并执行
|
||
}
|
||
|
||
return {
|
||
structureLoading,
|
||
structureError,
|
||
structureData,
|
||
structureInfo,
|
||
editMode,
|
||
editData,
|
||
hasChanges,
|
||
loadStructure,
|
||
clearStructure,
|
||
switchToEditMode,
|
||
switchToViewMode,
|
||
saveStructure
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 四、数据流程
|
||
|
||
### 4.1 数据获取流程
|
||
|
||
```
|
||
用户触发查看结构(右键菜单/操作按钮)
|
||
↓
|
||
ConnectionTree 触发 'table-structure' 事件
|
||
↓
|
||
index.vue 接收事件,调用 useStructureState.loadStructure()
|
||
↓
|
||
根据 connectionId 获取连接信息(确定 dbType)
|
||
↓
|
||
调用 GetTableStructure API
|
||
↓
|
||
后端根据 dbType 分发:
|
||
- MySQL → GetTableStructure (DESCRIBE 查询)
|
||
- MongoDB → GetCollectionStructure (文档分析)
|
||
- Redis → GetKeyInfo (命令查询)
|
||
↓
|
||
返回结构数据
|
||
↓
|
||
更新 structureData 和 structureInfo
|
||
↓
|
||
ResultPanel 检测到 structureInfo 不为空,显示"结构"Tab
|
||
↓
|
||
StructureContent 根据 dbType 渲染对应组件
|
||
```
|
||
|
||
### 4.2 API 调用
|
||
|
||
```typescript
|
||
// 获取表结构
|
||
const result = await window.go.main.App.GetTableStructure(
|
||
connectionId,
|
||
database,
|
||
tableName
|
||
)
|
||
|
||
// 返回数据结构
|
||
// MySQL:
|
||
{
|
||
type: 'mysql',
|
||
database: 'test',
|
||
table: 'users',
|
||
columns: [...], // 字段信息数组
|
||
}
|
||
|
||
// MongoDB:
|
||
{
|
||
type: 'mongo',
|
||
database: 'test',
|
||
collection: 'users',
|
||
structure: {
|
||
sampleDocs: [...], // 文档示例
|
||
fieldStats: {...}, // 字段统计
|
||
indexes: [...], // 索引信息
|
||
documentCount: 1000 // 文档总数
|
||
}
|
||
}
|
||
|
||
// Redis:
|
||
{
|
||
type: 'redis',
|
||
key: 'user:1001',
|
||
info: {
|
||
type: 'hash',
|
||
ttl: 3600,
|
||
length: 5,
|
||
value: {...} // 值预览
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 五、实现细节
|
||
|
||
### 5.1 表格展示
|
||
|
||
#### 使用 Arco Design Table 组件
|
||
- **分页**:字段/索引较多时,使用分页(每页 20 条)
|
||
- **排序**:支持按字段名、类型等排序
|
||
- **搜索**:字段信息表格支持搜索字段名
|
||
- **固定列**:字段名列固定,方便横向滚动查看
|
||
|
||
#### 样式优化
|
||
- **字体**:使用等宽字体显示类型信息
|
||
- **颜色**:主键字段用特殊颜色标识,NULL 字段用灰色
|
||
- **宽度**:列宽自适应,最小宽度 100px
|
||
|
||
### 5.2 JSON 展示
|
||
|
||
#### MongoDB 文档示例、Redis 值预览
|
||
- 使用 `<pre>` 标签展示格式化的 JSON
|
||
- 支持折叠/展开(使用 `a-collapse` 组件)
|
||
- 长文本自动换行,限制最大高度,超出部分滚动
|
||
- 支持复制功能(点击复制按钮)
|
||
|
||
### 5.3 加载状态
|
||
|
||
- **加载中**:显示 Spin 组件和"加载中..."提示
|
||
- **加载失败**:显示错误提示,提供重试按钮
|
||
- **空数据**:显示空状态提示
|
||
|
||
### 5.4 响应式设计
|
||
|
||
- **小屏幕**:对话框宽度自适应,最小 600px
|
||
- **表格**:横向滚动,固定关键列
|
||
- **Tab**:内容过多时,Tab 可滚动
|
||
|
||
---
|
||
|
||
## 六、交互设计
|
||
|
||
### 6.1 触发查看结构
|
||
|
||
1. **从连接树触发**:
|
||
- 右键菜单 → "查看结构"
|
||
- 或点击节点操作按钮
|
||
- 或双击节点
|
||
|
||
2. **参数传递**:
|
||
- 从节点数据获取 `connectionId`、`database`、`tableName`、`dbType`
|
||
- 通过事件传递给 `index.vue`
|
||
- `index.vue` 调用 `useStructureState.loadStructure()`
|
||
|
||
3. **Tab 切换**:
|
||
- 自动切换到结果面板的"结构"Tab
|
||
- 如果结果面板隐藏,自动显示
|
||
|
||
### 6.2 结构Tab操作
|
||
|
||
- **切换Tab**:点击"结构"Tab查看,点击其他Tab返回
|
||
- **刷新**:在结构Tab中添加刷新按钮,重新加载结构数据
|
||
- **复制**:字段信息、索引信息支持复制(选中文本或复制按钮)
|
||
- **关闭**:切换到其他Tab或清空结构数据
|
||
|
||
### 6.3 数据更新
|
||
|
||
- **自动加载**:触发查看结构时自动加载数据
|
||
- **手动刷新**:在结构Tab中提供刷新按钮
|
||
- **错误重试**:加载失败时显示错误提示和重试按钮
|
||
- **清空数据**:切换连接或执行SQL时自动清空结构数据
|
||
|
||
---
|
||
|
||
## 七、技术实现要点
|
||
|
||
### 7.1 组件拆分
|
||
|
||
- **扩展组件**:`ResultPanel.vue` 添加"结构"Tab
|
||
- **内容组件**:`StructureContent.vue` 负责根据 `dbType` 路由到对应组件
|
||
- **专用组件**:`MySQLStructure.vue`、`MongoStructure.vue`、`RedisStructure.vue`
|
||
- **复用组件**:`IndexesTab.vue` 可被 MySQL 和 MongoDB 复用(需适配数据格式)
|
||
- **状态管理**:`useStructureState.ts` composable 管理结构数据状态
|
||
|
||
### 7.2 数据格式化
|
||
|
||
- **MySQL 字段类型**:保持原样显示(如 `int(11)`、`varchar(50)`)
|
||
- **MongoDB 文档**:BSON 转换为 JSON 格式显示
|
||
- **Redis 值**:根据类型格式化(string 直接显示,hash 显示为对象)
|
||
|
||
### 7.3 性能优化
|
||
|
||
- **懒加载**:结构Tab切换时才加载对应内容(使用 `v-if`)
|
||
- **数据缓存**:同一表结构数据缓存 5 分钟,避免重复请求
|
||
- **分页加载**:字段/索引较多时使用分页,避免一次性加载过多数据
|
||
- **按需渲染**:只有在 structureInfo 不为空时才渲染结构Tab
|
||
|
||
---
|
||
|
||
## 八、扩展功能(可选)
|
||
|
||
### 8.1 导出功能
|
||
|
||
- **导出为 SQL**:MySQL 表结构导出为 CREATE TABLE 语句
|
||
- **导出为 JSON**:MongoDB 集合结构导出为 JSON Schema
|
||
- **导出为文本**:所有类型支持导出为文本格式
|
||
|
||
### 8.2 编辑功能(融入查看区域)
|
||
|
||
#### 设计原则
|
||
- ✅ **融入查看区域**:编辑功能直接在结构查看 Tab 中实现,通过模式切换
|
||
- ✅ **统一界面**:查看和编辑使用相同的布局和组件,减少界面切换
|
||
- ✅ **权限检查**:编辑前检查用户权限(ALTER TABLE、CREATE INDEX 等)
|
||
- ✅ **操作确认**:结构修改是危险操作,需要确认对话框
|
||
|
||
#### 编辑模式设计
|
||
|
||
**模式切换**:
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 结构 - database.table [查看] [编辑] │
|
||
├─────────────────────────────────────────────────────────┤
|
||
│ [字段信息] [索引信息] │
|
||
├─────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ [编辑模式内容] │
|
||
│ - 可编辑表格(字段信息) │
|
||
│ - 添加字段按钮 │
|
||
│ - 删除字段按钮 │
|
||
│ - 保存/取消按钮 │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**编辑功能**:
|
||
- **MySQL**:
|
||
- 修改字段:类型、是否NULL、默认值、注释
|
||
- 添加字段:在指定位置添加新字段
|
||
- 删除字段:删除不需要的字段(需确认)
|
||
- 修改索引:添加/删除索引
|
||
- **MongoDB**:
|
||
- 添加索引:创建新索引
|
||
- 删除索引:删除不需要的索引(需确认)
|
||
- 注意:MongoDB 字段是动态的,不支持字段编辑
|
||
- **Redis**:
|
||
- 不支持编辑(Redis 是键值存储,无结构概念)
|
||
|
||
#### 实现方式
|
||
|
||
**方式一:Tab 切换(推荐)**
|
||
- 在结构 Tab 内部使用子 Tab 切换查看/编辑模式
|
||
- 查看 Tab:只读展示
|
||
- 编辑 Tab:可编辑表格,带保存/取消按钮
|
||
|
||
**方式二:按钮切换**
|
||
- 在结构 Tab 顶部添加"编辑"按钮
|
||
- 点击后切换到编辑模式,按钮变为"查看"
|
||
- 编辑模式下显示保存/取消按钮
|
||
|
||
**推荐使用方式一**,界面更清晰,模式切换更明显。
|
||
|
||
#### 编辑操作流程
|
||
|
||
```
|
||
用户点击"编辑"Tab/按钮
|
||
↓
|
||
检查权限(ALTER TABLE、CREATE INDEX)
|
||
↓
|
||
加载当前结构数据到编辑表格
|
||
↓
|
||
用户修改字段/索引
|
||
↓
|
||
点击"保存"按钮
|
||
↓
|
||
生成 ALTER TABLE 语句
|
||
↓
|
||
显示确认对话框(显示将要执行的 SQL)
|
||
↓
|
||
用户确认
|
||
↓
|
||
执行 ALTER TABLE 语句
|
||
↓
|
||
刷新结构数据
|
||
↓
|
||
切换回查看模式
|
||
```
|
||
|
||
#### 安全措施
|
||
|
||
1. **权限检查**:编辑前检查数据库用户权限
|
||
2. **确认对话框**:显示将要执行的 SQL,用户必须确认
|
||
3. **操作日志**:记录所有结构修改操作
|
||
4. **撤销功能**:支持撤销最近一次修改(可选,P2)
|
||
5. **备份提示**:重要表修改前提示备份(可选,P2)
|
||
|
||
### 8.3 对比功能
|
||
|
||
- **结构对比**:对比两个表的结构差异
|
||
- **版本历史**:记录表结构变更历史(需要额外存储)
|
||
|
||
---
|
||
|
||
## 九、实现优先级
|
||
|
||
### P0(必须实现)
|
||
1. ✅ 在 ResultPanel 中添加"结构"Tab
|
||
2. ✅ useStructureState composable 实现
|
||
3. ✅ MySQL 字段信息展示
|
||
4. ✅ MySQL 索引信息展示
|
||
5. ✅ MongoDB 文档示例展示
|
||
6. ✅ MongoDB 字段统计展示
|
||
7. ✅ Redis Key 信息展示
|
||
8. ✅ 连接树右键菜单触发
|
||
|
||
### P0.5(查看功能完成后实现)
|
||
1. 查看/编辑模式切换
|
||
2. MySQL 字段编辑(修改类型、NULL、默认值)
|
||
3. MySQL 索引编辑(添加/删除索引)
|
||
4. MongoDB 索引编辑(添加/删除索引)
|
||
5. 权限检查
|
||
6. 确认对话框
|
||
|
||
### P1(重要功能)
|
||
1. 数据加载状态和错误处理
|
||
2. JSON 格式化显示
|
||
3. 表格搜索和排序
|
||
4. 自动切换到结构Tab
|
||
5. 清空结构数据逻辑(切换连接、执行SQL时)
|
||
|
||
### P2(优化功能)
|
||
1. 数据缓存
|
||
2. 复制功能
|
||
3. 导出功能
|
||
4. 响应式优化
|
||
5. 编辑模式撤销/重做
|
||
6. 修改前备份提示
|
||
|
||
---
|
||
|
||
## 十、总结
|
||
|
||
表结构查看功能设计遵循以下原则:
|
||
|
||
1. **统一接口**:不同数据库类型使用相同的触发方式和展示框架
|
||
2. **差异化展示**:根据数据库类型展示对应的结构信息
|
||
3. **集成设计**:在结果面板中展示,无需弹出窗口,界面更简洁
|
||
4. **用户体验**:提供清晰的表格展示、JSON 格式化、搜索排序等功能
|
||
5. **性能优化**:懒加载、数据缓存、分页等优化措施
|
||
6. **可扩展性**:组件化设计,便于后续添加新功能
|
||
|
||
### 设计优势
|
||
|
||
- ✅ **无需弹出窗口**:在结果面板中展示,界面更简洁
|
||
- ✅ **操作连贯**:与查询结果、消息在同一区域,切换方便
|
||
- ✅ **符合现有架构**:扩展 ResultPanel 组件,无需新增复杂组件
|
||
- ✅ **状态管理清晰**:使用 composable 管理结构数据,易于维护
|
||
- ✅ **查看编辑融合**:编辑功能融入查看区域,通过模式切换,无需额外界面
|
||
- ✅ **统一体验**:查看和编辑使用相同布局,降低学习成本
|
||
|
||
### 编辑功能融入优势
|
||
|
||
- ✅ **无缝切换**:查看和编辑在同一区域,切换流畅
|
||
- ✅ **上下文保持**:编辑时可以看到原始结构,便于对比
|
||
- ✅ **操作连贯**:查看 → 编辑 → 保存 → 查看,流程顺畅
|
||
- ✅ **界面简洁**:不需要额外的编辑窗口或页面
|
||
|
||
通过以上设计,可以实现一个功能完善、用户体验良好的表结构查看和编辑功能。
|
||
|