Files
backend_v2/db/migrations/2026-09-22-04-street-entity-key-title.sql
toom1996 be4db0bf96 fix(publish): 最终审查修复波——迁移索引口径 / 入库计数 / 仓储证据
C1(关键):2026-09-22-03 的街拍实体键索引改用最终表达式
(city, year, COALESCE(title, '')),与体检及 StreetSnapEntityState 口径一致。
此前索引按 (city, year) 比体检更窄,同城同年多专题的合法数据会通过体检、
再由索引抛原生 23505;04 退化为幂等兜底并在注释说明真正常态由 03 承载。
新增 db/migrations/README.md,写清迁移链执行顺序与各步前提/不可逆点。

I1:processRunway 的 image_count 改为按实际落库主图行数(countMainImages),
不再用 len(p.Looks)(空主图 / sha1 重复会被跳过,导致计数偏大且不再自愈)。
补 service 单测与「入库后 image_count == 存活主图行数」的 DB 断言。

I2:三个迁移文件不再把已删除的一次性搬迁脚本写成硬前置,改为写明取回方式
(git show c4bafc5:scripts/migrate_single_table/main.go,并须在旧代码树上运行)。

I3:新增 SetRecordStatus / SetStreetRecordStatus 仓储集成测试:
pending 经仓储通过后在公开视图可见、驳回后不可见、不存在的 id 返回 ErrNotFound。

Minor:修正锁不住口径的走秀 image_count 测试(改为删主图、留细节图);
修正去重注释与事实不符(含 FindNearDuplicateImage 注释);
ListRecords / ListStreetRecords 改用 Scope 杜绝 Count 后复用 *gorm.DB;
dbtool 视图改 CREATE OR REPLACE 并重跑 dump(仍 4 视图、无草稿表);
删除挂在 Popular 上的「IDs 返回…」注释;README 改为单表 + status 现状;
SetRecordStatus 注释写明有意不校验前置状态;规格补两条已知不一致。
2026-09-23 16:03:22 +08:00

35 lines
1.7 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 街拍实体键细化:由 (city, year) 改为 (city, year, title)。
--
-- ⚠️ 本文件是**幂等兜底**,最终表达式的常态承载在 2026-09-22-03(它已直接建同一表达式索引)。
-- 之所以必须保留:03 的 `CREATE UNIQUE INDEX IF NOT EXISTS` 只按**索引名**判断存在性,
-- 遇到「同名但口径更窄的旧 (city, year) 索引」会静默跳过、留下错误结构 ——
-- 只有本文件的 `DROP INDEX IF EXISTS` + 重建能纠正这类存量库。
-- 全新库上重跑本文件也只是 DROP 后原样重建,幂等无害。
--
-- 背景:同城同年可能有多个专题(如 London 2027 Day 2 / Day 3),原键把它们判为同一实体,
-- 导致唯一索引不允许共存、且入库查重把第二个专题当成重复直接放弃。
--
-- COALESCE(title, '') 是刻意的:唯一索引中 NULL 互不冲突,若直接用 title,
-- 两条 title 为 NULL 的行会被判为不同实体而共存。入库始终会写 title,
-- 这里只是把「NULL 也要参与唯一性」这件事钉死。
-- 建索引前先体检(与 03 同一口径 (city, year, COALESCE(title, ''))):
-- 直接建索引只会抛原生 23505,这里先给出可读的报错原因。
DO $$
DECLARE dup int;
BEGIN
SELECT count(*) INTO dup FROM (
SELECT city, year, COALESCE(title, '')
FROM street_snaps WHERE is_deleted = 0
GROUP BY 1, 2, 3 HAVING count(*) > 1
) t;
IF dup > 0 THEN
RAISE EXCEPTION 'street_snaps 有 % 组重复实体键,请先人工合并再加唯一索引', dup;
END IF;
END $$;
DROP INDEX IF EXISTS uq_ss_entity;
CREATE UNIQUE INDEX IF NOT EXISTS uq_ss_entity
ON street_snaps (city, year, COALESCE(title, '')) WHERE is_deleted = 0;