CloudBeaver 不只是能连上数据库:VPS 部署后的查询、CSV 导入与导出

从连接身份和时区检查,到限制查询、事务、CSV 暂存核验,说明浏览器数据库管理器在日常工作中该怎样使用。

把应用部署到土耳其|BRNCHOST · 土耳其 VDS
云服务器,积分可续期|雨云 · 国内外节点 · 积分兑换权益
低价年付,大流量 VPS|RackNerd · SSD 存储 · 1Gbps 端口
香港轻量,搭个小站|晚安云 · 香港云服务器
香港 VPS,大带宽可选|野草云 · BGP 直连
大陆访问,精品线路|搬瓦工 · CN2 GIA / CTGNet 套餐
资料归档,交给 AI 整理|WorkBuddy · 本地文件处理
建站起步,先看应用镜像|腾讯云 · 轻量应用服务器
CN2 GIA,中国方向优化|DMIT · Premium 网络
双 ISP 原生住宅 IP|丽萨主机 · 美国 9929 精品线路
高频 CPU,多地部署|Evoxt · 云服务器 · 每周异地备份
京东云轻量云主机:129元/年,新人专享,限购1台

网页能打开,数据库也连接成功了,接下来呢?不少 CloudBeaver 教程到这里就结束,真正让人犹豫的操作却刚开始:表有几十万行,能不能直接打开;CSV 导入失败要不要重试;编辑了一格数据,关闭标签页算不算撤销;导出的 SQL 能不能拿来当备份。

这篇把 CloudBeaver Community 放进一个完整的小流程:在 VPS 部署入口,连接演练数据库,查出需要的数据,导出一份可核对的结果,再把一份 CSV 安全地放进暂存表。示例采用 26.2.1,数据库示例使用 PostgreSQL。命令中的名称和数据都是演示值。

从数据库查询到导出文件,再到暂存表核验的流程

部署先做到“不把数据库端口交给浏览器”

浏览器不直接连接 PostgreSQL,CloudBeaver 的服务端才是数据库客户端。把管理器放到 VPS 后,数据库看到的连接来源通常也是这台 VPS 或对应的容器网络。

Docker 和 Compose 插件安装好以后,在独立目录保存 compose.yaml:

name: cloudbeaver
services:
  cloudbeaver:
    image: dbeaver/cloudbeaver:26.2.1
    restart: unless-stopped
    ports:
      - "127.0.0.1:8978:8978"
    volumes:
      - workspace:/opt/cloudbeaver/workspace
    environment:
      JAVA_OPTS: "-Xms256m -Xmx1024m"
    mem_limit: 2g
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
volumes:
  workspace:

执行 docker compose config --quiet、docker compose pull、docker compose up -d,再查看启动日志。这里只给本机开放 8978,首次配置从 SSH 隧道进入:

ssh -N -L 18978:127.0.0.1:8978 your-user@your-vps

浏览器打开 http://127.0.0.1:18978/,设置管理员,关闭匿名访问。团队需要固定域名时,由宿主机 Caddy 的 reverse_proxy 127.0.0.1:8978 提供 HTTPS;域名、证书和访问范围要先配置好。如果 Caddy 也在容器内,需要改用共同网络中的服务名。

这里的内存值是起步配置,不是并发承诺。一次大结果集、一个复杂查询、同时打开很多连接,都可能增加占用。选 VPS 时,除了网页到服务器的体验,还要看服务器到数据库的距离。

尚未准备节点,可以看看雨云当前的云服务器方案,按数据库所在区域和预期工作量选配置;不必为了查询入口追求过高配置,也不要把业务数据库仅剩的内存全部挤给管理器。

高防 / BGP,按需选线路|雨云云服务器 · 依地区与套餐提供

第一条 SQL,用来确认你在哪里

添加 PostgreSQL 连接时,Host 应是 CloudBeaver 所在环境能到达的地址。数据库与它在同一个 Docker 网络时,通常使用服务名;输入 localhost,往往只会连接 CloudBeaver 自己的容器。远端数据库还要核对来源白名单和 TLS。

连接成功后先运行:

SELECT current_database() AS database_name,
       current_user AS database_user,
       current_setting('TimeZone') AS session_timezone;

