两个月做了个数据库统一搜索引擎,说说我的思路和踩过的坑

0 阅读6分钟

两个月做了个数据库统一搜索引擎,说说我的思路和踩过的坑

起因

去年底我入职了一家新公司。项目多、数据源杂——光 MySQL 实例就有七八个,加上 Redis 集群、Kafka 集群,后来又上了 PostgreSQL。

入职第一周,我大概花了一整天时间配置各种数据库客户端。Navicat 管 MySQL,Another Redis Desktop Manager 管 Redis,Offset Explorer 管 Kafka,DBeaver 管 PostgreSQL。四个工具、四套连接配置、四种界面风格。

最让我崩溃的不是工具多,而是找数据

产品经理问「order_log 这个表在哪个库」,我得打开 Navicat 一个一个实例去翻。有时候翻遍了 MySQL 才发现这个表在 PostgreSQL 里。一天下来,光是在工具之间切换和找表就浪费了大量时间。

我心想,这都 2026 年了,为什么查个表名还得像在文件管理器里翻文件夹一样?

于是我开始做 DataWhere

image.png

思路

传统数据库客户端的用法:选连接 → 选库 → 选表 → 看数据。你得先知道目标在哪。

但很多时候你就是不知道。你可能只记得一个关键词,比如「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,点击直达工作台查询界面。

image.png

两个月做了什么

从 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→表),中间多了一层。

image.png

碰到几个有意思的问题:

跨库独立连接。不同数据库可能属于不同用户、不同权限。连接器对每个数据库建立独立连接,避免权限交叉。查 postgres 库的 public schema 和查 app_dbbusiness schema 互不干扰。

系统 Schema 过滤。PostgreSQL 有大量系统 Schema(pg_cataloginformation_schemapg_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 全平台
多语言中文 / 英文
暗色主题支持
只读安全所有工作台严格只读,可放心给非技术人员使用

支持的数据源版本:

数据源支持版本
MySQL5.6.x, 5.7.x, 8.0.x, 8.4.x
PostgreSQL12.x, 13.x, 14.x, 15.x, 16.x, 17.x
Redis5.x, 6.x, 7.x
Kafka2.8.x, 3.3.x, 3.6.x

后面打算做什么

架构搭好之后,剩下的事情就是往里填数据源了。

下一步是 Oracle 和 SQL Server。企业环境这俩见得最多,尤其是金融和传统行业的公司,核心系统基本都跑在这上面。消息队列那边会加 RocketMQ 和 RabbitMQ,国内用 RocketMQ 的团队太多了,不加说不过去。Elasticsearch 也在计划里,很多人用它存日志和做全文检索,索引结构如果能和数据库表一起搜,覆盖面就广了。

搜索本身也会改进,现在只支持精确分词匹配,后面会加搜索历史和拼音模糊匹配。

另外有个想法还在琢磨——连接状态检测和响应时间统计。有些数据源偶尔会抽风,如果能提前感知到,排查问题能快不少。

官网www.opclite.com 免费下载使用,全平台支持。用着有什么问题随时反馈。