数据主体请求:一年十二件、三十天与一套导出脚本

德国用户的一封访问请求,让他在九张表里拼了两个半小时,还漏掉对象存储里的十八个文件。本文把一年十二件请求拆成访问五件、导出四件、删除三件,用三十天内部时限、三问核验与一套导出脚本,把单件工时从 2.5 小时压到 0.5 小时。

请求到来时,你要在三十天里交出证据,而不是在第三十天开始找。

一、第一封来自德国的访问请求

陆远的一人 SaaS 跑到第 19 个月,收到第一封数据主体访问请求:一位德国用户要求「你们存了我的哪些数据,请全部给我」。他打开数据库,先找到 users 里的那一行,再顺着邮箱在 comments、files、events 里翻,两个半小时过去,才拼出一份不算完整的清单。发出去之后,用户回信问:「我在你们对象存储里的十八个文件呢?」

以下情境为教学假设,人物、引语和数字不代表经核实的真实案例。

那十八个文件在 files 表里有元数据,正文却在对象存储里,按 user_id 查表根本查不到。陆远补了文件清单,又发现自己把一条本该剔除的第三方收件人信息也导了出去。

请求处理是一条流水线,不是一次搜索。 搜索只能回答「我在这个库里找到了什么」,流水线要回答「这个人的数据分布在哪些系统、每一处由谁负责、哪一天必须交出去」。

工时的大头不是查询,是确认边界。 第一次两个半小时里,真正跑 SQL 不到二十分钟,剩下都在判断哪些行属于本人、哪些字段要脱敏、哪些第三方数据必须剔除。

同一套动作会被重复执行十二次。 一年十二件请求,如果每件都手工拼一遍,等于把同一条流水线重造十二次;脚本化的价值不在快,而在每次都用同一套口径。

第一次交付不等于第一次合格。 漏掉文件、夹带第三方信息、字段没有用途说明,这几种返工都不会在查询阶段暴露,只会在用户回信时暴露。

二、十二件请求与三种输出物

一年 12 件 = 访问 5 + 导出 4 + 删除 3,平均 1 件/月。三类请求共用一套身份核验与计时,但交付物完全不同。

类型件数/年输出物关键动作
访问5一份数据清单按表列出字段与用途,不含原始文件
导出4结构化导出包主数据、文件、事件三类齐交
删除3删除确认与例外说明级联删除,法定保留项单列

访问请求回答「有没有、是什么、给谁用」,输出可以是表格;导出请求回答「我要带走」,输出必须是可读、可迁移的文件;删除请求回答「什么时候删干净」,输出是一份带时间点和例外项的确认。

三类的共同前置是身份核验,共同约束是计时。把三类混在一张工单里,最常见的后果是:删除请求被当成访问请求处理,用户拿到清单却发现数据还在。

按 5、4、3 的比例,访问类占 41.7%(5÷12),导出类占 33.3%(4÷12),删除类占 25%(3÷12)。这个分布决定脚本的优先级:访问与导出合计 9 件,占 75%,先把这两类的查询与打包自动化,收益最大。

工单只留五个字段:收到日期、请求类型、核验通过日期、交付日期、例外项。字段再少就无法复盘,再多就会让人懒得填,五个是能坚持记录的上限。

三个类型里,删除最容易被低估。访问和导出只要「给对」,删除还要「删净」,而删净依赖的是另外九张表和五个外部接口,工作量并不在同一个量级。

三、三十天、三问核验与拒绝的写法

内部时限定 30 天,对外只承诺「在适用法律要求的期限内」。实际执行的中位数是 3 天,余量来自把核验和取数拆成两步,而不是最后一周赶工。

GDPR 访问请求为 1 个月,CCPA 为 45 天,PIPL 要求及时处理、无固定天数;三者取严,内部仍按 30 天排期。以适用法域与专业意见为准。

法域法定时限内部排期
GDPR1 个月30 天
CCPA45 天30 天
PIPL及时处理、无固定天数30 天

中位 3 天不代表可以拖到第 29 天。中位数只说明常规件的样子,长尾件往往卡在身份核验或第三方数据剔除上,这两类恰恰需要提前预留时间。

身份核验固定三问:账号绑定邮箱能否收信、最近一次登录的大致时间、能否说出一个只有本人知道的订单或项目名。三问都过才进入取数;任何一问不过,回信要求补充,但不在邮件里复述已有信息,避免把核验变成信息泄露。

核验失败时只回一句「无法确认身份,请补充信息」,不要解释是哪一问错了。解释等于告诉对方哪一问可以猜,也等于把账号存在与否暴露给非本人。

