Planche 使用文档
结合应用中实际看到的界面介绍 Planche 的功能。所有截图都使用示例数据库,你可以直接在浏览器中打开它。
开始使用
Planche 是一个在浏览器中使用的数据库客户端。SQLite 文件可直接在页面中打开;MySQL、PostgreSQL 等网络数据库则通过你电脑上运行的代理连接。两种方式可以同时使用。
SQLite 文件:无需安装
把 .sqlite、.db 或 .sqlite3 文件拖到页面上,或从欢迎界面选择。编译为 WebAssembly 的 SQLite 会在页面内加载它,文件永远不会被上传。如果浏览器支持 File System Access API,修改可以写回原文件,否则会下载一份副本。
MySQL、PostgreSQL、SQL Server、Oracle、Neon、Supabase、Cloudflare D1:一条命令
浏览器本身无法与数据库建立 TCP 连接,因此需要由本地代理代为连接:
npx planche
代理会在 127.0.0.1:8888 启动,并显示配对链接,点击即可打开应用(加上 --open 会自动在浏览器中打开)。链接包含一次性代码,应用用它换取代理令牌,因此令牌本身不会出现在 URL 或 shell 历史中。之后浏览器只与 127.0.0.1 通信,代理再连接数据库;主机、用户名和密码都留在本机。

代理需要 Node.js 22 或更高版本。npx 会从 npm 仓库获取并运行它。npx planche@latest 运行最新版本;如需指定版本,请用版本号替换 latest。
用安装代替 npx
机器上没有 Node.js,或者你更想要一个常驻的命令?一行即可安装:
macOS, Linux
curl -fsSL https://planche.dev/install.sh | shWindows
irm https://planche.dev/install.ps1 | iex所有文件都放在你的主目录下,全程不需要管理员权限。如果机器上已有 Node.js 22 或更高版本就直接使用,否则会下载一份官方运行时的私有副本,并用 nodejs.org 一同发布的校验和进行验证。之后 planche 就是 PATH 上的一个命令,无需访问仓库即可立即启动。安装结束后脚本还会直接把代理跑起来,所以第一次运行不需要再做任何事 —— shell 只有在新终端里才会读到新的 PATH。
用 planche upgrade 更新,用 planche uninstall 卸载;两种情况下 ~/.planche 里的设置都会保留。有新版本时代理最多每天提醒一次,可用 PLANCHE_NO_UPDATE_CHECK=1 关闭。安装脚本是纯文本,你可以先读再运行:curl -fsSL https://planche.dev/install.sh -o install.sh。
如果无法连接 planche.dev(例如没有网络或网络策略拦截),代理会在启动时检测到这一情况,并在自己的地址上提供随包附带的应用副本。除示例数据库不包含在该副本中外,其余功能相同。此时应用版本与代理版本一致;运行 npx planche@latest 可将两者更新到最新版本。
受限网络与内网 / 隔离网
唯一需要外部网络的只有把代理装进来这一步:npx 要从 npm 仓库下载。如果这条路被封,可以在能访问 npm 的机器上装一次再带进来(npm i -g planche),或用 npm pack planche 打成 tarball 拷贝进来,或发布到内部仓库。
之后就不再有出网的通信。代理在自己的地址上提供应用,而该页面完全不会向你机器之外发起任何请求——编辑器、SQLite 引擎和所有图标都在包里,没有 CDN、没有网络字体、没有统计。加上 --serve-app 可以跳过可达性检测,一开始就在本地提供;当网络不是拒绝请求而是直接吞掉时(例如强制门户会对任何地址作出响应),也应该用这个选项。
你放弃的只是真正需要互联网的东西:托管服务(Neon、Supabase、Cloudflare D1)、通往无法到达主机的 SSH,以及示例数据库。网络内部的数据库——包括供整个团队使用的网关——和其他环境下完全一样。
工作区
一个浏览器标签页中可以同时打开多个数据库连接。每个连接都有工具栏下方的独立标签,点击即可切换。

每个连接都会保存自己的工作区状态。切换到其他连接后再返回,之前打开的查询标签页、正在编写的 SQL 和查询结果都会保留。
- 模式树(左侧)——这个连接的数据库、表、视图、存储过程等对象。单击展开,右键弹出该对象可用的操作。
- 查询标签页(右上)——一个标签就是一个 SQL 编辑器,想开多少都行。用“Open Table”打开的标签页不显示编辑器,而是用网格显示该表的行。
- 结果面板(下方)——Message 记录每条语句做了什么(影响行数、错误、耗时),旁边是 Info 和 History;每返回一个结果集就多出一个 Result 标签页。
- 底栏——当前连接的名称、只读或事务未提交时出现的标记,以及最近一条状态消息。
关掉浏览器不会丢失工作:重新打开后连接会自动重连,查询标签页和其中的 SQL 会回来,从文件打开的 SQLite 数据库即使在你重新授予文件权限之前,也能从本地副本恢复。
连接数据库
在 Connection › Connect(Alt + N)中打开连接管理器,点击 Add New 后选择 DBMS。表单只显示该引擎需要的字段。Test Connection 用于验证设置;Connect 会打开连接标签页。