这个动作很朴素,却能避免两个常见问题:连错库,以及时间理解错了。应用把时间按 UTC 存储,查询会话按另一时区显示,导出后又被表格软件转换一次,同一条记录可能看起来像跨了日期。先记录会话时区,再决定报表按哪种时区解释。

给连接起一个能区分环境的名字,例如 demo-readonly,比一排都叫 PostgreSQL 更有用。生产与测试不要只差一个难辨认的字母;日常查数使用只读数据库账号,需要导入时再切换到演练库中有限的写入账号。

隔离环境中的 CloudBeaver SQL 查询与结果

图中订单为虚构样例。查询界面的操作方式可以参考,连接地址和数据库账号不能照搬到真实业务。

先缩小问题,再让数据库返回结果

假设演练库有 public.orders,包含 id、status、amount、created_at 四列。想检查最近的一批订单,可以先这样写:

SELECT id, status, amount, created_at
FROM public.orders
WHERE created_at >= TIMESTAMPTZ '2026-09-01 00:00:00+00'
  AND created_at <  TIMESTAMPTZ '2026-10-01 00:00:00+00'
ORDER BY created_at DESC, id DESC
LIMIT 100;

明确列名可以减少无关字段,避免顺手把备注、地址等敏感列导出。半开时间区间也比“月底 23:59:59”更容易处理小数秒。排序加上 id,是为了让相同创建时间的记录有确定顺序。

LIMIT 100 限制返回行数,但不保证数据库只扫描一百行。筛选、排序和关联仍然可能很贵。遇到慢查询时,先用普通 EXPLAIN 看计划,再决定是否适合做实际执行分析;EXPLAIN ANALYZE 会真正运行语句,不能当成毫无成本的查看按钮。PostgreSQL EXPLAIN

若只是想知道各状态的数量,让数据库做聚合即可:

SELECT status, COUNT(*) AS order_count, SUM(amount) AS total_amount
FROM public.orders
WHERE created_at >= TIMESTAMPTZ '2026-09-01 00:00:00+00'
  AND created_at <  TIMESTAMPTZ '2026-10-01 00:00:00+00'
GROUP BY status
ORDER BY order_count DESC, status;

不要为了做这个统计,把整张大表先拉到浏览器。浏览器、CloudBeaver、数据库都会为这份多余的数据付出成本,结果还未必比一条明确的聚合查询更容易核对。

网格编辑的“保存”,和数据库事务不是一个按钮

Data Editor 可以展示并编辑允许修改的数据,但表能不能编辑,既取决于数据库权限,也与驱动、结果集和行标识有关。缺少主键或明确唯一标识时,不要为了让界面能写就强行忽略提示;先回到表设计或明确的 SQL 条件。Data Editor 文档

在自动提交模式下,写入可能立即提交。手动提交模式允许在同一事务内决定提交或回滚,但它不是万能撤销键。已经提交的改动、某些数据库会隐式提交的 DDL,以及事务外部的副作用,都不受一个普通 Rollback 按钮完整保护。事务模式说明

需要修改数据时,先在演练库确认当前会话模式,避免在界面手动事务中又随意嵌套另一套 BEGIN 流程。一个练习可以很简单:查询一条样例记录,修改它,观察影响行数,回滚后再次查询。确认你理解了“编辑网格”“发送变更”和“提交事务”的区别,再处理有价值的数据。

离开页面以前也别留着未结束的事务。浏览器标签页看似闲着,数据库会话仍可能持有锁。定时清理习惯和合理的数据库超时设置,比指望每个人都记得关页面可靠得多。

导出 CSV,先把这份文件的含义写清楚

CloudBeaver 支持从表或查询结果发起导出,CSV 和 SQL 都是文档列出的格式。导出的来源不同,范围就可能不同:从整表导出,与从一个带筛选的查询结果导出,不应默认得到相同数据。数据导出文档

选择 CSV 后,至少核对编码、列分隔符、列名表头、引号和 NULL 表示。收件人需要用什么工具打开,最好在导出前问清楚。一个身份证号、长订单号或带前导零的编号,一旦被表格软件自动识别成数字,保存后可能已经不再是原始值。

建议随文件附一段说明:查询条件、导出时间、时区、行数,以及金额的币种和单位。不是为了写一份复杂报告,而是让三天后收到文件的人仍知道这些数字代表什么。

