Files
backend_v2/db/migrations/2026-09-22-03-entity-key-unique.sql

38 lines
1.5 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.

-- 实体键唯一索引:单表发布模型下「一个实体一行」的结构性保证。
--
-- 为什么必须有:旧流程靠晋升时的实体键 upsert 把同一实体的多条草稿并成一行(自愈)。
-- 单表之后没有 upsert 阶段,只剩入库时的「先查后插」;一次瞬时读失败或多实例并发,
-- 就会留下两行,且两行都会通过审核进入公开视图 —— 前台出现重复内容。
--
-- 部分索引(WHERE is_deleted = 0):与 RunwayEntityState / StreetSnapEntityState 的查询口径一致,
-- 软删的旧实体键不再占用,允许同实体重新入库。
-- 建索引前先体检:有重复则中止,避免索引创建失败留下半成品状态。
DO $$
DECLARE dup int;
BEGIN
SELECT count(*) INTO dup FROM (
SELECT brand_id, season_code, collection_type
FROM brand_runways WHERE is_deleted = 0
GROUP BY 1, 2, 3 HAVING count(*) > 1
) t;
IF dup > 0 THEN
RAISE EXCEPTION 'brand_runways 有 % 组重复实体键,请先人工合并再加唯一索引', dup;
END IF;
SELECT count(*) INTO dup FROM (
SELECT city, year
FROM street_snaps WHERE is_deleted = 0
GROUP BY 1, 2 HAVING count(*) > 1
) t;
IF dup > 0 THEN
RAISE EXCEPTION 'street_snaps 有 % 组重复实体键,请先人工合并再加唯一索引', dup;
END IF;
END $$;
CREATE UNIQUE INDEX IF NOT EXISTS uq_br_entity
ON brand_runways (brand_id, season_code, collection_type) WHERE is_deleted = 0;
CREATE UNIQUE INDEX IF NOT EXISTS uq_ss_entity
ON street_snaps (city, year) WHERE is_deleted = 0;