各引擎需要填什么
- MySQL / MariaDB——主机、端口(3306)、用户、密码。数据库可选,树中会列出全部。字符集默认
utf8mb4。 - PostgreSQL——主机、端口(5432)、用户、密码,以及必填的数据库:PostgreSQL 会话无法切换数据库。其中的模式会在树里充当“数据库”,Planche 用
SET search_path切换。 - SQL Server——主机、端口(1433)、登录名、密码、数据库。模式(
dbo等)充当“数据库”。Azure SQL 请开启 TLS;若是自签名证书,则不要勾选验证服务器证书。 - Oracle——主机、端口(1521)、用户、密码,以及服务名(例如
FREEPDB1)。代理使用纯 JavaScript 的 thin 驱动,无需安装 Instant Client。模式即用户,通过ALTER SESSION SET CURRENT_SCHEMA切换。 - SQLite——选择打开方式。在浏览器中无需安装任何东西,操作的是文件的内存副本。通过代理则由运行代理的机器上真正的 SQLite 打开文件,因此锁和 WAL 都正常工作,可与其他程序共用;这时需要填写路径,也可以让 Planche 在文件不存在时创建它。
- Neon / Supabase——粘贴控制台里的连接字符串,主机、用户、密码和数据库会自动填好。TLS 始终开启,也没有 SSH 步骤。Supabase 请使用会话池(端口 5432)或直连;端口 6543 是事务池,每条语句可能落在不同后端,导致模式切换、临时表和手动事务失效,选中时 Planche 会给出提示。
- Cloudflare D1——账户 ID、数据库 ID,以及具备 D1 Edit 权限(只读用 D1 Read)的 API 令牌。代理用它调用 Cloudflare REST API,没有 TCP 连接也没有 SSH。每个请求都会自动提交,因此 D1 禁用手动事务。
- Redis——主机、端口(6379)、密码,服务器配置了 ACL 用户时还需填写用户(使用
default用户时留空)。数据库字段是开始时所在的逻辑数据库(db0)。TLS 和 SSH 的用法与 SQL 引擎相同。 - Elasticsearch / OpenSearch——主机和端口(9200)。填写用户和密码时,Planche 使用 Basic 认证登录;用户留空时,密码会作为 API 密钥(编码后的
id:key)发送。使用https时请开启 TLS;若是自签名证书(Elasticsearch 8 默认使用),则不要勾选验证服务器证书。 - Cloudflare DO (wrangler dev)——只需 wrangler dev 服务器 URL(默认
http://localhost:8787),无需账户 ID、令牌或密码。它只读取本地wrangler dev会话,不支持已部署的 Durable Objects;每个对象显示为独立数据库。
密码、令牌与防护
- Save password——不勾选时密码只存在到你关闭标签页;勾选后会随配置保存在本浏览器中。无论哪种方式,它都只会发给你自己的代理。
- Agent token——留空表示使用配对链接得到的令牌。只有当你运行多个代理或手动配对时才需要填写。
- 只读、环境配色和事务模式都是按配置设置的,参见安全。
SSH 隧道
只能通过跳板机访问的数据库需要使用 SSH 隧道。在配置中启用 SSH tunnel 并填写跳板机信息,本地代理会打开隧道并通过它连接数据库。

各字段
- SSH Host / Port——跳板机。可以直接使用
~/.ssh/config中的Host别名:Planche 会像ssh命令那样解析它,自动补上HostName、User、Port和IdentityFile(也会跟随Include;不支持ProxyJump)。 - SSH User——留空则使用配置块里的用户。
- SSH Auth——私钥、密码或 ssh-agent。
- 私钥:选择密钥文件,或留空以使用配置中的
IdentityFile,再不然使用~/.ssh/id_*。密钥有口令时请填写 passphrase。 - ssh-agent:使用运行
npx planche那台机器的代理套接字(SSH_AUTH_SOCK),因此硬件密钥和转发的 agent 都能正常工作。
- 私钥:选择密钥文件,或留空以使用配置中的
- 上方表单里数据库的主机和端口是在跳板机上解析的,通常是
127.0.0.1或内网名称。
主机密钥
第一次连接陌生的跳板机时会显示指纹并询问你是否接受。接受的密钥会追加到 ~/.planche/known_hosts,同时也会读取你已有的 ~/.ssh/known_hosts。如果之后密钥变了,连接会被拒绝而不是再次信任——和 ssh 命令的规则一致。
值得了解
- 密钥和 passphrase 遵循 Save password 设置,并且只会从浏览器传给你本机的代理。
- 隧道会随连接一起关闭。
- SSH 认证失败会与数据库错误分开报告,让你知道该修哪一边。
- 如果你希望代理完全忽略
~/.ssh/config和默认密钥,请在启动前设置PLANCHE_SSH_CONFIG=none。
连接 wrangler dev 中的 Cloudflare Durable Objects
Cloudflare DO (wrangler dev) 仅用于本地开发。它读取你自己电脑上正在运行的 wrangler dev 会话中的 Durable Objects。不支持已部署的 Durable Objects。
为什么每个对象都显示为数据库
每个 Durable Object 都拥有自己的私有 SQLite 数据库,因此在架构树中,每个对象都显示为一个独立数据库。有名称的对象显示为 <namespaceId>/<object>。例如,do-probe-Counter/probe-one 表示 do-probe-Counter 命名空间中的 probe-one 对象,其中命名空间 ID 为 <script>-<ClassName>。这不是通常意义上的数据库名,而是传给 idFromName() 的对象名。用 newUniqueId() 创建的对象没有名称,会以其 64 位十六进制 ID 显示。
wrangler 维护一个开发注册表。同时运行的其他 wrangler dev 会话中的 Durable Objects 也会显示,所以一个 Planche 配置可以检查多个本地项目。
连接
- 在 Worker 项目中运行
wrangler dev。 - 运行
npx planche,然后创建 Cloudflare DO (wrangler dev) 连接。 - 输入 wrangler dev 服务器 URL,默认值为
http://localhost:8787。无需账户 ID、API 令牌、密码或 SSH 设置。
本地代理读取 <devUrl>/cdn-cgi/local/explorer/api 上的 wrangler Local Explorer API,因此无需在 Worker 端安装或部署组件。URL 必须是环回地址,否则代理会成为通向任意主机的 HTTP 代理。
没有服务监听时:Cannot reach a wrangler dev server at http://localhost:8787 (fetch failed). Run `wrangler dev` in your Worker project and try again.
端口属于其他服务器时:... answered (HTTP 401) but is not a wrangler dev server. Check the port, and that `wrangler dev` (wrangler 4.x) is what is running there.
SQLite 工具和存储
Durable Object 存储是 SQLite,因此 SQL 编辑器和 ctx.storage.sql 表与其他 SQLite 数据库一样工作。Planche 通过 sqlite_master 和 PRAGMA 读取表、视图、触发器、列和索引,支持 CREATE TABLE DDL、根据外键生成 ERD,并把单表 SELECT 结果匹配到原表,以便在网格中编辑行。
Planche 在树中隐藏 miniflare 的内部管理表 __miniflare_do_name。它不会隐藏 _cf_KV,因为其中存放由 ctx.storage.put() 写入的数据,值得查看。
每个请求都会自动提交。BEGIN、COMMIT 和 ROLLBACK 会被拒绝并显示说明,手动事务选项也会像 Cloudflare D1 配置一样隐藏。
为什么不支持已部署对象
Cloudflare 公共 API 只记录了两个 Durable Objects 方法:列出命名空间和列出对象。它没有提供已文档化的 SQL 端点来查询对象存储。
Cloudflare 控制面板有一个查询已部署对象的 Data Studio 标签页(Beta),其背后的端点可用 API 令牌访问。但该端点不在公共 API 参考中,可能随时更改。也没有 Durable Objects 专用的令牌权限。D1 有 D1 Read/D1 Edit,Workers KV 和 R2 也有各自的权限;但能解锁此端点的唯一权限是 Workers Scripts Edit。它赋予部署和修改账户中每个 Worker 的写权限。Planche 不会为了浏览数据而要求用户授予该权限。
目前如需访问已部署对象,请使用控制面板的 Data Studio,或从 Worker 暴露你自己的端点。
Redis
Redis 配置支持 Redis 6 和 7,以及使用相同协议的服务器(Valkey、KeyDB、Dragonfly)。代理为每个配置保持一个连接;打开 Pub/Sub 或 Monitor 标签页期间再多占用一个连接。
键树
树中列出逻辑数据库(默认 db0 到 db15)及其键数量。展开数据库后,键按第一个 : 段分组(user:、session:),每个分组也以同样方式展开。每一层都用 SCAN 每页读取 1,000 个键,达到 10,000 个时停止并给出提示;Planche 从不执行 KEYS,因为它遍历整个键空间期间会一直阻塞服务器。键名不会在会话之间保存。
键查看器
双击键会在单独的标签页中打开。标题栏显示类型、生存时间、长度和内存(MEMORY USAGE);可以在这里修改生存时间和键名,确认后也可删除该键。重命名使用 RENAMENX,因此不会覆盖已存在的键。
- 哈希、集合、有序集合——用
HSCAN/SSCAN/ZSCAN读取为表格,带有过滤框(普通文本,或a*这样的 glob)和加载更多。值和分数可直接编辑;行可以在表格中添加和删除。 - 列表——索引和值,每次读取 200 个;元素可以编辑、推入任一端或删除。Redis 只能按值删除列表元素,因此删除时先用唯一标记覆盖该元素,再删除这个标记:共两条命令,如果其他写入者在两者之间移动了列表,索引可能会变。
- 流——最新条目在前,显示其字段;可以添加(
field value; field value)和删除条目。 - 字符串和 RedisJSON——JSON 值显示为可折叠的树,HTML 值显示为渲染后的页面;切换到文本即可编辑。超过 1 MB 的值先加载前 1 MB,需要时再加载其余部分。HTML 在沙箱框架中渲染,不运行脚本,也不从其他主机加载任何内容。
控制台
Redis 连接上的查询标签页是一个控制台:每行一条命令,使用 redis-cli 语法(双引号支持 \n, \xHH 转义;单引号按字面处理),支持 # 和 // 注释。Ctrl / ⌘ + Enter 执行光标所在行的命令;整个脚本会逐条依次执行。SELECT n 会把标签页切换到该数据库。单个对象的响应显示为 JSON,记录显示为表格,结果上方的表格 / JSON 开关可以切换视图。
控制台会拒绝 SUBSCRIBE、PSUBSCRIBE 和 MONITOR:它们会一直占用连接,使树和所有其他标签页停止工作。请改用发布/订阅和监视工具。
工具
在树的空白处右键,或使用工具菜单:
- 服务器信息——
INFO以卡片显示(版本、内存、命中率、每秒操作数、持久化、复制),以及每个数据库的键数量和可过滤的全部字段;可按需每 5 秒刷新一次。 - 慢日志——
SLOWLOG GET最新的 128 条记录,显示耗时、客户端以及记录门槛;清空前会先询问。 - 客户端——
CLIENT LIST;确认后可以断开其他客户端。应用自身的连接会被标记,不能在这里断开。 - 发布/订阅——订阅频道和 glob 模式(
news orders.*)并实时查看收到的消息;向频道发布消息并查看有多少订阅者收到。 - 监视——实时显示每个客户端执行的每条命令。Redis 会把每条命令复制给每个监视者,因此在繁忙的服务器上会降低吞吐量:请只短时间运行。当事件速度超过代理每 100 ms 500 个事件的上限时,会显示被跳过的命令数。
- 内存分析——扫描一个数据库(最多 10,000、100,000 或 1,000,000 个键),分批查询每个键的大小、类型和过期时间:按类型、前缀和过期时间统计内存,并列出最大的 50 个键。20,000 个键约需 1 秒。
MEMORY USAGE对大型集合根据元素样本进行估算。点击键可打开它,点击前缀可删除其下的键。 - 按模式删除键——找出匹配某个模式的键(每次最多 100,000 个),显示数量和其中 20 个,要求重新输入模式,然后用
UNLINK每次 500 个删除。历史中只为这次操作记录一条。数据库节点和前缀节点的菜单中也有此项。
安全
只读配置只接受 Planche 读取命令列表中的命令;网关代理会根据服务器自身的 COMMAND INFO 标志检查每条命令。FLUSHDB、FLUSHALL、SWAPDB、SHUTDOWN 等命令执行前会先询问。AUTH、HELLO … AUTH、MIGRATE … AUTH、CONFIG SET requirepass 和 ACL SETUSER 中的密码在历史中会被遮盖。
暂不支持
Redis Cluster 和 Sentinel。连接到集群节点时,Planche 只显示该节点在 db0 中的键;对于由其他节点持有的键,会给出该节点,而不会跟随重定向。
Elasticsearch 和 OpenSearch
Elasticsearch(7 和 8)和 OpenSearch(1 和 2)在连接管理器中是两个独立的条目,用法相同:代理只把你的请求发送到集群的 REST API,不做其他事情。
控制台
查询标签页是一个使用 Kibana Dev Tools 语法的控制台:包含方法和路径的一行开始一个请求,其下各行是请求体。
GET /_cat/indices?v
POST /products/_search
{
"query": { "match": { "name": "keyboard" } }
}
Ctrl / ⌘ + Enter 执行光标所在的请求。_bulk 和 _msearch 的请求体按原样(NDJSON)发送。补全会在方法之后提供常用端点,以及树中已加载的索引名。SQL 也通过同一个控制台执行:Elasticsearch 用 POST /_sql?format=txt,OpenSearch 用 POST /_plugins/_sql。
结果
搜索命中按每个文档一行返回:_index、_id、_score,然后是 _source 的字段;嵌套对象和数组在 JSON 查看器中打开。_cat 的输出会转为行。单个对象的响应(如 _cluster/health 或映射)以 JSON 打开;表格 / JSON 开关可以切换两种视图。右键点击命中并选择打开即可编辑该文档。
索引树
树中列出索引及其文档数量、一个 Aliases 文件夹,以点开头的系统索引则折叠在 System indices 中。展开索引会以点分字段路径及其类型列出映射(customer.country: keyword、items: nested)。双击索引会在新的控制台标签页中执行一次 50 个文档的搜索。执行写入请求后树会重新加载,因此新建或删除的索引会立即出现或消失。在树的空白处右键可查看集群健康、节点、分片、索引模板,以及创建索引的模板。
文档查看器
查看器显示文档的版本、_seq_no 和 _primary_term,并以树显示其 _source。切换到文本即可编辑;保存时发送 PUT /<index>/_doc/<id>?if_seq_no=…&if_primary_term=…,因此如果在你打开之后有人修改了该文档,保存会因冲突被拒绝,而不会覆盖对方的修改。刷新以读取当前版本,然后重新编辑。
安全
只读配置允许 GET 和 HEAD 请求、发往搜索类端点(_search、_count、_msearch、_mget 等)的 POST,以及只读 SQL。时间点(point-in-time)和 scroll 上下文会在集群上保存状态,因此会被拒绝。删除索引、别名、模板或快照,任何通配符或逗号分隔的目标,以及 _delete_by_query 和 _restore,执行前都会先询问;按 ID 删除单个文档则不会询问。在发往安全 API 的请求中,password、hash、API key、secret 和 token 字段在历史中会被遮盖。
模式树
模式树会随引擎变化:MySQL 和 SQLite 使用数据库 › 对象,PostgreSQL 和 SQL Server 另有模式层级。文件夹的计数可在展开前显示表的数量。

右键点击任意节点,都会出现适合那里的操作:
- Open Table——按设置中的行数限制打开数据网格。
- Generate SQL——根据真实的列和主键生成 SELECT、INSERT、UPDATE 或 DELETE 骨架,插入到光标处。
- Show Create / Alter——对象的 DDL,或表设计器。
- Copy Table to… / 比较 / 比较数据——见下文各节。
- Truncate / Drop——单独放在菜单底部,且都需要重新输入对象名称。
SQL 编辑器
编辑器使用 VS Code 背后的 Monaco,并随应用一起打包。补全同时提供当前方言的关键字、函数,以及已连接数据库的表和列。

执行语句
- Ctrl / ⌘ + Enter 运行选中内容,或光标所在的那条语句。
- F9 遵循 设置 › 安全 › 执行范围(默认是整个脚本)。
- Ctrl / ⌘ + Shift + Enter 始终运行整个脚本。
脚本由真正的解析器切分,而不是按分号:BEGIN … END 的主体不会被破坏,客户端 DELIMITER 命令、PostgreSQL 的 $$ 美元引用、SQL Server 的 GO 批处理,以及以 / 结束的 Oracle PL/SQL 块都能被理解。正因为每条语句都被分类,行数上限、破坏性确认和试运行才成为可能。
行数上限
没有限制的 SELECT 会被加上 LIMIT(视引擎而定为 TOP 或 FETCH FIRST),这样在大表上误发 SELECT * 也不会淹没浏览器。默认 500 行,生效时结果中会注明。已经自带限制的语句不会被改动。
历史与本地快照

History 标签页列出你运行过的语句;Query › Local History 保存每个编辑器标签页文本的快照,因此被替换或执行过的文本可以找回。任何内容存储前都会先掩盖密码字面量,你也可以在设置中完全关闭持久化。
结果网格
网格只渲染可见区域,因此数十万个单元格也能流畅滚动。若结果的所有列来自同一张带主键的表,便可直接编辑。

编辑
双击单元格编辑(也可以在刚点过的单元格上按 F2 / Enter),用 Add row 或 Add with form 插入,选中行来删除。在你按下 Commit 之前什么都不会执行,而且默认会先展示生成的 UPDATE、INSERT、DELETE 语句。Discard 会丢弃待提交的修改。
选择与复制
界面文字无法用拖动来选中,所以在网格上滑动鼠标不会把标签选成一片高亮。行是用点击来选的:点一行,再按 Shift 点另一行就选中两者之间的全部,按 ⌘ / Ctrl 点击则把某一行加入或移出选择。之后在单元格右键菜单里选的操作,会作用于所有选中的行。

- 筛选:列 = 此值——以精确匹配重新加载该表。
- 复制——单元格值、列名,或把选中的行复制为 TSV(含表头)、CSV、JSON 或可直接运行的 INSERT 语句。
- 编辑 / 设为 NULL / 设为空字符串 / 删除行——都在提交前保持挂起。
- 发送到草稿板——见下文。
- 隐藏列——用工具栏的列选择器可以恢复。
自上次加载以来的变化
刷新表标签页时,会按主键把新数据与上一次加载做比较。变化的单元格会高亮(悬停可看之前的值),新行被标出,消失的行数以徽章显示——在部署或批处理之后特别有用。比较结果只存在于该标签页中,点 × 即可清除。
按外键下钻
如果所连数据库定义了外键,该列的值就会变成链接。点一下,被引用的那行就在新标签页里打开,并且已经筛选好了——不用写查询,也不用复制 id。

addresses 中的客户 id,customers 就会只筛选出这位客户。这不需要任何设置:加载网格时会从数据库读取外键信息。把鼠标停在链接上,会显示它指向哪里。
手动把两张没有关系的表连起来
许多实际数据库的关系没有外键约束:可能是早年创建时未加约束的列、拆分到另一数据库的表,或用户数据位于另一台服务器的服务。你可以在 Planche 中手动声明这些关系,之后便可像普通外键一样跟随它们。
右键点击该列的值,选择将“…”链接到其他表。

- 不会往数据库里写任何东西。 链接只是 Planche 替你保存的信息,所以对只有只读权限的库也能这么做。
- 目标可以是任意已打开的连接。 可以是同一服务器上的另一数据库,也可以是使用不同引擎的连接。例如,可将 MySQL 的
orders.user_id连接到 PostgreSQL 的users.id;点击链接后会切换到该连接并打开已筛选的表。 - 不会丢。 链接按连接配置保存,刷新后依然在。
- 可以分享。 Export › 导出列链接写成 JSON 文件;导入时按 id、名称、主机的顺序匹配配置,另一台机器上的同事也能得到同样的跳转路径。
- 会出现在 ERD 里,画成虚线关系;如果目标不在图中,就在旁边补一个代表它的方框。
哪怕一个外键都没有的数据库,几分钟之后也能点着走,而且把配置文件发给同事,他们也能从同样的状态开始。
草稿板
草稿板是一个运行在你浏览器里的 SQLite 数据库。任何网格都能通过单元格右键菜单把行复制进去——一行、选中的行,或已加载的全部行。

列类型根据源类型推断,新建的表会立刻出现在草稿板的模式树中。因为它就是一个普通的浏览器 SQLite 连接,你可以像对待其他数据库一样查询和编辑,并用 Connection › Save Database File 导出为 .db 文件。它会被本地缓存,刷新后依然存在。草稿板中的内容不会被发送到任何地方。
随时用 Tools › 草稿板 打开或切换过去。
跨连接查询
在草稿板的查询标签页中,你可以用三段式名称 "连接名".数据库.表 引用任意已打开连接的表,并与其他内容联接:
SELECT o.id, o.total, u.email
FROM "Shop MySQL".shop.orders o
JOIN "User service".public.users u ON u.id = o.user_id
WHERE o.status = 'paid';
语句执行前,每个被引用的表都会被拉取成本地副本,SQL 也会被改写为使用副本,因此联接由浏览器中的 SQLite 完成。这样,MySQL 的表和 PostgreSQL 的表无需任何服务端配置就能联接。

副本每次运行都会刷新,每张表上限 10 万行,进度显示在底栏。Tools › 联合查询会打开一个预填了语法和当前连接名称的标签页。
比较与复制
这三个工具都不会自己执行任何东西——它们只生成脚本,供你阅读、修改并自行运行。
比较结构

Database › 比较结构(或树节点上的“比较表…”)会在任意两个已打开连接之间比较表、列、索引、视图、存储过程、函数、触发器和事件。比较 CREATE 语句时会剔除噪音——DEFINER、SQL SECURITY、算法以及数据库限定符——因此只显示真正的差异。在编辑器中打开脚本会把目标方言的 ALTER / CREATE 语句交给你,除非勾选相应选项,所有 DROP 都是注释状态。
比较数据

Database › 比较数据按源表主键匹配行,并把值作为规范化文本比较,因此不同驱动返回日期、小数和 JSON 的方式不会造成假差异。你会看到目标缺少的行、不同的行(逐列展示)以及只有目标才有的行,还有一份 INSERT / UPDATE / DELETE 脚本——DELETE 默认注释掉。每侧最多加载 5 万行,并显示进度。
复制表到…

右键一张表并选择 Copy Table to…,即可在任意其他已打开的连接或数据库上重建它。CREATE TABLE 以目标方言生成并可编辑,因此调整一下类型就能把 MySQL 的表复制到 PostgreSQL。行会分批流式传输并显示进度条。如果同名表已存在,复制会中止——选择“删除并重建”则必须先重新输入表名。
AI 助手
右侧面板不是写好 SQL 让你复制,而是直接操作这个应用:读取结构、打开查询标签页、在那里执行,并在改动数据前征求你的确认。从右边缘的图标或 工具 › AI 助手 打开。
一个问题如何变成答案

用平常的话问就行。模型看不到你的屏幕,所以它会先问应用当前打开了什么,再读取要用的表的列。它调用的每个工具都会留下一张卡片,因此这条查询依据什么写成一目了然,而不是靠它自己声称。写好的语句会在查询标签页中打开并执行,于是你能看到进度、中途取消,结果也能像其他查询一样排序和导出。
它写的语句会先交给引擎做执行计划。引用了不存在的列时,错误会回到模型手里由它自己改正,坏掉的查询不会出现在你眼前;如果计划是对大表做全表扫描,执行前会先问你。
它不会做的事


- 只用一个连接 —— 你当前打开的那个。没有参数可以指定别的连接,也没有打开或关闭连接的工具。用哪个数据库,由你在用哪个决定。
DROP和TRUNCATE不会执行 —— 你批准也不行,换个说法不行,藏在分号后面也不行。它可以写进标签页并告诉你会毁掉什么,但执行是你的事。- 写入先问你 —— 之后还要走和你手打的语句一样的关卡:显示改动行数的试运行、破坏性语句确认、只读连接的拒绝。
模型从哪里来

在 设置 › AI 中选择。密钥交给本地代理并在那里使用,不会存在浏览器里,也不会发往 planche.dev;你的 SQL 和结构同样不会。
- API 密钥 —— Anthropic、OpenAI 兼容端点或 Gemini。是否保存由你决定,保存前会先告诉你写到哪个文件。
- 本机登录 —— 执行过
ant auth login后 SDK 会自己找到凭据,无需粘贴任何东西。 - 本地 CLI —— 已安装并登录的 Claude Code 或 Codex,完全不需要密钥。
让别的代理来操作 Planche

帮助 › 连接 AI 代理 会给你配置内容。只要支持 HTTP 版 MCP 即可,编辑器里的代理就能使用同样的工具。调用在浏览器标签页中执行,经过同样的关卡;写入会在那里请你确认,并标注为来自外部。给出的令牌只用于那一个端点,重启后依然有效;吊销它会断开你交出过它的所有程序。
安全
在生产库中执行不带 WHERE 的 DELETE 很容易造成意外影响。Planche 会在这类语句执行前提供多层确认;如有需要,也可在设置中逐项关闭。
试运行:改动之前先看看会影响哪些行

从编辑器执行 UPDATE 或 DELETE 前,Planche 会将它改写为读取受影响行的 SELECT,并显示行数和样本。它支持各方言的联接写法:MySQL 的 UPDATE a JOIN b、PostgreSQL 的 UPDATE … FROM 与 DELETE … USING、SQL Server 的 UPDATE 别名 … FROM,以及 Oracle 的相关子查询。无法可靠改写的语句将不显示预览,以免给出错误的结果。
其余的网
- 破坏性语句确认——
DROP、TRUNCATE以及没有WHERE的DELETE/UPDATE都会先询问,并原样列出将要执行的语句。从树中删除表或数据库时还需要重新输入名称。 - 只读连接——写入在到达数据库之前就会被拒绝。
- 网格提交预览——写入前展示生成的语句。
- 手动事务——在你确认之前不会提交。
- 环境配色——生产环境看起来就和预发不同。

ERD
Tools › 查看 ERD 会根据所选数据库的外键绘制实体关系图,采用鸡爪符号,实体可拖动,列宽可调整。布局按数据库保存,所以你整理好的排布明天依然在。

你自己定义的列链接会显示为虚线关系。当链接指向图外的表(另一个数据库或另一个连接)时,会在源表旁添加一个幽灵实体,使关系依然可见。
表设计
Create Table 和 Alter Table 会打开一个设计器,包含三个标签页:列、索引,以及(对支持的引擎)存储属性。

SQL 标签页会用你所用引擎的方言展示 Planche 将要执行的语句,并随着输入实时更新——既适合学习方言,也便于确认自己接下来要做什么。

其余功能在 Table 和 Database 菜单里:重命名、复制结构、创建和删除数据库,以及在引擎支持时的用户管理、进程列表、服务器变量和状态。
导出

- 下载为 CSV——当前结果,或整张表。表会按主键顺序分页读取,并在浏览器支持 File System Access API 时直接写入你选择的文件,因此再大的表也不必放进内存。过程中显示进度,也可以中途停止。
- 模式导出为 HTML——一个自包含页面,包含你勾选的表的列和索引。
- 导出 / 导入列链接——把虚拟外键存成 JSON 文件,便于换机器或分享给同事。
- 复制为 INSERT——在网格中手动搬运少量行时使用。
- 保存数据库文件——把浏览器 SQLite 数据库(包括草稿板)写回磁盘。
以 =、+、- 或 @ 开头的 CSV 值会加上一个撇号,让表格软件把它当作文本而不是公式。
网关模式(团队)
一个代理就能服务整个团队。在网关模式下,数据库凭据保存在共享主机上的配置文件里,浏览器只按名称选择配置。
Terminal
npx planche --gateway gateway.json --addr 0.0.0.0 --allow-remote \
--token "$(openssl rand -base64 24)" --public-url https://sql.example.comgateway.json
{
"name": "Acme staging",
"profiles": [
{
"name": "Shop (read-only)",
"driver": "mysql",
"host": "db.internal",
"port": 3306,
"user": "reporting",
"password": "…",
"database": "shop"
},
{
"name": "Shop (writable)",
"readOnly": false,
"driver": "postgres",
"host": "pg.internal",
"port": 5432,
"user": "app",
"password": "…",
"database": "shop"
}
]
}name——网关的名称,会显示在连接界面上。profiles[].name——浏览器看到的名称,也是客户端唯一会回传给服务端的内容。profiles[].readOnly——不写就是只读;要允许写入请设为false。- 其余字段与连接表单里填的完全同名:
driver(mysql、postgres、mssql、oracle、sqlite、d1)、host、port、user、password、database;此外 Oracle 用serviceName,SQLite 用file,Cloudflare D1 用accountId、databaseId、apiToken。也可以照样写ssh配置块。
需要经跳板机的配置要加一个 ssh 块。此时上面的 host 和 port 是从跳板机看到的地址,因此通常写 127.0.0.1:
gateway.json(profiles 中的一项)
{
"name": "Shop via bastion (read-only)",
"driver": "mysql",
"host": "127.0.0.1",
"port": 3306,
"user": "reporting",
"password": "…",
"database": "shop",
"ssh": {
"host": "bastion.example.com",
"port": 22,
"user": "deploy",
"auth": "key"
}
}auth可以是key、agent或password。用key且不写privateKey时,代理会用网关主机~/.ssh/config中为该主机指定的IdentityFile,没有则退回~/.ssh/id_*——服务器上通常这么做,因为这样密钥不会留在配置文件里。agent使用网关的SSH_AUTH_SOCK;password需要password字段。- 如果确实要写
privateKey,它的值是密钥内容(PEM / OpenSSH),不是路径。密钥有口令时再加passphrase。 - 跳板机的主机密钥必须先在网关机器上被信任。 在那台机器上执行一次
ssh bastion.example.com,或在配置的acceptHostKey里写上SHA256:…指纹来固定:网关模式下浏览器只发送配置名称,无法回答“未知主机密钥”的确认。
- 配置默认只读,而且只读由代理强制执行:每个请求只接受一条
SELECT形态的语句,并在引擎支持时把会话本身设为只读。浏览器端的防护只是便利功能,而这一层无法从客户端绕过。 - 携带凭据而非配置名称的请求会被拒绝。
- 代理自己提供 Web 应用,因此页面只与自身来源通信,严格的内容安全策略保持不变。
- 它使用明文 HTTP:请在前面放一个 TLS 反向代理,并用
--public-url告知公开地址。
同事打开该地址,在连接对话框的 Configure 处粘贴一次令牌即可;随后配置就会出现在欢迎界面和连接管理器中。
连接同步(端到端加密)
连接同步把你的连接配置保存在 planche.dev 上,换一台电脑也能直接用。所有内容在上传前就已在浏览器里加密,所用的密钥服务器永远拿不到。入口在 连接 › 连接同步。从 1.0 起这是 Pro 功能,0.x 的所有版本均免费。
开启同步
- 用 GitHub 登录。登录只是让服务器知道哪个保险库属于你。
- 设置一个至少 10 个字符的口令,输入两遍。口令特意与 GitHub 登录分开:服务器看得到你的登录信息,所以登录本身绝不能用来解锁你的数据。
- 连接配置随即加密并上传。在另一台电脑上用同一个账号登录,输入同一个口令即可解锁。
加密方式
- 浏览器用 PBKDF2-SHA256(600,000 次迭代,随机 16 字节盐值)把口令派生为 256 位 AES-GCM 密钥。每次保存都使用新的 12 字节随机数(nonce)。
- 密钥以不可导出的方式创建,只存在于当前标签页的内存中。密钥和口令都不会写入磁盘,也不会发送到任何地方,因此每次开启新会话都要重新输入口令。
- 服务器为每个账号保存一个加密保险库。旁边以明文保存的只有重建密钥所需的参数(盐值和迭代次数)、nonce、版本号以及最后一次保存的时间,这些都不会透露任何内容。
- 账号方面,服务器保存你的 GitHub id 和邮箱地址(邮箱设为私密时改存 GitHub 用户名),以及登录期间的会话。
保险库里有什么
- 连接配置:主机、端口、用户、各项选项,以及你在这些配置上设置的列链接。
- 密码、SSH 密码和私钥——但仅限开启了 保存密码 的配置。你不愿留在本机的密钥,同样不会留在服务器上。
- 示例数据库和草稿库不在其中:哪台电脑需要,就在哪台电脑上创建。
- 查询历史、查询结果和数据库中的数据一律不会同步。
多台电脑之间
每个配置都记录了最后修改时间,合并两个保险库时以较新的那份为准。删除操作会保留 90 天,所以在一台电脑上删掉的配置不会从另一台电脑上冒出来。如果两台电脑同时保存,服务器会拒绝后到的那次,那台电脑会先合并较新的保险库再重新保存,而不是直接覆盖。
忘记口令怎么办
服务器上的保险库任何人都无法解密,我们也不例外,因此无法找回。请在仍保留着连接配置的电脑上点击 从服务器删除,然后用新口令重新开启同步。删除账号 会删除保险库和你的登录信息;无论哪一项,都不会动你电脑上的连接配置。
同步只在 planche.dev 上可用。本地代理提供的应用副本不会访问互联网,因此那里没有同步功能。
隐私与安全
- 你的数据不会到我们这里。 planche.dev 只提供静态页面;查询和结果只在你的浏览器与你自己的代理之间往返(浏览器 SQLite 则完全留在页面内)。
- 凭据留在本地。 配置保存在浏览器存储中;除非你选择保存,密码和 SSH 机密只在会话期间保留。应用会拒绝与非回环地址的代理通信(除非该代理正是提供本页面的那个),因为远程代理意味着要把凭据发到网络上。
- 代理会认证每个请求。 除健康检查外的所有路由都需要令牌,多次令牌错误会短暂锁定认证,只有应用来源可以调用它,绑定到非回环地址需要显式开关和令牌。
- SQLite 文件访问受限。 代理只打开主目录(不含隐藏目录和系统目录)或你指定目录下的文件,并且在你启用之前拒绝
ATTACH。 - 查询历史会脱敏。 在保存历史或快照之前会掩盖密码字面量,也可以关闭持久化。
- 统计匿名且可选。 只统计类别性事实——用的是哪个引擎、哪个对话框、语句是否成功——绝不收集 SQL 文本、主机名、数据库、表或文件名。设置里一个开关即可关闭。
Planche 按现状提供。这里描述的安全措施是便利功能而非保证:你要为自己运行的每条语句负责,请保留备份。
键盘快捷键
编辑器快捷键在 SQL 编辑器获得焦点时生效,其余在任何位置都可用。
| 按键 | 作用 |
|---|---|
| F9 | 执行——按照 设置 › 安全 › 执行范围,运行整个脚本或光标处的语句。 |
| Ctrl / ⌘ + Enter | 运行选中的内容,或光标所在的那条语句。 |
| Ctrl / ⌘ + Shift + Enter | 无论执行范围如何设置,都运行整个脚本。 |
| Ctrl / ⌘ + K | 快速命令面板:输入即可跳转到表、菜单操作或连接。 |
| Alt + N | 打开连接管理器。 |
| Alt + T | 在当前连接上新建查询标签页。 |
| Shift / ⌘ / Ctrl + click | 在结果网格中扩展(Shift)或切换(⌘ / Ctrl)行选择。 |
| F2 / Enter | 在结果网格中编辑刚点过的单元格(与双击相同)。 |
| Ctrl / ⌘ + F | 在编辑器中查找和替换。 |