3.3 KiB
3.3 KiB
数据库重复对象修复说明
问题描述
在重新运行 video_system_database.sql 时,遇到了 relation "idx_comments_parent" already exists 错误。这是因为数据库中已经存在了某些表、索引或其他对象,重复创建会导致错误。
修复方案
1. 添加 IF NOT EXISTS 子句
为所有可能重复的数据库对象添加了 IF NOT EXISTS 子句,使脚本可以安全地重复运行:
表创建
CREATE TABLE IF NOT EXISTS ak_video_danmakus (...)
CREATE TABLE IF NOT EXISTS ak_user_interactions (...)
CREATE TABLE IF NOT EXISTS ak_content_comments (...)
-- ... 所有其他表
索引创建
CREATE INDEX IF NOT EXISTS idx_comments_parent ON ak_content_comments(parent_id);
CREATE INDEX IF NOT EXISTS idx_danmakus_content_time ON ak_video_danmakus(content_id, time_point);
-- ... 所有其他索引
列添加
ALTER TABLE ak_contents
ADD COLUMN IF NOT EXISTS content_type VARCHAR(20) DEFAULT 'article',
ADD COLUMN IF NOT EXISTS video_url TEXT,
-- ... 所有其他列
2. 修复字段引用错误
弹幕表字段名修正
- 修正了 RPC 函数中的字段名:
content→text - 添加了
user_name字段的自动填充
时长字段引用修正
- 修正了播放记录函数中的时长字段引用
- 根据内容类型动态选择
video_duration或audio_duration
3. 增强的 RPC 函数
-- 弹幕插入函数 - 现在包含用户名自动填充
CREATE OR REPLACE FUNCTION insert_danmu_with_validation(...)
-- 播放记录函数 - 现在正确处理不同媒体类型的时长
CREATE OR REPLACE FUNCTION record_play_progress_with_validation(...)
现在的优势
✅ 幂等性(Idempotent)
- 脚本可以安全地多次运行
- 不会因为对象已存在而失败
- 支持增量更新和重新部署
✅ 错误处理
- 自动处理重复对象创建
- 提供清晰的错误信息
- 支持部分失败恢复
✅ 向后兼容
- 保持所有现有功能
- 不破坏已有数据
- 支持渐进式迁移
使用建议
部署流程
- 第一次部署:创建所有新对象
- 更新部署:只创建不存在的对象,跳过已存在的
- 修复部署:可以安全地重新运行整个脚本
开发流程
# 可以安全地重复运行
psql -f video_system_database.sql
# 或者在 Supabase 中直接粘贴执行
# 不需要担心重复执行问题
监控建议
- 关注 RPC 函数的执行日志
- 监控数据一致性
- 验证索引性能
测试验证
基础功能测试
-- 测试弹幕插入
SELECT insert_danmu_with_validation(
'content-uuid-here'::UUID,
'测试弹幕',
10.5
);
-- 测试播放记录
SELECT record_play_progress_with_validation(
'content-uuid-here'::UUID,
30.0,
5.0
);
重复执行测试
-- 这些命令应该不会报错,即使多次执行
CREATE INDEX IF NOT EXISTS idx_test ON ak_video_danmakus(id);
CREATE TABLE IF NOT EXISTS ak_test_table (id UUID);
未来扩展
脚本现在具备了良好的可维护性基础:
- 新增表或索引时记得使用
IF NOT EXISTS - 新增列时使用
ADD COLUMN IF NOT EXISTS - RPC 函数使用
CREATE OR REPLACE FUNCTION
这确保了系统的稳定性和可扩展性。