You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Supabase仅追加表行级安全:订阅分配追踪策略问询

行级安全策略优化方案(订阅分配追踪表)

核心需求

要实现的目标是:仅允许当前持有某订阅的用户,查看该订阅的所有分配历史记录(用于追踪重新分配过程),同时规避原思路中IN子查询的低效问题。

优化后的策略写法

推荐用EXISTS子查询替代IN,EXISTS在多数场景下性能更优(找到匹配项即终止查询,无需遍历全部结果)。以下是两种可行方案:

方案1:仅允许当前订阅所有者查看对应订阅的所有历史记录

CREATE POLICY "Current subscription owners can view full assignment history"
ON assignments
FOR SELECT
USING (
  EXISTS (
    SELECT 1
    FROM assignments latest_assign
    WHERE latest_assign.subscription_id = assignments.subscription_id
    ORDER BY latest_assign.created_at DESC
    LIMIT 1
    AND latest_assign.user_id = auth.uid()
  )
);

方案2:允许用户查看自己的分配记录 + 当前持有的订阅的所有历史记录

如果需要兼顾“用户能看到自己被分配过的所有记录”,可以调整为:

CREATE POLICY "Users can view their own assignments and current subscriptions' history"
ON assignments
FOR SELECT
USING (
  -- 查看自己作为被分配者的记录
  user_id = auth.uid()
  -- 查看自己当前持有的订阅的所有历史
  OR EXISTS (
    SELECT 1
    FROM assignments latest_assign
    WHERE latest_assign.subscription_id = assignments.subscription_id
    AND latest_assign.created_at = (
      SELECT MAX(created_at)
      FROM assignments
      WHERE subscription_id = assignments.subscription_id
    )
    AND latest_assign.user_id = auth.uid()
  )
);

性能优化建议

为让子查询快速执行,必须创建复合索引:

-- 针对subscription_id和created_at的索引,加速最新记录查找
CREATE INDEX idx_assignments_subscription_created ON assignments (subscription_id, created_at DESC);

该索引可让数据库直接定位到每个subscription_id的最新记录,避免全表扫描。

你的思路验证

你提出的“先匹配user_id == auth.uid()的行,再对关联的subscription_id执行ORDER BY created_at, LIMIT 1”的思路是可行的,本质就是方案2的逻辑——先放行用户自己的记录,再校验该记录所属订阅的最新所有者是否为当前用户,结合索引后性能会远优于原IN子查询的写法。

内容的提问来源于stack exchange,提问作者catlan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 16:44:55