Files
backend_v2/scripts/pgvector/initdb/03-migrate-phash-bigint-to-vector.sql
toom1996 299fd974df updae
2026-09-21 19:19:03 +08:00

51 lines
2.2 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.

-- 03-migrate-phash-bigint-to-vector.sql
-- 兼容旧库:phash 早期以 bigint 存储 64-bit dHash 指纹(uint64),现模型改为 vector(64)。
-- pgvector 不支持 bigint -> vector 直接转换,需逐位拆成 0/1 向量(位 i -> 第 i 维,
-- 与 Go 侧 phash.ToVectorBits 完全一致,保证旧数据与新写入向量在同一语义空间可比)。
--
-- 用法(仅升级旧库时需要):
-- 本迁移原先由后端启动时的 AutoMigrate(migratePhashSQL)自动执行;AutoMigrate 已移除,
-- 故升级老库改回手动执行:
-- psql "postgres://fashion:fashion_dev_2026@localhost:5432/fashion" -f 03-migrate-phash-bigint-to-vector.sql
--
-- 已为 vector/text 类型的列自动跳过;可重复执行。
DO $$
DECLARE
t text;
dt text;
BEGIN
FOR t IN
SELECT tablename FROM pg_tables
WHERE schemaname = 'public'
AND tablename IN ('brand_runway_images','brand_runway_draft_images','street_snap_images','street_snap_draft_images')
LOOP
SELECT data_type INTO dt
FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = t AND column_name = 'phash';
IF dt = 'bigint' THEN
-- bigint 即 64-bit dHash 指纹;pgvector 不支持 bigint->vector 直接转换,且 ALTER ... USING 的
-- transform 表达式不允许子查询(0A000)。改用纯表达式:bigint::bit(64) 取 64 位模式(MSB 在左),
-- reverse 成 LSB 在左(与 phash.ToVectorBits 维度顺序一致:第 i 维 = bit i),插逗号后 text::vector(64)。
-- NULL 自然透传。
EXECUTE format($e$
ALTER TABLE %I ALTER COLUMN phash TYPE vector(64)
USING (
('[' ||
rtrim(regexp_replace(reverse(phash::bit(64)::text), '(.)', '\1,', 'g'), ',') ||
']')::vector(64)
)
$e$, t);
RAISE NOTICE 'migrated phash (bigint -> vector) on %', t;
ELSIF dt IN ('character varying','text') THEN
EXECUTE format($e$
ALTER TABLE %I ALTER COLUMN phash TYPE vector(64) USING phash::vector(64)
$e$, t);
RAISE NOTICE 'migrated phash (text -> vector) on %', t;
ELSE
RAISE NOTICE 'phash on % already type %, skipped', t, dt;
END IF;
END LOOP;
END $$;