属于我们的Compliance & Regulation系列
阅读完整指南公司保留的数据平均比合法需要的数据多 33%,从而增加了存储成本和泄露风险。 数据保留是法律合规性、成本优化和安全性的融合点。保留太多会增加攻击面。保留太少就会违反法律保留要求。
本指南涵盖保留策略设计、数据类型的法律要求以及无需人工干预即可保持组织合规的自动执行。
要点
- 保留期限由法律要求、业务需求和隐私义务的交叉点决定
- 自动执行至关重要 --- 手动删除流程的失败率为 40%
- 同一系统内不同数据类型可能有不同的保留期限
- 当预计发生诉讼时,法律保留必须优先于标准保留政策
法规的保留期限要求
最低保留要求
| 数据类型 | 通用数据保护条例 | SOX(美国) | 税法(可变) | 健康保险流通与责任法案 | 行业标准 |
|---|---|---|---|---|---|
| 财务记录 | 无最低限度(目的限制) | 7 年 | 3-10 年(按国家/地区) | 不适用 | 7 年 |
| 员工记录 | 工作期限+ 2-6 年 | 不适用 | 终止后 3-7 年 | 不适用 | 终止后 7 年 |
| 客户 PII | 只要目的有必要 | 不适用 | 不适用 | 不适用 | 当关系结束 + 2 年时删除 |
| 健康档案 | 不适用 | 不适用 | 不适用 | 自创建/最后生效日期起 6 年 | 因州而异(最长 30 年) |
| 税务文件 | 不适用 | 7 年 | 3-10 年(按国家/地区) | 不适用 | 7 年 |
| 合同 | 不适用 | 持续时间 + 7 年 | 不适用 | 不适用 | 持续时间 + 6 年(诉讼时效) |
| 招聘资料 | 最长 6 个月(最佳实践) | 不适用 | 不适用 | 不适用 | 6-24 个月 |
| 支持票 | 只要需要 | 不适用 | 不适用 | 不适用 | 关闭后 3 年 |
| 审核日志 | 只要需要 | 7 年 | 不适用 | 6 年 | 7 年 |
| 营销许可 | 同意期限 | 不适用 | 不适用 | 不适用 | 直至撤回 + 2 年 |
特定国家/地区的税收保留
| 国家 | 保留期限 | 笔记 |
|---|---|---|
| 美国 | 3-7年 | IRS:一般监禁 3 年,欺诈罪判处 7 年 |
| 英国 | 6 年 | 英国税务海关总署要求 |
| 德国 | 10年 | 欧盟最严格 |
| 法国 | 6 年(有些人 10 年) | 商业代码 |
| 荷兰 | 7 年 | Fiscale bewaarplicht |
| 澳大利亚 | 5 年 | ATO 要求 |
| 加拿大 | 6 年 | CRA 要求 |
| 印度 | 8 年 | 所得税法 |
| 阿联酋 | 5 年 | 联邦税务局 |
设计保留计划
第 1 步:库存数据类别
| 类别 | 系统 | 业主 | 数据示例 |
|---|---|---|---|
| 客户资料 | CRM、电子商务、支持 | 销售 | 姓名、电子邮件、订单历史记录 |
| 员工资料 | HRIS、薪资、福利 | 人力资源 | SSN、薪资、绩效评估 |
| 财务数据 | 会计、ERP、银行业 | 金融 | 发票、收据、税务申报 |
| 营销数据 | 电子邮件平台、分析 | 营销 | 活动数据、同意记录 |
| 产品数据 | ERP、电子商务 | 运营 | 产品规格、定价、库存 |
| 操作日志 | 应用服务器、数据库 | 信息技术 | 访问日志、错误日志、审计跟踪 |
第 2 步:指定保留期
对于每个类别,使用以下层次结构确定保留期:
- 法定最低限度:法律要求您保留什么?
- 法律最高限度:法律要求您删除什么? (GDPR 目的限制)
- 业务需求:您实际需要多长时间?
- 风险承受能力:保留它与删除它的成本是多少?
保留期限为:最长(法定最低期限,业务需要),但不得长于法定最长期限(如果适用)。
第 3 步:定义处置操作
| 行动 | 描述 | 何时使用 |
|---|---|---|
| 删除 | 永久删除所有副本 | 过期数据的默认设置 |
| 匿名 | 删除识别元素,保持聚合 | 分析、研究 |
| 档案 | 转向受限的加密存储 | 合法保留,合规存档 |
| 聚合 | 用摘要替换个别记录 | 财务报告 |
自动保留执行
PostgreSQL 实现
-- Retention policy table
CREATE TABLE retention_policies (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
table_name VARCHAR(100) NOT NULL,
date_column VARCHAR(100) NOT NULL,
retention_days INTEGER NOT NULL,
action VARCHAR(20) NOT NULL, -- 'DELETE', 'ANONYMIZE', 'ARCHIVE'
condition TEXT, -- Optional WHERE clause
enabled BOOLEAN DEFAULT TRUE,
last_run TIMESTAMP,
records_affected INTEGER DEFAULT 0
);
-- Insert policies
INSERT INTO retention_policies (table_name, date_column, retention_days, action, condition) VALUES
('support_tickets', 'closed_at', 1095, 'ANONYMIZE', 'status = ''closed'''),
('recruitment_candidates', 'applied_at', 730, 'DELETE', 'status != ''hired'''),
('session_logs', 'created_at', 90, 'DELETE', NULL),
('newsletter_unsubscribed', 'unsubscribed_at', 365, 'DELETE', NULL),
('audit_logs', 'created_at', 2555, 'ARCHIVE', NULL);
-- Enforcement function
CREATE OR REPLACE FUNCTION enforce_retention_policies()
RETURNS TABLE(policy_id UUID, table_name TEXT, records_affected BIGINT) AS $$
DECLARE
policy RECORD;
affected BIGINT;
query TEXT;
BEGIN
FOR policy IN
SELECT * FROM retention_policies WHERE enabled = TRUE
LOOP
IF policy.action = 'DELETE' THEN
query := format(
'DELETE FROM %I WHERE %I < NOW() - INTERVAL ''%s days''',
policy.table_name, policy.date_column, policy.retention_days
);
IF policy.condition IS NOT NULL THEN
query := query || ' AND ' || policy.condition;
END IF;
ELSIF policy.action = 'ANONYMIZE' THEN
-- Anonymization requires table-specific logic
-- This is a simplified example
query := format(
'UPDATE %I SET email = ''[email protected]'', name = ''Anonymized'' WHERE %I < NOW() - INTERVAL ''%s days''',
policy.table_name, policy.date_column, policy.retention_days
);
IF policy.condition IS NOT NULL THEN
query := query || ' AND ' || policy.condition;
END IF;
END IF;
EXECUTE query;
GET DIAGNOSTICS affected = ROW_COUNT;
UPDATE retention_policies
SET last_run = NOW(), records_affected = affected
WHERE id = policy.id;
RETURN QUERY SELECT policy.id, policy.table_name::TEXT, affected;
END LOOP;
END;
$$ LANGUAGE plpgsql;
日程安排
# Run retention enforcement daily at 3 AM
# /etc/cron.d/retention-enforcement
0 3 * * * postgres psql -d ecosire -c "SELECT * FROM enforce_retention_policies();" >> /var/log/retention-enforcement.log 2>&1
合法保留
当合法保留适用时
当诉讼预期、未决或正在进行时,合法保留会暂停正常的保留政策。无论保留时间表如何,所有潜在相关数据都必须保留。
实施
-- Legal hold table
CREATE TABLE legal_holds (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
matter_name VARCHAR(255) NOT NULL,
description TEXT,
custodians TEXT[], -- Users whose data is held
tables_affected TEXT[], -- Tables where retention is suspended
created_at TIMESTAMP DEFAULT NOW(),
released_at TIMESTAMP,
created_by UUID REFERENCES users(id)
);
-- Modified retention enforcement respects legal holds
CREATE OR REPLACE FUNCTION enforce_retention_with_holds()
RETURNS void AS $$
BEGIN
-- Skip tables under active legal hold
DELETE FROM session_logs
WHERE created_at < NOW() - INTERVAL '90 days'
AND 'session_logs' NOT IN (
SELECT UNNEST(tables_affected)
FROM legal_holds
WHERE released_at IS NULL
);
END;
$$ LANGUAGE plpgsql;
验证和合规性
每月保留审核
- 所有保留政策均已记录并处于最新状态
- 自动执行成功运行(检查日志)
- 不存在超出保留期限的数据(样本检查)
- 法律保留对所有未决诉讼均有效
- 新数据类别已分配保留期限
- 第三方处理器符合保留要求
常见问题
如果我们保留数据的时间超过 GDPR 规定的必要时间,会发生什么情况?
保留个人数据超过其必要的保留期限违反了 GDPR 的存储限制原则(第 5(1)(e) 条)。监管机构可处以最高 2000 万欧元或全球年营业额 4% 的罚款。更实际的是,过多的数据会增加您遭受泄露的风险——您要对不应该拥有的数据负责。
我们如何处理备份副本的保留?
备份使保留变得复杂,因为它们包含特定时间点的数据快照。选项:(1) 按照与最长保留期一致的计划轮换备份,(2) 加密备份并在保留到期时销毁加密密钥(“加密粉碎”),(3) 接受备份可能包含过期数据,但将其记录为具有补偿控制的技术限制。
我们如何在 Odoo 中实现保留?
Odoo 没有内置的保留自动化功能。使用以下方式实现它:(1) 对旧记录进行归档或匿名化的计划操作(cron 作业),(2) 在特定模型上强制执行保留规则的自定义模块,(3) 用于批量操作的数据库级函数。 ECOSIRE 提供 Odoo 定制 来实现自动化数据生命周期管理。
接下来会发生什么
数据保留是完整治理计划的组成部分之一。将其与新系统的隐私设计、HR 数据的员工数据隐私 以及第三方处理器的供应商合同管理 相结合。
联系 ECOSIRE 获取数据保留策略设计和实施咨询。
由 ECOSIRE 发布——帮助企业在整个生命周期中管理数据。
作者
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
相关文章
应付账款自动化投资回报率:将发票成本从 12 美元削减到 2 美元背后的实际数字(2026 年)
应付账款自动化将每张发票处理费用从 12-15 美元减少到 3 美元以下。完整的 2026 年投资回报率计算:按数量、节省来源和限制计算的回报。
BMF Programmablaufplan Lohnsteuer 2026:实施德国官方工资税计算(XML、API、Odoo)
BMF Programmablaufplan Lohnsteuer 2026 开发人员指南:PAP 是什么、XML 伪代码格式、官方测试服务以及到 Odoo 工资单的映射。
2026 年实际可行的 25 个业务流程自动化示例(来自在生产中运行它们的团队)
涵盖财务、销售、支持和运营的 25 个真实业务流程自动化示例 - 诚实地说明了 AI 代理、RPA 和工作流程的最佳表现。
更多来自Compliance & Regulation
BMF Programmablaufplan Lohnsteuer 2026:实施德国官方工资税计算(XML、API、Odoo)
BMF Programmablaufplan Lohnsteuer 2026 开发人员指南:PAP 是什么、XML 伪代码格式、官方测试服务以及到 Odoo 工资单的映射。
服装和时尚品牌 ERP:尺码-颜色矩阵、季节规划和合规性(2026 年指南)
2026 年时尚和服装品牌如何选择 ERP:尺寸-颜色矩阵变体、季节性规划、GoBD 和 DATEV 合规性、供应商比较和成本。
ERPNext 2026 年人力资源和薪资:设置、薪资结构和多国合规性
2026 年 ERPNext 人力资源和工资单逐步设置:HRMS 应用程序安装、工资结构、工资单录入运行、所得税表、多国合规性。
2026 年 GoHighLevel A2P 10DLC 合规性:注册、费用和修复被阻止的短信
2026 年完整的 GoHighLevel A2P 10DLC 指南:品牌和活动注册步骤、运营商费用、常见拒绝原因以及如何修复过滤短信。
ERP 系统的 GxP 验证:您的 2026 年验证 RFP 必须要求什么(CSV、IQ/OQ/PQ、审计跟踪)
2026 年 GxP ERP 验证 RFP 必须要求的内容:CSV 和 CSA 范围、21 CFR 第 11 部分、EU 附件 11、IQ/OQ/PQ 可交付成果、审计跟踪和 GAMP 5 风险。
OpenClaw 安全模型、数据驻留、SOC 2 和 ISO 27001
OpenClaw 安全架构:租户隔离、加密、秘密管理、审计日志、数据驻留、SOC 2、ISO 27001、GDPR、HIPAA 适应性。