两个月做了个数据库统一搜索引擎,说说我的思路和踩过的坑
起因
去年底我入职了一家新公司。项目多、数据源杂——光 MySQL 实例就有七八个,加上 Redis 集群、Kafka 集群,后来又上了 PostgreSQL。
入职第一周,我大概花了一整天时间配置各种数据库客户端。Navicat 管 MySQL,Another Redis Desktop Manager 管 Redis,Offset Explorer 管 Kafka,DBeaver 管 PostgreSQL。四个工具、四套连接配置、四种界面风格。
最让我崩溃的不是工具多,而是找数据。
产品经理问「order_log 这个表在哪个库」,我得打开 Navicat 一个一个实例去翻。有时候翻遍了 MySQL 才发现这个表在 PostgreSQL 里。一天下来,光是在工具之间切换和找表就浪费了大量时间。
我心想,这都 2026 年了,为什么查个表名还得像在文件管理器里翻文件夹一样?
于是我开始做 DataWhere。
思路
传统数据库客户端的用法:选连接 → 选库 → 选表 → 看数据。你得先知道目标在哪。
但很多时候你就是不知道。你可能只记得一个关键词,比如「payment」「user_log」,但不确定它在哪个实例、哪个库,甚至不确定它在 MySQL 里还是 Redis 里。
DataWhere 就是让你直接搜。搜「payment」,结果里会列出:
- MySQL 生产环境 → payment_db → payments 表
- PostgreSQL → analytics → payment_monthly 视图
- Redis → db0 → payment:lock:order_123
- Kafka → payment-created-events topic
不用管它在哪,搜就完了。搜完如果是表则直接鼠标浮动展示DDL,点击直达工作台查询界面。
两个月做了什么
从 v1.0.5 到现在的 v1.1.3,主要经历了这些阶段:
第一阶段:验证核心假设(v1.0.5)
先实现 MySQL、Redis、Kafka 三种数据源,看看「统一搜索」这个方向能不能跑通。用 SQLite FTS5 做全文索引,搜索结果按匹配度排序,点搜索结果直接跳进工作台。
第二阶段:插件化重构(v1.1.0)
三种数据源的代码写完后,我发现每新增一种数据源要改的地方太多太散——模型定义、统计逻辑、搜索处理、前端类型……稍有不慎就会漏改。
于是我花了一周时间做了插件化架构重构:
// 之前:每新增一种数据源要改 N 个 match 分支
// 之后:连接器通过注册表管理
pub fn get_registered_connectors() -> HashMap<&'static str, ConnectorFactory> {
let mut map = HashMap::new();
map.insert("mysql", mysql::create_connector);
map.insert("redis", redis::create_connector);
map.insert("kafka", kafka::create_connector);
map.insert("postgresql", postgresql::create_connector);
map
}
主要的改动:DataSourceType 从封闭枚举改成了 open newtype string(pub struct DataSourceType(pub String)),新增数据源类型不需要改类型定义。同时定义了 DataSourceConnector trait,统一了连接测试、版本获取、元数据同步等接口。
现在接入新数据源大约只需要 12 处改动(后端 5 处 + 前端 7 处),模型定义、数据库 Schema、统计逻辑这些文件都不用动。
第三阶段:PostgreSQL 接入(v1.1.0 - v1.1.3)
PostgreSQL 是重构后的第一个验证对象。它和 MySQL 的元数据模型差异挺大,MySQL 是两级结构(实例→数据库→表),PostgreSQL 是三级(实例→数据库→Schema→表),中间多了一层。
碰到几个有意思的问题:
跨库独立连接。不同数据库可能属于不同用户、不同权限。连接器对每个数据库建立独立连接,避免权限交叉。查 postgres 库的 public schema 和查 app_db 的 business schema 互不干扰。
系统 Schema 过滤。PostgreSQL 有大量系统 Schema(pg_catalog、information_schema、pg_toast 等),同步时必须排除,否则索引体积会膨胀几十倍。
视图和物化视图。这是 v1.1.3 加的。工作台左侧目录树按「表 / 视图 / 物化视图」分类展示,点击视图自动生成 SELECT 查询,搜索也支持视图类型的跳转。
技术选型的一些考量
为什么选 Tauri 而不是 Electron
安装包大小。DataWhere 的 Windows 安装包约 6 MB,macOS 约 18 MB。同等功能的 Electron 应用至少 80 MB 起步。安装包小,用户试一下的意愿就高。
其次是内存占用。Tauri 的 webview 复用系统原生组件,空闲时内存占用大约是 Electron 的一半。数据库客户端经常要长时间挂在后台,这个差异很关键。
为什么 Rust 后端
数据库连接和元数据同步是 IO 密集型任务。Rust 的 tokio 异步运行时在这类场景下表现很好,配合 sqlx 的连接池,多个数据源并行同步时不会互相阻塞。
另外,Redis 的 redis-rs、Kafka 的 rskafka 都是纯 Rust 实现,不需要额外安装 C 依赖,对用户安装体验很友好——尤其是 Windows 用户,不用装 CMake 或者 Visual Studio Build Tools。
搜索引擎为什么选 SQLite FTS5
FTS5 是 SQLite 内置的全文检索引擎,不需要额外的服务进程。对于一个本地优先的桌面应用来说,这是最轻量的选择。搜索性能在万级别的元数据对象上完全够用,搜索延迟在毫秒级。
目前的功能全貌
经过两个月的迭代,DataWhere 现在能做什么:
| 功能 | 说明 |
|---|---|
| 统一搜索 | 一个搜索框检索所有已配置数据源的元数据 |
| MySQL 工作台 | 只读 SQL 查询、DDL 悬停查看、表结构/索引、结果导出 |
| PostgreSQL 工作台 | 只读 SQL 查询、Schema 切换、视图/物化视图、DDL 查看 |
| Redis 工作台 | Key 树形展示(按冒号分组)、全数据类型支持、分页加载 |
| Kafka 工作台 | Topic 浏览、按 Offset 拉取消息 |
| 环境管理 | 按环境分组管理数据源(开发/测试/生产) |
| 数据源导入导出 | 批量迁移数据源配置 |
| 跨平台 | Windows / macOS / Linux 全平台 |
| 多语言 | 中文 / 英文 |
| 暗色主题 | 支持 |
| 只读安全 | 所有工作台严格只读,可放心给非技术人员使用 |
支持的数据源版本:
| 数据源 | 支持版本 |
|---|---|
| MySQL | 5.6.x, 5.7.x, 8.0.x, 8.4.x |
| PostgreSQL | 12.x, 13.x, 14.x, 15.x, 16.x, 17.x |
| Redis | 5.x, 6.x, 7.x |
| Kafka | 2.8.x, 3.3.x, 3.6.x |
后面打算做什么
架构搭好之后,剩下的事情就是往里填数据源了。
下一步是 Oracle 和 SQL Server。企业环境这俩见得最多,尤其是金融和传统行业的公司,核心系统基本都跑在这上面。消息队列那边会加 RocketMQ 和 RabbitMQ,国内用 RocketMQ 的团队太多了,不加说不过去。Elasticsearch 也在计划里,很多人用它存日志和做全文检索,索引结构如果能和数据库表一起搜,覆盖面就广了。
搜索本身也会改进,现在只支持精确分词匹配,后面会加搜索历史和拼音模糊匹配。
另外有个想法还在琢磨——连接状态检测和响应时间统计。有些数据源偶尔会抽风,如果能提前感知到,排查问题能快不少。
官网www.opclite.com 免费下载使用,全平台支持。用着有什么问题随时反馈。