拒绝也要写成可交付的文本:引用具体条款、说明为什么该请求不适用、给出内部复核与外部申诉两条路径。口头拒绝或只回一句「无法处理」,在监管视角里等于没有处理。

拒绝模板只留四段:请求摘要、适用条款、不适用理由、申诉路径。模板越短越容易被真正使用,越长的模板越容易在忙的时候被跳过。

计时从「收到可识别请求」开始,不是从「核验通过」开始。核验拖延也算在 30 天里,这一条要写进内部流程,否则容易在月末才发现只剩三天。

四、导出脚本与四点四五 MB 的包

脚本做三件事:按 user_id 查 9 张级联表、按文件清单去对象存储取 18 个文件、按 90 天窗口取 113 条事件。输出统一成一个目录加一份清单,清单里写清每个文件的来源表与生成时间。

组成数量体积
主数据97 行58 KB
文件18 个4.32 MB
90 天事件113 条68 KB
合计—约 4.45 MB

复算:

手工工时:12 件 × 2.5 h = 30 h
脚本工时:12 件 × 0.5 h = 6 h
一年节省:30 − 6 = 24 h
导出包体积:58 KB + 4,320 KB + 68 KB = 4,446 KB ≈ 4.45 MB
方式单件工时一年十二件
手工2.5 h30 h
脚本0.5 h6 h

脚本化之后单件 0.5 小时,剩下的一半时间仍然花在核验与写回信上,取数本身接近零。这个比例是对的:机器负责「不漏」,人负责「该不该给」。

导出包不要塞原始日志。90 天事件已经够回答「我做过什么」,更长的日志既增加体积,也把无关第三方的标识带出去。

脚本必须可重跑。同一个 user_id 跑两次应得到同样的目录结构,差异只允许出现在生成时间;不能重跑的脚本,在补交时会把人工判断又做一遍。

清单本身也是交付物。用户拿到的如果不是「哪些表、哪些字段、哪些文件」,而是一堆没有索引的 JSON,等于把整理工作又推回给对方。

体积不用设硬上限,但要设检查点:超过 4.45 MB 时先看是不是把日志或他人数据带进来了,而不是先想怎么压缩。

五、行动清单与复算验收

把上面三类请求收进同一条流水线,再用八条检查确认它能在 30 天内稳定交付。

  • 建一个公开可查的请求入口,表单里只收邮箱与请求类型
  • 固定三问身份核验,任一问不过就要求补充而不泄露已有信息
  • 把 9 张按 user_id 级联的表写进一条查询,输出字段名与用途
  • 维护文件清单,导出时按清单去对象存储取 18 个文件
  • 事件统一取 90 天窗口,导出前剔除第三方标识
  • 每件请求建 30 天计时,从收到可识别请求当天起算
  • 准备拒绝模板,写清条款、理由与两条申诉路径
  • 每年复盘 12 件:类型分布、实际中位天数、返工原因

验收标准:随机抽一件已完成的请求,能在 30 天记录内指出核验时间、取数时间、交付时间和例外说明。

使用边界与实操验收

边界一:不提供法律意见。
本文的时限与模板是工程口径,具体适用哪部法律、能否拒绝,须由专业意见判断。

边界二:不同法域时限不同。
GDPR 1 个月、CCPA 45 天、PIPL 及时处理无固定天数,内部 30 天只是取严后的排期,不是对外承诺。

边界三:身份核验不能过度收集。
三问已经足够,不要为了「更保险」去要身份证、住址或人脸,那会把一次请求变成一次新的收集。

边界四:第三方数据要剔除。
导出包里出现他人的邮箱、订单或评论,等于用一次访问请求制造了一次泄露。

边界五:删除请求与法定保留冲突时先解释。
发票等法定保留项不能删,但要在确认里写清保留范围、依据与到期时间,而不是沉默。

关键参考与核验范围

  • GDPR Art 15 :用于核对访问请求的范围与副本要求。
  • ICO 访问权 :用于核对身份核验与时限的实务口径。
  • GDPR Art 30 :用于核对处理活动记录,作为取数范围的底稿。
  • OWASP 隐私风险 Top 10 :用于核对导出与二次披露的风险点。
  • GDPR Art 13 :用于核对收集时告知与请求响应的一致性。

以上链接于 2026-10-26 实测可公开访问;未核验版本、价格与配额。核验日期:2026-10-26。

系列导航

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「Indie」更多文章

  1. 开源项目验收:十项能力、四维评分与三种不该开源的项目
  2. 治理、fork 与退出:17 位贡献者、82% 的提交与一次改协议的代价
  3. 双许可与企业版:九家询价、两家成交与 4,800 美元