导出完成后,用独立的计数查询核对范围,并抽查首尾几行与特殊值:中文、逗号、换行、引号、NULL、空字符串和长编号。CSV 中空字符串与 NULL 如果输出成同一种形式,后续导入就可能无法恢复原意。

如果文本来自不可信输入,并且接收者要用电子表格打开,还应按所在组织的规则处理公式型单元格,避免把外部输入当作公式执行。不要为避免公式而未经说明地修改数据库原值;面向阅读的文件与需要无损回导的文件,可以采用不同交付方式。

导入先落暂存表,不直接顶着正式数据跑

社区版的导入操作以 CSV 为稳妥起点。官方页面把 XML、XLSX 导入标为 PRO 能力;不要因为导出列表里有 XLSX,就推断社区版也支持相同方向的导入。数据导入文档

第一次导入前,在独立演练库建立暂存表:

CREATE TABLE public.orders_import_stage (
  source_id text,
  status text,
  amount_text text,
  created_at_text text
);

把外部字段先按文本收下,便于识别原始异常,而不是在导入中途因为一个坏日期失败。代价是后面必须主动校验,不能把“导入成功”当成类型已经正确。

在 Data Editor 选择这个目标表,进入 Import,上传 CSV,核对字段映射与分隔符。先拿十几行样例测试,确认没有错列,再处理完整文件。出现重复键、批量加载和事务选项时,也要根据目标数据库和驱动能力判断,不要认为每个开关都会在所有连接里出现。

导入后可以先检查:

SELECT COUNT(*) AS imported_rows FROM public.orders_import_stage;
SELECT source_id, COUNT(*) AS copies
FROM public.orders_import_stage
GROUP BY source_id
HAVING COUNT(*) > 1;
SELECT * FROM public.orders_import_stage
WHERE source_id IS NULL OR btrim(source_id) = ''
LIMIT 20;

然后再单独检查金额和日期的可转换性。测试直接强制转换时,一条坏数据就可能使整条语句失败;遇到错误应保存异常行并修正来源,不要一遍遍盲目重试。正式入库前还要决定主键冲突是拒绝、跳过还是更新,并把规则写下来。

这个暂存步骤能把“文件格式不对”和“业务合并规则不对”分开。真正写入正式表前,再安排备份、事务、影响行数核对和回退方案。大批量导入则评估数据库原生工具及专门的数据流程,不必坚持所有任务都从网页上传。

SQL 导出不等于数据库备份

把几张表导出成 INSERT 语句,适合交换样例或处理有限数据,但不能直接当成完整灾备。角色、权限、索引、序列、扩展、对象依赖和一致性时点,都可能超出这份文件的范围。

PostgreSQL 应使用适合自身恢复目标的备份方案,例如逻辑备份与恢复演练;有时间点恢复要求的,还要另行设计 WAL 等机制。CloudBeaver 工作区备份则是另一件事,它保存管理器的状态,不保存被连接数据库的全部业务内容。pg_dump 文档

连不上或导不出,先看失败发生在哪一步

现象 先查的位置 容易浪费时间的做法
域名返回 502 Caddy 上游、CloudBeaver 进程与端口 先改数据库密码
登录正常,连接超时 VPS 到数据库的路由、来源规则、端口 把所有端口放开试试
认证失败 数据库账号、库名、认证方式与 TLS 反复重装网页管理器
能查不能编辑 数据库权限、主键、事务模式 改用超级用户长期工作
CSV 导入异常 编码、字段映射、类型、重复数据 对正式表不断重试
大结果集卡顿 SQL 计划、返回范围、内存与网络 只给浏览器刷新页面

本文在本机 ARM64 隔离 Docker 环境验证了 CloudBeaver Community 26.2.1:完成初始化和管理员登录,通过浏览器连接 PostgreSQL 18.6 并查询五条虚构订单;数据库侧验证只读角色可查询、更新被拒绝。停止实例后备份工作区,恢复到独立卷和另一端口,再用原账号登录并通过原连接查询成功。四份 Compose 示例均通过配置校验。导入导出步骤依据官方文档整理,未做生产数据迁移、跨版本升级或 VPS 机房性能测试。

浏览器入口的好处,是把常用查询和结果处理集中到一个随手能打开的地方。它最适合的工作节奏仍然很朴素:先确认连接,再缩小数据范围,处理完以后核对结果。少掉这几分钟,省下来的往往只是发现错误之前的时间。

参考资料