refactor(postgres models): remove unnecessary indexes and add new fields and indexes

1. 移除 ExternalSystemHealthCheck、ExternalSystemQuotaUsage、ExternalToolTestCase 中的冗余索引
2. 为 ChannelUserIdentity 新增 pending_review 字段并添加GIN索引加速查询
3. 为 ChannelAuditLog 添加 target_account 字段索引
4. 为 ChannelOutboxEntry 新增 delivered_parts 字段并添加高频查询列索引
This commit is contained in:
Kris 2026-07-09 04:23:35 +08:00
parent 361dbe2149
commit 33acf3b61e
2 changed files with 34 additions and 4 deletions

View File

@ -284,9 +284,10 @@ class ChannelUserIdentity(Base):
default=dict,
comment="渠道绑定映射:{channel_type: [peer_id, ...]}",
)
merged_from = Column(JSON_VALUE, nullable=False, default=list, comment="合并来源 identity_id 列表")
merged_from = Column(JSON_VALUE, nullable=False, default=list, comment="合并来源结构化证据列表")
confidence = Column(String(16), nullable=False, default="low", comment="身份置信度low/medium/high")
version = Column(Integer, nullable=False, default=1, comment="乐观锁版本号")
pending_review = Column(Boolean, nullable=False, default=False, comment="低置信度合并待审批标记H-21")
# 审计字段
created_by = Column(String(64), nullable=True)
@ -306,6 +307,19 @@ class ChannelUserIdentity(Base):
unique=True,
postgresql_where=text("is_deleted = 0"),
),
# GIN 索引:加速 channel_bindings / merged_from 的 @> 包含查询
Index(
"ix_channel_user_identities_channel_bindings_gin",
"channel_bindings",
postgresql_using="gin",
postgresql_ops={"channel_bindings": "jsonb_path_ops"},
),
Index(
"ix_channel_user_identities_merged_from_gin",
"merged_from",
postgresql_using="gin",
postgresql_ops={"merged_from": "jsonb_path_ops"},
),
)
def to_dict(self) -> dict[str, Any]:
@ -323,6 +337,7 @@ class ChannelUserIdentity(Base):
"merged_from": self.merged_from or [],
"confidence": self.confidence,
"version": self.version,
"pending_review": self.pending_review,
"created_by": self.created_by,
"updated_by": self.updated_by,
"created_at": format_utc_datetime(self.created_at),
@ -481,6 +496,9 @@ class ChannelAuditLog(Base):
Index("ix_channel_audit_logs_operation_time", "operation", "timestamp"),
Index("ix_channel_audit_logs_operator_time", "operator", "timestamp"),
Index("ix_channel_audit_logs_target_time", "target_channel", "timestamp"),
# 高频过滤列索引H-8target_account 为审计日志查询的高频过滤条件,
# 无索引会触发全表扫描。
Index("ix_channel_audit_logs_target_account", "target_account"),
)
def to_dict(self) -> dict[str, Any]:
@ -614,6 +632,13 @@ class ChannelOutboxEntry(Base):
nullable=True,
comment="降级原因摘要BEST_EFFORT 持久化失败、markDeliveryUnconfirmedFailed 等)",
)
delivered_parts = Column(
JSONB,
nullable=False,
default=list,
server_default="[]",
comment="多分片投递已成功投递的分片序号列表重试时仅发送未投递分片H-15",
)
# 过期与追踪
expires_at = Column(DateTime, nullable=False, comment="过期时间(默认创建时间 + 24h")
@ -635,6 +660,10 @@ class ChannelOutboxEntry(Base):
Index("ix_channel_outbox_locked_at", "locked_at"),
Index("ix_channel_outbox_latency_ms", "latency_ms"),
Index("ix_channel_outbox_funnel_node", "funnel_node"),
# 外键列索引H-8_applyOutboxQueryFilter 按 channel_session_id 过滤,
# conversation_id 为高频 JOIN/级联列,无索引会触发全表扫描。
Index("ix_channel_outbox_channel_session", "channel_session_id"),
Index("ix_channel_outbox_conversation", "conversation_id"),
)
def to_dict(self) -> dict[str, Any]:
@ -666,6 +695,7 @@ class ChannelOutboxEntry(Base):
"partial_failure": self.partial_failure,
"stream_aborted_at_chunk": self.stream_aborted_at_chunk,
"degraded_reason": self.degraded_reason,
"delivered_parts": self.delivered_parts,
"expires_at": format_utc_datetime(self.expires_at),
"trace_id": self.trace_id,
"version": self.version,

View File

@ -744,7 +744,7 @@ class ExternalSystemHealthCheck(Base):
detail = Column(Text, nullable=True, comment="探测结果说明")
error_code = Column(String(64), nullable=True, comment="错误码")
error_message = Column(Text, nullable=True, comment="错误信息")
checked_at = Column(DateTime, nullable=True, index=True, comment="探测时间")
checked_at = Column(DateTime, nullable=True, comment="探测时间")
# 审计字段
created_by = Column(String(64), nullable=True)
@ -1023,7 +1023,7 @@ class ExternalSystemQuotaUsage(Base):
quota_name = Column(String(128), nullable=False, comment="配额展示名称")
quota_window = Column(String(32), nullable=False, comment="窗口类型daily/hourly/rolling_24h/minute/custom")
window_start = Column(DateTime, nullable=True, comment="窗口起始时间")
window_end = Column(DateTime, nullable=True, index=True, comment="窗口结束时间(重置时间)")
window_end = Column(DateTime, nullable=True, comment="窗口结束时间(重置时间)")
# 配额数值
limit_value = Column(BigInteger, nullable=False, default=0, comment="配额上限")
@ -1440,7 +1440,7 @@ class ExternalToolTestCase(Base):
# 上次运行结果
last_run_at = Column(DateTime, nullable=True, comment="上次运行时间")
last_run_status = Column(String(32), nullable=True, index=True, comment="上次运行结果passed/failed/error/skipped")
last_run_status = Column(String(32), nullable=True, comment="上次运行结果passed/failed/error/skipped")
last_run_duration_ms = Column(Integer, nullable=True, comment="上次运行耗时毫秒")
last_run_response = Column(JSON_VALUE, nullable=True, comment="上次运行响应(已脱敏)")
last_run_error = Column(Text, nullable=True, comment="上次运行错误信息")