Back to directory

dsh-database-manager

Maintenance: Active

nabin-qq273274877/dsh-database-manager

A DSH Web GUI database management panel for SQLite, MySQL, and Redis, with approval-protected agent tools.

View on GitHub
$ dsh plugin add dsh-database-manager

Install

dsh has no central install command — add this plugin’s entry (documented in its README) to your profile or patch config, then restart.

How installs work

2

stars

1

forks

TypeScript

Language

MIT

License

2026-09-22

Created

2026-11-09

Last push

README

dsh-database-manager

License: MIT Node DSH

中文 | English

为 DeepSeek Harness Web GUI 提供数据库管理面板:侧边栏一个「数据库管理」入口,打开后统一管理 SQLite / MySQL / Redis,并提供一组受写保护闸门约束的 agent 工具。

不用离开 DSH,也不用另外打开一个数据库客户端:在同一个界面里查数据、改结构、跑 SQL、翻 Redis 键值。

数据源列表

目录

功能特性

数据源列表(面板首页)

  • 顶部工具条:左侧搜索(名称 / 主机 / 标签)+ 分组显示(不分组 / 按类型 / 按分组 / 按标签),右侧「新增数据库」
  • 列表列:数据库类型、名称、主机、用户、认证、标签、操作
  • 操作列:测试(连通性 + 延迟 + 服务端版本)、连接(进入对应数据库面板)、编辑、删除
  • 每个数据源带独立的只读标记与标签 / 分组,可运行时增删,不必改配置文件、不必重启

MySQL / SQLite 面板

左侧库 / 表树(搜索过滤、视图标记、行数),右侧六个标签页:

标签页 能做什么
浏览 分页与跳页、点列排序、按索引排序、列名下方显示列注释、分页行右侧显示表注释、双击单元格就地编辑、行编辑 / 复制到插入表单 / 删除、多选批量删除。也用于承载 SQL 查询的结果集
结构 改列 / 删列 / 新增列(与建表页同一套控件)、主键编辑、唯一约束、索引管理、非重复值计数;注释由右侧的注释列承载,鼠标悬停字段名也能看到全文(注释列在宽表上会被横向滚走);操作列固定在表格最右
SQL 编辑器,Ctrl+Enter 执行;SELECT 的结果落在浏览页
搜索 依例查询(QBE):每列一行,填了值的行才参与,条件之间是 AND
插入 按列类型给控件;「要插入的行数」可生成多组独立表单,整批一个事务提交
操作 移动表 / 表选项 / 复制表 / 表维护 / 删除数据或表

另有 导入导出:SQL 转储(结构 / 数据 / DROP 可选,整库或单表)与 CSV(当前表),均在浏览器侧完成;导出完成后面板会明确显示「导出完成:文件名(大小)」,浮窗里的主按钮也变成同一个完成态,旁边的再次导出用当前设置重跑。

点库名进入的表列表页顶部是两行常驻控件:数据库操作(导出整库 / 导入到本库 / SQL / 重命名 / 复制 / 字符集 / 删除数据库)与表过滤 + 新建表。这两行在表列表读出来之前就可点,读取状态只占下方的表区域;库表多时先出「只有名字」的列表,行数与大小随后补齐(补齐前显示 …,与引擎真的不提供行数时的「未知」区分开)。

库级 SQL(数据库操作行里的 SQL 按钮,phpMyAdmin 的库页同款)在一个整页编辑器里对本库执行语句,schema 随语句一起下发给宿主,不需要写 USE;CREATE TABLE、SHOW TABLES、ALTER DATABASE 这类对库而不是对表的语句就在这里跑(表级 SQL 标签页是从某张表进去的,建表语句原本无处可写)。结果集就地用同一张只读表格渲染,结果区长时自带纵向/横向滚动(不会被裁掉);有写入时自动重读表列表与统计。

Redis 面板

