恢复了以下迁移文件到原始状态: - 004_add_redeem_code_notes.sql - 005_schema_parity.sql - 006_fix_invalid_subscription_expires_at.sql - 007_add_user_allowed_groups.sql - 008_seed_default_group.sql - 009_fix_usage_logs_cache_columns.sql - 010_add_usage_logs_aggregated_indexes.sql - 011_remove_duplicate_unique_indexes.sql - 012_add_user_subscription_soft_delete.sql - 013_log_orphan_allowed_groups.sql - 014_drop_legacy_allowed_groups.sql - 015_fix_settings_unique_constraint.sql - 016_soft_delete_partial_unique_indexes.sql - 018_user_attributes.sql - 019_migrate_wechat_to_attributes.sql - 024_add_gemini_tier_id.sql 数据库迁移文件不应在应用后修改,即使只是注释。
33 lines
1.2 KiB
SQL
33 lines
1.2 KiB
SQL
-- 013: 记录 users.allowed_groups 中的孤立 group_id
|
||
-- 任务:fix-medium-data-hygiene 3.1
|
||
--
|
||
-- 目的:在删除 legacy allowed_groups 列前,记录所有引用了不存在 group 的孤立记录
|
||
-- 这些记录可用于审计或后续数据修复
|
||
|
||
-- 创建审计表存储孤立的 allowed_groups 记录
|
||
CREATE TABLE IF NOT EXISTS orphan_allowed_groups_audit (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
user_id BIGINT NOT NULL,
|
||
group_id BIGINT NOT NULL,
|
||
recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
UNIQUE (user_id, group_id)
|
||
);
|
||
|
||
-- 记录孤立的 group_id(存在于 users.allowed_groups 但不存在于 groups 表)
|
||
INSERT INTO orphan_allowed_groups_audit (user_id, group_id)
|
||
SELECT u.id, x.group_id
|
||
FROM users u
|
||
CROSS JOIN LATERAL unnest(u.allowed_groups) AS x(group_id)
|
||
LEFT JOIN groups g ON g.id = x.group_id
|
||
WHERE u.allowed_groups IS NOT NULL
|
||
AND g.id IS NULL
|
||
ON CONFLICT (user_id, group_id) DO NOTHING;
|
||
|
||
-- 添加索引便于查询
|
||
CREATE INDEX IF NOT EXISTS idx_orphan_allowed_groups_audit_user_id
|
||
ON orphan_allowed_groups_audit(user_id);
|
||
|
||
-- 记录迁移完成信息
|
||
COMMENT ON TABLE orphan_allowed_groups_audit IS
|
||
'审计表:记录 users.allowed_groups 中引用的不存在的 group_id,用于数据清理前的审计';
|