-- 「疑似同款」结果表:把跨图集近邻对在**入库时**算好落库,后台页面只读结果。 -- -- 背景(2026-10-13 实测):原实现在**打开图集页时**对每张图实时做一次向量近邻检索 —— -- 一个 116 张图的图集要发 116 次查询、每次约 20KB SQL(768 维向量文本在 SELECT 与 -- ORDER BY 各出现一次)。本机 PostgreSQL 跑在 WSL2 里、Windows 经 wslrelay 访问, -- 该链路大 payload 吞吐实测约 0.47MB/s:服务端执行单条只要 0.45ms,客户端往返却要 45ms, -- 合计 116×45ms ≈ 5 秒。改为「入库时(或 dbtool similarbackfill 回填时)算一次存表」后, -- 页面退化为一次几百字节的小查询,瓶颈消失。 -- -- 设计要点: -- 1. **双向存两行**(A→B 与 B→A):这样打开任一张图所在的图集都能直接看到对方,读侧无需 UNION。 -- 2. **只存 id 与相似度**,不存对方图片的描述:描述靠读侧 join 图片表/图集表取得, -- 图片被改(改名、换图集)时不会留下陈旧文案。 -- 3. **不存「重复」语义**:与规格 §9 一致 —— 只提示、不隐藏、不计入重复率、不参与任何去重。 -- 4. 图片被软删后这里的行可能残留,读侧 join 时按 is_deleted 过滤即可,无需级联清理。 -- -- 幂等:IF NOT EXISTS。无不可逆点(纯新增表,可 DROP 重建)。 CREATE TABLE IF NOT EXISTS public.image_similar_pairs ( kind varchar(8) NOT NULL, -- 图片类型:runway | street(一对近邻同属一种) self_id integer NOT NULL, -- 本图 other_id integer NOT NULL, -- 近邻图 sim real NOT NULL, -- 余弦相似度 0~1 created_at integer NOT NULL DEFAULT 0, PRIMARY KEY (kind, self_id, other_id) ); -- 主键 (kind, self_id, other_id) 已完整覆盖读法「按 kind+self_id 取某张图的所有近邻」, -- 无需额外索引。 -- 应用后请重新导出结构:./bin/dbtool dump -clean -out db/backups/db_dump.sql