左侧目录树,右侧三个标签页:

  • 目录树:每个逻辑库(db0–db15)是一个根节点,key 按名字里的 : 分层折叠为目录,行尾显示该目录下的键数;顶部过滤框在已展开的层里匹配键名
  • 值:按类型渲染并可编辑——string 改值(保留 TTL)、list 按下标改 / 删 / 追加、set 增删成员、hash 逐字段改、zset 改分值与成员;stream 只读并说明原因
  • 服务信息:版本、内存、连接数、各库键数
  • 命令行:任意命令 + 回复,作用于当前选中的库

树上的写操作:目录行悬停出现 +(在该目录下新增键,前缀自动补上)与 🗑(删除整个目录);key 行悬停出现 🗑。TTL 可改可清(「设为永久」走 PERSIST,因为 EXPIRE key 0 会删掉整个键)。

大库可用性

按层加载 + 大库一次性建索引,使千万级 keyspace 也能浏览:

  • 小库(< 100 万键)逐层扫描:点开某个目录才扫该前缀,一次层级扫描同时得出子目录与每个子目录的精确键数。实测本机 Docker Redis 打开 26.5 万键库的根层 0.7–1.4 s,展开一个 20 万键的同层分支 1.0 s
  • 大库(≥ 100 万键)改为遍历一次、建全树、缓存:SCAN MATCH p:* 的成本 70% 花在把键名搬过网络(实测走 50 万键:返回键名 5.2 s,不返回 1.5 s),所以在服务端用 Lua 把键名折叠成「目录 → 计数」,网络开销基本归零(实测 1950 万键约 52 秒、传输约 0 KB)。Redis 单线程,脚本执行期间会阻塞其它客户端,因此脚本有界、由主机侧驱动游标分多次推进,批次大小按「单次阻塞几十毫秒」取
  • 大库直接开始建索引,边建边看,顶部有真实进度条(已扫描 X / Y,发现 N 个目录),不做前置确认框——这个操作是只读的、分批推进的,真正的备选方案只有「干脆不浏览这个库」
  • 不留漏目录的可能:索引是完整遍历而非采样。实测一个 1950 万键的库里存在只有 1 个键的目录(hyperf、shopadmin),采样会漏掉它们,而目录列表正是用户判断「库里有什么」的依据
  • 目录与计数从不撒谎:一层扫描一定跑到末尾,没有键数上限;目录总数超过索引上限(20 万)时报错而不是静默丢目录
  • 写入时只做局部更新(新增 / 删除键只改受影响的祖先与自身层级),不重扫全库

排序用的是不区分大小写的 code-unit 比较,不是 localeCompare。实测 20 万键:localeCompare 要 23.3 s,这个要 166 ms——这就是「能渲染」和「看起来卡死」的区别。

离开面板再回来,停在你刚才那一页

点会话行返回对话、再点侧边栏「数据库管理」进来,应该还是离开时的那张表、那个标签页。做不到的原因不在缓存,而在 React 的生命周期:shell 渲染 main 插槽时以「当前选中的面板 id」为 key,切回会话就会把整个面板组件卸载,面板里的 useState 随之全部销毁——再挂载时只剩「哪个数据源连着」还记得(那份状态本来就在插件控制器里),位置于是回到默认页。

现在位置记在插件控制器(src/client/controller.ts 的 memory(),按数据源 id 分开存),面板卸载不影响它:

  • 回来仍是同一个库、同一张表、同一个标签页;浏览页连页码、排序、筛选都在,树里展开的库也一并恢复
  • 两个 SQL 编辑框的草稿(表级 SQL 标签页、库级 SQL 页)一并保留,写了一半的语句不会因为回去看会话就没了
  • 写开关不保留:重进面板不会把「允许写入」自动恢复成开——那等于把一次授权变成永久授权
  • Redis 的树不自动重新展开:展开一个大库意味着重新扫描或重建索引,每次进面板都付一遍这个代价不可接受;选中的键和标签页会恢复

