# 告别繁琐,一个平台搞定所有数据库查询——dbquery 深度介绍
> 运维和开发同学的日常:手边同时开着 Navicat、DBeaver、Redis Desktop Manager 和 MongoDB Compass,切来切去;想让测试同学查一个线上表,却不敢直接给数据库密码;新人入职要配置一堆客户端工具……这些痛点,dbquery 一次解决。
---
## 一、项目简介
**dbquery** 是一个基于 Django 4.2 + Bootstrap 5 构建的轻量级数据库运维查询平台。它运行在浏览器里,无需安装任何客户端,支持 **MySQL、TiDB、PostgreSQL、Redis、MongoDB** 五种主流数据库,并内置完整的用户权限体系,让 DBA、开发、测试各司其职,安全地共用同一套工具。
一条 `docker-compose up -d` 命令即可启动,5 分钟上线。
> GitHub:[https://github.com/kisen9102-lgtm/dbquery](https://github.com/kisen9102-lgtm/dbquery)
---
## 二、核心功能
### 1. 跨实例数据库查询
不记得某个数据库在哪台机器上?在搜索框输入数据库名,系统自动扫描所有已注册实例,返回匹配的数据库名、所在实例、表数量、大小、数据库类型等信息,一张表格全览。
也可以直接输入 IP + 端口,查看该实例上所有数据库的概览。
### 2. 在线 SQL 编辑器
打开 SQL 查询页面,选择实例和数据库,即可开始查询。
- **语法高亮**:MySQL/TiDB/PostgreSQL 使用 SQL 模式,Redis/MongoDB 使用纯文本模式,输入提示符自动切换
- **对象浏览器**:左侧面板展示当前数据库的所有表(MySQL/PG)或集合(MongoDB),点击即可插入表名
- **多语句执行**:一次提交多条 SQL,每条语句分别返回结果集
- **结果导出**:结果可一键导出为 CSV 文件
- **行数限制**:超出限制自动截断并提示,防止意外拖垮数据库
- **左上角类型标签**:当前连接的数据库类型(MySQL / TiDB / PostgreSQL / Redis / MongoDB)实时显示,一眼知晓操作的是哪种数据库
**Redis 支持的命令**(只读白名单):
```
GET MGET KEYS SCAN TYPE TTL PTTL EXISTS STRLEN GETRANGE
INFO DBSIZE TIME HGET HGETALL HMGET HKEYS HVALS HLEN
LRANGE LLEN LINDEX SCARD SMEMBERS SRANDMEMBER SISMEMBER
ZRANGE ZRANGEBYSCORE ZREVRANGE ZCARD ZSCORE ZRANK
```
**MongoDB 支持的查询语法**:
```
db.<集合>.find({"字段": "值"})
db.<集合>.count_documents({"字段": "值"})
db.<集合>.aggregate([{"$match": {...}}, {"$group": {...}}])
```
### 3. 实例管理
在实例管理页面可以注册、编辑、删除各类数据库实例:
- 支持设置实例名、IP、端口、环境(测试/生产/开发)、数据库类型
- Redis / MongoDB 支持独立凭据(用户名、密码、authSource),MySQL / TiDB / PostgreSQL 使用统一的服务账号
- 每个实例都有「测试连接」按钮,注册时即可验证连通性
- 不同类型用彩色标签区分(MySQL 蓝、TiDB 青、PostgreSQL 深蓝、Redis 红、MongoDB 绿)
### 4. 用户管理与权限控制
三级角色体系,精准管控访问范围:
| 角色 | 能做什么 | 限制 |
|------|---------|------|
| **root** | 全部操作,不受限制 | — |
| **admin** | 管理实例、用户、用户组 | 不可修改 root 账号 |
| **query** | 执行只读查询 | 只能看所属用户组的实例;**看不到实例 IP/端口**;禁止查询系统库;只能执行 SELECT |
query 用户在 SQL 编辑器里看到的实例列表,只有被授权的那几个,连 IP 地址都看不到,彻底避免敏感信息泄露。
### 5. 用户组管理
创建用户组,把若干实例和若干 query 用户绑定进去。用户组是权限管理的核心单元:
- 一个实例可以属于多个组
- 一个用户可以属于多个组
- 组内的所有实例对组内的所有 query 用户可见
适合按业务线或环境划分权限:「电商组」的同学只能查电商相关实例,「支付组」的同学只能查支付相关实例。
### 6. 多语言界面
界面支持 **中文 / English** 一键切换,偏好保存在浏览器本地存储,下次打开自动还原。
---
## 三、与主流工具对比
| 特性 | dbquery | Navicat | DBeaver | Archery | Yearning |
|------|---------|---------|---------|---------|---------|
| 部署方式 | Docker,无客户端 | 桌面客户端安装 | 桌面客户端安装 | Docker | Docker |
| 多人共用 | ✅ Web,天然多人 | ❌ 每人独立安装 | ❌ 每人独立安装 | ✅ | ✅ |
| MySQL 支持 | ✅ | ✅ | ✅ | ✅ | ✅ |
| TiDB 支持 | ✅ 原生标注 | ⚠️ 兼容 MySQL | ⚠️ 兼容 MySQL | ⚠️ 兼容 MySQL | ⚠️ 兼容 MySQL |
| PostgreSQL 支持 | ✅ 多 Schema | ✅ | ✅ | ✅ | ❌ |
| Redis 支持 | ✅ 只读白名单 | ✅(付费版) | ✅(插件) | ❌ | ❌ |
| MongoDB 支持 | ✅ 只读查询 | ✅(付费版) | ✅(插件) | ❌ | ❌ |
| 用户权限体系 | ✅ 三级角色 + 用户组 | ❌ 本地工具 | ❌ 本地工具 | ✅ | ✅ |
| IP/端口对 query 用户隐藏 | ✅ | ❌ | ❌ | ❌ | ❌ |
| SQL 只读强制(query 角色) | ✅ | ❌ | ❌ | ✅ | ✅ |
| Redis 只读白名单 | ✅ | ❌ | ❌ | ❌ | ❌ |
| 对象浏览器 | ✅ | ✅ | ✅ | ⚠️ 有限 | ⚠️ 有限 |
| 多语言 | ✅ 中/英 | ✅ | ✅ | 中文 | 中文 |
| 开源免费 | ✅ | ❌(¥ 1500+/年) | ✅(社区版) | ✅ | ✅ |
| 无需前端构建 | ✅ | — | — | ❌ | ❌ |
**小结:**
- 对比 **Navicat / DBeaver**:dbquery 是 Web 应用,天然支持多人共用,无需每个人安装配置客户端;内置权限体系,可以安全地给测试、开发同学开账号,而客户端工具一旦给出连接信息就完全失控。
- 对比 **Archery / Yearning**:这两款是专注 SQL 审核和工单流程的重型平台,功能强大但部署复杂、学习成本高。dbquery 更轻量,定位是「安全的在线查询工具」,没有工单审批流程,适合中小团队快速落地。
- dbquery 的独特优势:**Redis + MongoDB 只读访问**,这在同类开源平台中几乎是空白。
---
## 四、部署方法
### 前提条件
- Docker + Docker Compose
- 一个外部 MySQL 8.0 实例作为平台元数据库(存用户、实例信息)
### 步骤
**1. 准备元数据库**
在 MySQL 上执行:
```sql
CREATE DATABASE ops_db CHARACTER SET utf8mb4;
CREATE USER 'ops_user'@'%' IDENTIFIED BY 'your-password';
GRANT ALL PRIVILEGES ON ops_db.* TO 'ops_user'@'%';
FLUSH PRIVILEGES;
```
**2. 准备配置文件**
```bash
cp .env.docker.example .env
# 编辑 .env,填写元数据库连接信息和查询账号密码
```
`.env` 关键配置:
```ini
DBS_DB_HOST=host.docker.internal # 元数据库地址
DBS_DB_PORT=3306
DBS_DB_USER=ops_user
DBS_DB_PASSWORD=your-password
DBS_DB_NAME=ops_db
QUERY_DEFAULT_ACCOUNT=dbs_admin # 查询目标 MySQL/TiDB/PG 实例用的账号
QUERY_DEFAULT_PASSWORD=your-dbs-admin-password
SECRET_KEY=your-random-secret-key
```
**3. 启动**
```bash
docker-compose up -d
```
首次启动自动完成:等待 MySQL 就绪 → 执行 migrate → 创建超级管理员 → 启动 gunicorn
**4. 访问**
打开浏览器访问 `http://localhost:8000`,默认账号:`dbsroot / Dbs@Root2026`
---
## 五、具体使用场景与操作说明
### 场景一:DBA 注册一个新的 TiDB 实例
1. 以 admin 或 root 账号登录,进入「实例管理」
2. 点击「添加实例」,填写:
- 实例名:`tidb-生产主库`
- IP:`10.0.1.100`,端口:`4000`
- 环境:`生产`
- 类型:`TiDB`
3. 点击「测试连接」,确认可连通后点「添加」
4. 实例列表中出现青色 `TiDB` 标签的新实例
> TiDB/MySQL/PostgreSQL 使用环境变量 `QUERY_DEFAULT_ACCOUNT` 统一账号连接,无需单独填写凭据。在目标实例上提前创建该账号并授予 SELECT 权限即可。
### 场景二:给测试同学开一个只读账号
1. 进入「用户管理」,点击「添加用户」
2. 填写用户名、密码,角色选「查询用户 (query)」
3. 进入「用户组管理」,新建用户组「测试组」
4. 在用户组详情中,把允许该同学访问的实例加入组,再把该用户加入组
5. 该同学登录后,只能在 SQL 查询页看到「测试组」内的实例,看不到 IP 地址,只能执行 SELECT 语句
### 场景三:跨实例查找某个数据库
1. 进入「数据库查询」
2. 在「数据库名称」输入框输入 `order`,点击「查询」
3. 系统扫描所有实例,返回所有名称包含 `order` 的数据库,显示所在实例、类型、表数量、大小
### 场景四:在线查询 MySQL 数据
1. 进入「SQL 查询」,从下拉框选择实例
2. 左上角显示 `MySQL`,左侧对象浏览器展开显示所有表
3. 在数据库选择器选择 `shop`,编辑器中输入:
```sql
SELECT * FROM orders WHERE status = '已完成' LIMIT 20;
```
4. 点击「执行」,结果以表格形式展示,点击「导出 CSV」可下载
### 场景五:查询 Redis
1. 进入「SQL 查询」,选择 Redis 类型实例
2. 左上角显示 `Redis`,左侧对象浏览器隐藏(Redis 无表结构)
3. 数据库选择器显示 `db0` 到 `db15`,选择 `db0`
4. 在编辑器输入只读命令,例如:
```
HGETALL user:1001
```
或
```
SCAN 0 MATCH user:* COUNT 100
```
5. 点击执行,返回命令结果。写入类命令(SET、DEL 等)会被直接拒绝
### 场景六:查询 MongoDB
1. 选择 MongoDB 类型实例
2. 左上角显示 `MongoDB`,左侧对象浏览器显示集合列表及行数
3. 从数据库选择器选择 `testdb`
4. 在编辑器输入(注意:字段名必须用双引号):
```
db.users.find({"age": 28})
```
或统计:
```
db.users.count_documents({"city": "北京"})
```
或聚合:
```
db.orders.aggregate([{"$group": {"_id": "$status", "count": {"$sum": 1}}}])
```
5. 点击执行,文档以表格形式展示
### 场景七:切换界面语言
点击页面右上角的语言切换按钮(`中 / EN`),界面立即切换为英文,刷新后依然保持,偏好存储在浏览器本地存储中。
---
## 六、安全设计说明
dbquery 在设计上对安全性有明确考量:
- **query 角色无法看到 IP/端口**:即使账号泄露,攻击者也无法直接连接数据库
- **query 角色强制只读**:后端校验 SQL 语句,非 SELECT 直接返回 403
- **Redis 命令白名单**:只允许预定义的只读命令,SET/DEL/FLUSHDB 等危险命令被拒绝
- **MongoDB 两道防线**:先用正则校验查询结构,再用 `json.loads` 验证 JSON 合法性,无 `eval()`,杜绝注入
- **CSRF 保护**:所有写操作均携带 CSRF Token
- **Session 认证**:无 JWT,无 Token 泄露风险
---
---
## 七、获取项目
- **GitHub**:[https://github.com/kisen9102-lgtm/dbquery](https://github.com/kisen9102-lgtm/dbquery)
- **Docker 镜像**:`docker pull ghcr.io/kisen9102-lgtm/dbquery:latest`
如果觉得有用,欢迎给个 ⭐,也欢迎提 Issue 和 PR。
*dbquery — 轻量、安全、开箱即用的多数据库在线查询平台*