以「一次操作的结果落在哪里」为准则的几处取舍

只要产生结果集,结果一律落在浏览标签页。 SQL 与搜索两个标签页执行 SELECT 后都跳转到浏览标签页,而不是各自在下方渲染一张表:改动前两种做法各有各的表格,同一批行在不同标签页里长得不一样。

  • 写语句留在 SQL 页:INSERT/UPDATE/DDL 没有结果集可放进表格,而「已影响 N 行」正是用户要看的那句话;跳走等于把它藏起来
  • 结果集不假装成表:浏览工具条上的分页、按索引排序、导出/导入全部作用于表,而结果集没有表、没有主键、没有总行数,所以这些控件在结果集期间整块不出现,且结果集只读
  • 搜索把条件带到浏览页,于是结果集是真正的表读:可翻页、可按索引排序、有主键时还能直接编辑匹配行。浏览页顶部显示已应用的筛选条件并提供一键清除

插入页的「留空 / NULL / 空字符串」是三件不同的事,所以给了三个明确入口,而不是靠一个空文本框去猜:

操作 写进 SQL 的东西 结果
留空 该列不进 INSERT 引擎填它的 DEFAULT,没有 DEFAULT 则 NULL
勾 NULL 该列 = NULL 显式存 NULL(与留空不同:留空会用 DEFAULT)
勾空字符串 该列 = '' 只有 NOT NULL 且无默认值的文本列给这个勾

TINYINT 给的是自己填值的输入框,不是「是/否」下拉:BOOL、BOOLEAN 与 TINYINT(1) 在服务端是同一个类型(实测 information_schema.COLUMNS 对三种写法一律返回 tinyint(1)),给前两者两个选项就等于给后者也提供,而一个存着 2、3 或 -1 的 TINYINT(1) 根本填不进去。

无主键的表不提供行内编辑与批量删除:行由主键标识,没有主键的「删除这三行」说不清是哪三行。主键存在时批量删除走一次请求、一个事务。

引擎不支持的功能禁用并写明原因,而不是藏起来:藏起来会让按文档找过来的用户找不到控件。例如 SQLite 上没有可搬的目标库、没有忠实的复制表语句、没有可改的表选项、没有 REPAIR,这几块都渲染出来但禁用,理由写在块里。

大表上的两类危险操作会在按下去之前说清代价:需要整表重建的操作(SQLite 的改类型 / 删列 / 改主键)在确认框里写明「会新建表、搬数据、删旧表、改名,全程一个事务,大表需要时间」;数据库重命名会说明 MySQL 没有 RENAME DATABASE,实现是建库→搬表→删原库。

界面截图

数据源列表

数据源列表

统一管理三类数据源:类型、名称、主机、用户、认证方式、标签一屏可见,每行带测试 / 连接 / 编辑 / 删除。面板底部是写保护的两个策略开关。

数据库列表与库操作

数据库列表与库操作

左侧库 / 表树,右侧表列表与库操作(导出整库、导入到本库、库级 SQL、重命名、复制数据库、字符集、删除数据库、新建表)。库表多时先出列表、再补行数与大小,两行控件始终可点。

数据浏览

数据浏览

分页与跳页、按索引排序、双击单元格就地编辑,行尾是编辑 / 复制 / 删除。列注释显示在列名下方,表注释显示在分页行右侧。

表结构

表结构

列属性一屏可见(类型、可空、键、默认值、额外、非重复值计数、注释),鼠标悬停字段名即显示该列注释全文(注释列本身在宽表上会被横向滚走),操作列固定在表格最右;下方是索引区块。

数据插入

数据插入

Read the full README on GitHub →

DSH Plugins is an independent community directory of DeepSeek Harness plugins. Not affiliated with or endorsed by DeepSeek. Third-party plugins are not security-audited — review the source before installing.

New DeepSeek Harness plugins, weekly. No spam.